In the previous instalment (Docker Lab – Containerising your website, Part 1), we installed Docker and Docker Compose, and set up an Nginx container. If all you need is to serve a few static pages there’s no need to read any further. But if you need your website to be dynamic, if you need PHP and, perhaps, a database, read on…
These instructions assume that you have followed the steps in part 1.
It will come as no surprise that, in order to install PHP, we need to edit the docker-compose.yml file. But before we do that, it will be necessary to stop Docker (just in case you left it running from the last session). In fact, you can edit the docker-compose.yml file while Docker is still running – but the changes won’t take effect until Docker is restarted.
Check to see if Docker is running as follows:
docker ps
If any docker containers are running then you’ll see them listed like this:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 673b1e25c03a bitnami/nginx:latest "/app-entrypoint.s..." 3 hours ago Up 3 hours 0.0.0.0:80->8080/tcp, 0.0.0.0:443->8443/tcp lempcompose_nginx_1
If you haven’t started any Docker containers manually then you can stop the containers using Docker Compose.
Stopping using Docker Compose
When I stop jobs using Docker Compose, I always like to clean up as well. The containers will be rebuilt by Compose, so there isn’t a great deal of extra effort and it helps keep the cruft under control.
cd ~/lemp-compose docker-compose stop docker-compose rm
Stopping Manually
If you have started any containers manually then you’ll need to stop them by using the docker command and the container ID.
docker stop <containerId>
This step will need to be repeated for all containers which are running.
Configuring your Containers.
Now that your containers are stopped, the docker-compose.yml file will need to be edited to add a PHP container. Add a networks section to the top of your docker-compose.yml, beneath the version number and before services:
networks: app-tier: driver: bridge
Now add a section for PHP. Note that you’ll need a different PHP section for each vhost that you want to use PHP. You can’t (easily) host multiple websites with a single PHP instance. Because each vhost will have its own PHP instance I like to add the website name to the name of the PHP container that it will use.
phpfpm-<your website name>: image: 'bitnami/php-fpm:latest' networks: - app-tier volumes: - ./public/<your website name>/htdocs:/app - ./logs/<your website name>-php:/opt/bitnami/php/log
Finally, add the network and dependency to your nginx container configuration, under the image name and before the ports.
depends_on: - phpfpm-<your website name> networks: - app-tier
Having made these changes, your docker-compose.yml should look like this:
version: '2' networks: app-tier: driver: bridge services: nginx: image: 'bitnami/nginx:latest' depends_on: - phpfpm-<your website name> networks: - app-tier ports: - '80:8080' - '443:8443' volumes: - ./nginx/nginx.conf:/bitnami/nginx/conf/nginx.conf - ./nginx/fastcgi.conf:/bitnami/nginx/conf/fastcgi.conf - ./logs:/opt/bitnami/nginx/logs - ./nginx/vhosts:/bitnami/nginx/conf/vhosts - ./public:/opt/bitnami/nginx/html phpfpm-<your website name>: image: 'bitnami/php-fpm:latest' networks: - app-tier volumes: - ./public/<your website name>/htdocs:/app - ./logs/<your website name>-php:/opt/bitnami/php/log
Website configuration
So far so good – it still won’t work though – we need to make changes to the vhost configuration. The reason that it won’t work is that we haven’t set up PHP in the vhost configuration, and it will also be necessary to modify the root information so that all resources (php, html, image files etc) can be accessed correctly.
nano ~/nginx/vhosts/sites-available/<your website name>.conf
Edit it as follows, replacing the server_name domain name with the domain name(s) of your website.
server { listen 0.0.0.0:8080; server_name <your domain name>; server_tokens off; error_log "/opt/bitnami/nginx/logs/<your website name>-error.log"; access_log "/opt/bitnami/nginx/logs/<your website name>-access.log"; location / { try_files $uri $uri/index.php; } location ~ \.php$ { # fastcgi_pass [PHP_FPM_LINK_NAME]:9000; fastcgi_pass phpfpm-<your website name>:9000; fastcgi_index index.php; include fastcgi.conf; root /app; } location ~ \.htm$ { root /opt/bitnami/nginx/html/<your website name>/htdocs; } location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { expires max; log_not_found off; root /opt/bitnami/nginx/html/<your website name>/htdocs; } }
If you’ve pulled all of that off correctly, you should be able to put info.php into ~/lemp-compose/public/<your website name>/htdocs and start Docker:
cd ~/lemp-compose docker-compose up --remove-orphans -d
Enter your website URL into your browser and (fingers crossed) access your info.php which will, hopefully, be displayed correctly, served up by your containerised instance of Nginx and PHP. Go and have a well earned cup of tea before moving onto the next stage – setting up your database.
info.php
If you’ve never created an info.php file before it’s quite simple. It contains the following and nothing else:
<?php phpinfo(); ?>
If it displays information about your PHP instance then PHP is installed correctly. If nothing is displayed, or if you are greeted with the dreaded ‘File Not Found’ then go back and check your steps carefully.
Once you have confirmed that PHP is installed correctly be sure to delete your info.php file – it’s a hackers goldmine and may reveal passwords and other information that make your website trivially easy to compromise.