In this article I use docker-compose to create a MySQL+PHP environment to run a Legacy application.
A Legacy application is an app that needs an old and outdated version of PHP to work.
Official images for PHP are available from Docker hub here: https://hub.docker.com/_/php/
I use the oldest image available from there:
php:5.3.29-apache
You can download the image right away with:
$ docker pull php:5.3.29-apache
For the sake of example I provide a small snippet of PHP code, that only works with older PHP versions.
index.php
:
<?php
$conn = mysql_connect("localhost", "user", "saxud3sldnb");
mysql_select_db( "application_db");
mysql_close($conn);
-
mysql_connect
is no longer available in recent PHP versions
To keep track of the docker configurations and settings create a docker-compose.yml
.
Because then I can commit the docker-compose.yml
into the repository and keep track of the steps required to set up the environment.
The following file is the starting version:
docker-compose.yml
:
version: '3.7'
services:
legacy-php:
image: php:5.3.29-apache
volumes:
- .:/var/www/html
Then try to run it:
$ docker-compose run -T legacy-php php /var/www/html/index.php
Creating example-legacy-php-app_legacy-php_run ... done
Warning: mysql_connect(): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2) in /var/www/html/index.php on line 2
Warning: mysql_select_db(): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2) in /var/www/html/index.php on line 3
Warning: mysql_select_db(): A link to the server could not be established in /var/www/html/index.php on line 3
Warning: mysql_close() expects parameter 1 to be resource, boolean given in /var/www/html/index.php on line 4
There are some errors, because the MySQL server is not yet set up and connected.
This is the next step.
MySQL Docker images are available here:
https://hub.docker.com/r/mysql/mysql-server/
I am using version 5.7.37
in this guide:
$ docker pull mysql/mysql-server:5.7.37
Let's add the image to the docker-compose.yml file:
docker-compose.yml
:
version: '3.7'
services:
mysql:
image: mysql/mysql-server:5.7.37
environment:
MYSQL_DATABASE: application_db
MYSQL_USER: user
MYSQL_PASSWORD: saxud3sldnb
restart: always
legacy-php:
depends_on:
- mysql
image: php:5.3.29-apache
volumes:
- .:/var/www/html
The PHP example script requires a small change:
Use hostname "mysql" instead of "localhost".
index.php
:
<?php
$conn = mysql_connect("mysql", "user", "saxud3sldnb"); <1>
mysql_select_db( "application_db");
mysql_close($conn);
Run this with the same commandline as above, and get an empty output.
The script does not do much yet.
$ docker-compose run -T legacy-php php /var/www/html/index.php
Creating example-legacy-php-app_legacy-php_run ... done
$
So lets query the database for existing users.
index.php
:
<?php
$conn = mysql_connect("mysql", "user", "saxud3sldnb"); <1>
mysql_select_db( "application_db");
$result = mysql_query("SELECT * FROM `users`");
if (!$result) {
echo "Error: " . mysql_error();
} else {
while ($row = mysql_fetch_assoc($result)) {
foreach($row as $key => $value) {
echo $key.": ".$value.", ";
}
}
}
mysql_close($conn);
Running this example gives an error message, because the database is empty, and the table cannot be found.
$ docker-compose run -T legacy-php php /var/www/html/index.php
Creating example-legacy-php-app_legacy-php_run ... done
Error: Table 'application_db.users' doesn't exist%
$
Let's initializing the database with a simple example, to
get the code working.
init.sql
:
CREATE TABLE `users`(
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(80) NOT NULL DEFAULT '',
`password` varchar(40) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
);
INSERT INTO `users`(`name`,`password`) VALUES ('admin', MD5('passw0rd'));
The sql script above creates an initial table, and an admin user, with a md5 encoded password.
Using pure md5 is a bad algorithm for passwords, it is used here just for the example.
The MySQL docker images have a script to initialize the database, lets add init.sql
to the correct place:
docker-compose.yml
:
version: '3.7'
services:
mysql:
image: mysql/mysql-server:5.7.37
environment:
MYSQL_DATABASE: application_db
MYSQL_USER: user
MYSQL_PASSWORD: saxud3sldnb
restart: always
volumes:
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
legacy-php:
depends_on:
- mysql
image: php:5.3.29-apache
volumes:
- .:/var/www/html
ports:
- "8002:80"
- Port 80 is forwarded to the local machine, test the application at http://localhost:8002 from a webbrowser.
Restart the MySQL container to run the new init script.
Then run the example again:
$ docker-compose stop
Stopping example-legacy-php-app_mysql_1 ... done
$ docker-compose run -T legacy-php php /var/www/html/index.php
Creating example-legacy-php-app_legacy-php_run ... done
id: 1, name: admin, password: bed128365216c019988915ed3add75fb%
$
And this concludes the article.
What was done:
- A Docker container to run PHP 5 specific code
- A MySQL container connected to the PHP container
- The database is initialized and ready for use.
- Open the application from a webbrowser
This article was extracted from a small eBook I wrote and published for Free as a PDF here: https://php5to8.tk
Enjoy 😸
Top comments (1)
Helped me a lot.. Thank you!