Docker Development Question - Separate PHP instance

Problem:
Server is running PHP5.5.9
Client wants PHP7 and up

Solution:
Docker

Environment:

  • VPS Ubuntu 14.04
  • Apache 2.4.7
  • PHP 5.5.9

I’m trying to figure out the easiest way to serve the client’s WordPress website with a different PHP version.

I’m quite new to Docker so bare with me.

What I’ve pulled to do:

  • pulled Nginx-proxy
  • pulled apache-php7

I’ve been able to bind the document root of the website to the container and have it read from localhost, of course, it didn’t show anything because I don’t have a database container linked.

But I feel like there should be an easier way to complete this task rather than recreated the website and database in a container. And further create a proxy container to make it look pretty in a browser

I was wondering if I can just use what’s already on the local host computer. And somehow get the site to use the dockerized php7.

Any insight on this would be most appreciated. I will be happy to provide additional information if I’m missing anything.

I think the easiest solution for your use case is to have php-fpm running in a docker container

It is easy to build your image for php-fpm

Then in the apache config, you have to activate php fpm, pointing it to the port you have chosen (so that you can run multiple php-fpm versions and pick the one you like per virtual host for example). Making the php-fpm image is really easy, in the apache config you must configure php-fpm but again there is nothing special to docker

<FilesMatch \.php$>
    SetHandler "proxy:fcgi://127.0.0.1:9000"
</FilesMatch>

The configurations you provided goes in the apache configurations or inside the Docker container?

Inside the virtual host section of the apache config. Typically you create one file per virtual host in the directory /etc/httpd/conf.d. Those files are included via the main httpd.conf, the last line of it being

# Load config files in the "/etc/httpd/conf.d" directory, if any.
IncludeOptional conf.d/*.conf

this is an example in my case

<VirtualHost *:80>
    ServerAdmin .
    DocumentRoot somedirectory
    ServerName www.mysite.com
    <FilesMatch \.php$>
        SetHandler "proxy:fcgi://127.0.0.1:9000"
    </FilesMatch>
    AddDefaultCharset UTF-8
    <Directory "/">
     Require all granted
     DirectoryIndex index.php
    </Directory>
    <Directory "/vendor">
     Require all denied
    </Directory>
    <Directory "/includes">
     Require all denied
    </Directory>
    ProxyPass           /api http://api.mysite.org
    ProxyPassReverse    /api http://api.mysite.org
    Header unset ETag
    FileETag None
</VirtualHost>

Port 9000 is the default port for php-fpm, you can of course map a different port on your host, via the docker run -p option. Which makes it possible to switch from php version.

php-fpm is the modern way to run php, it is better than mod_php I believe. Making a docker image with php-fpm is easy, typically you would have your php scripts in a host directory which is mounted in the container (-v option)

I believe i understand the process, I’ll give some feedback and my process
once I’m back on the server on Monday.

Alright, I took this little endeavor off production to a test VPS on DigitalOcean. Here are my new Server Credentials and everything I have established so far.

I’m just running a test WordPress site on the Server which is currently running:

[System]
Ubuntu 16.04
Apache 2.4.18
PHP 7.0.13

[Apache2]
WordPress/Web Root:
/var/www/html
Virtualhost:
/etc/apache2/sites-available/WP-PHPTest.conf

<VirtualHost *:80>
ServerAdmin email@gmail.com
ServerName xxx.xx.xx.xxx
DocumentRoot /var/www/html

<FilesMatch \.php$>
SetHandler "proxy:fcgi://127.0.0.1:9000"
</FilesMatch>

<Directory /var/www/html/>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

[Docker]
Image:
bitnami/php-fpm:latest (PHP 7.1)
Run Command:
docker run -it --name phpfpm -v /var/www/html:/app bitnami/php-fpm

[Goal]
My goal is to get WordPress running in a different PHP version using a Docker container.

[Concerns]

  • I’m not sure if I’m setting up the virtual host right
  • php-fpm default port is 9000 Does the firewall need to be adjusted for Docker and php-fpm?
  • I’m not sure if I’m running the docker command right, am I supposed to mount the WordPress root directory to the /app directory of bitnami/phpfpm?
  • The Docker image maps port 9000 to 9000 (9000:9000) is that correct or must I change that?
  • What do I need to change to support SSL?

You’ve the idea right. In you apache config, you are using 127.0.0.1:9000. It is ok if apache is running on the host and if port 9000 (on the host) is mapped on port 9000 in the php-fpm container. So in the run command of php-fpm, you should also do -p 9000:9000

If both apache and php-fpm are in containers, then you should use docker-compose because it makes linking containers very easy. In this case each container has a name and you would use the container name instead of 127.0.0.1 (so phpfpm:9000).

For phpfpm, I think the volume mount would be -v /var/www/html:/var/www/html (assuming your php scripts are in /var/www/html). Start with a small script that just does phpinfo();.

If both apache and phpfpm are on the same host then no firewall rule is needed. Of course you probably need to open port 80 to access apache from you PC

Give a try to docker-compose, i will help you if both apache and phpfpm are in containers. In my case I run apache on the host and php-fpm in a container so I don’t need it.

Yes Apache is running on the host and I’ve made sure the container is mapped to 9000:9000 but something still isn’t right. putting in the IP to the test WordPress site only shows the php source code. For some reason php is not translating.

I dont need PHP-FPM installed on the host side do I?

No you don’t need php-fpm installed on the host side, the idea is that for all files with extension php the setHandler directives send to your php-fpm.
So you have to make sure that apache on the host uses your dockerized php-fpm and not the normal mod_php. So either make sure that mod_php is not installed or that it is not activated.
I can check at home how I did it, I don’t remember.

From what I can tell mod_php is not in the mods-enabled directory.

Alright, we are getting somewhere. So being on the subject of disabling mod_php, I looked into the mods-available (/etc/apache2/mods-available/) and noticed a “proxy_fcgi.load” after enabling it with the command “sudo a2enmod proxy_fcgi” and restarted Apache “service apache2 restart”. To test if the directory is serving PHP files correctly, I created an info.php file. It worked, it does indeed show the PHP version from the docker container. Now there is a new issue.

All PHP files from WordPress show the page “error establishing a database connection.” now being WordPress I know to check all possible location “wp-config.php” I double checked all database information, and it is all correct. I even took it a step further and completely made a new installation of WordPress with a new user and password, and I end up with the same thing. “error establishing a database connection.” So the PHP is working but not when it comes to WordPress.

When you connect to the database from within the docker container, you need to provide the IP of the database server. If the database is also running in a docker container then you can use some sort of container linking but if the database is running on the host then you must provide the IP of the host.

You can start a bash in the php-fpm container and then verify that you can ping the database server.