Get a Legacy PHP (5.3) application running in Docker
Tags: php, mysql, docker, legacycode
Published: 2022-04-27 09:24:00

---
title: Get a Legacy PHP (5.3) application running in Docker
published: true
description: How to create a docker-compose file to run older PHP+MySQL applications
tags: php,mysql,docker,legacycode
//cover_image: https://direct_url_to_image.jpg
---

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
<?php
$conn = mysql_connect("localhost", "user", "saxud3sldnb");
mysql_select_db( "application_db");
mysql_close($conn);
```

1. `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
<?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
<?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"
```

1. 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 😸