Dockerize your PHP application with Nginx and PHP8-FPM

If you are not yet familiar with Docker, I recommend you take a look at the tons of “What is Docker?” and “Getting Started with Docker” articles and tutorials, then come back here.

Since you keep reading, I’m going to assume that you already have some Docker experience and want to run your PHP applications in containers. After all, who wants to go through the trouble of installing all the dependencies on their local environment or managing a bunch of virtual machines for their various projects.

We will deploy a simple PHP application using the official Docker repositories for PHP and Nginx. There are several Docker repositories that combine PHP-FPM with Nginx, but if you rely only on the official repositories, you are absolutely on the safe side and right way.

First, install Docker on your machine if you haven’t already done so. The second requirement is to install Docker Compose. We have our necessary tools and the target in mind.

Nginx setup

Based on our requirements, Nginx will be a container. This container will run the official Nginx image. Since we are using Docker Compose, we will now create the following docker-compose.yml file. This YAML will run the latest Nginx image and set port 80 to port 8080:

web:
 image: nginx:latest
 ports:
 - "8080:80"

Now we can run the container.

$ docker-compose up

Now you should see the welcome page of Nginx on port 8080 via localhost or the IP of your local machine, via a browser of your choice.

- Dockerize your PHP application with Nginx and PHP8-FPM 1 -

Now that we have a running web server, let’s configure it a bit more. First, we need to update the docker-compose.yml file to mount a local directory that we need inside our Nginx container. I’ll use a folder called src, which is in the same directory as our docker-compose.yml file.

web:
    image: nginx:latest
    ports:
        - "8080:80"
    volumes:
        - ./src:/var/www/html

The next step is to let Nginx know that this folder exists.

Let’s create the following default.conf at the same level as the docker-compose.yml file:

server {
    index index.html;
    server_name phpfpm.local;
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /var/www/html;
}

We’ll take a look at what we’re doing here in the first place. The index.html will be our default index, the server name is phpfpm.local and it should point (Update your hosts file if necessary) to your Docker environment (Linux: localhost, Mac or Windows: Local IP). We still set the logs in case of access or error, so that later we can see the logs in our Docker compose log as well. Finally, we specify the root folder that we mounted in the container.

For this extension to take effect, we need to make one more change to our docker-compose.yml file:

web:
    image: nginx:latest
    ports:
        - "8080:80"
    volumes:
        - ./src:/src
        - ./default.conf:/etc/nginx/conf.d/default.conf

This adds the default.conf to the directory where Nginx looks for configuration files to include. You can now place an index.html file with any content in the src folder.

We start our container again:

$ docker-compose up

Now look at the content of the index.html in your browser under phpfpm.local:8080.

Website hallo - Dockerize your PHP application with Nginx and PHP8-FPM 2 -

Add PHP FPM

Now that our Nginx web server is up and running, we can bring PHP into play. First, we get the official PHP8-FPM repo and link it to our Nginx container.

The following should be noted: PHP runs in its own environment (container) and has no access to the code. We need to mount the src folder in the PHP container as well. This way Nginx will be able to serve all static files and PHP will be able to find its files to interpret.

Our docker-compose.yml should now look like this:

web:
    image: nginx:latest
    ports:
        - "8080:80"
    volumes:
        - ./src:/var/www/html
        - ./default.conf:/etc/nginx/conf.d/default.conf
    links:
        - php-fpm
php-fpm:
    image: php:8-fpm
    volumes:
        - ./src:/var/www/html

Next, you need to configure Nginx to use the PHP FPM container to interpret PHP files.

Our updated default.conf:

server {
    index index.php index.html;
    server_name phpfpm.local;
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /var/www/html;
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php-fpm:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

To test our changes, we rename the index.html file to index.php and replace its contents:

<?php
echo phpinfo();

And last but not least.

$ docker-compose up

We go back to our browser. After a refresh, we see the coveted PHP info.

php8 info - Dockerize your PHP application with Nginx and PHP8-FPM 3 -

Now you can run any simple PHP application using Docker containers, using the official images for Nginx and PHP.

You can find the example project here:
https://github.com/IshtarStar/docker-compose-nginx-phpfpm

This guide and configuration, should never be used on a production server and is not an example of best practice. This post is intended as an introduction to Docker Compose for beginners.

Table of Contents

Share on twitter
Twitter
Share on facebook
Facebook
Share on linkedin
LinkedIn
Share on xing
XING
Share on reddit
Reddit
Share on email
Email

Leave a Reply

Your email address will not be published. Required fields are marked *