Bootstrap FreeKB - PHP - Nginx and PHP FastCGI on Docker TCP port 9000
PHP - Nginx and PHP FastCGI on Docker TCP port 9000

Updated:   |  PHP articles

This assumes you have two containers running on the same Docker network, where one container was built from the nginx image and the other container was built from the php:fpm image

The docker container ls command can be used to ensure the containers are running.

~]# docker container ls -a
CONTAINER ID   IMAGE                 COMMAND                  CREATED        STATUS        PORTS                                                                                                                                                 NAMES
8e894ff6f352   php:fpm               "docker-php-entrypoint"   29 hours ago   Up 29 hours   0.0.0.0:9000->9000/tcp                                                                                                                                php-fpm
24bcf99fc7bc   nginx                 "/docker-entrypoint.sh"   29 hours ago   Up 29 hours   0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp

 

Let's say the server block in the /etc/nginx/conf.d/default.conf file in the nginx container contains the following. Notice that the document root directory is /var/www/html.

AVOID TROUBLE

Ensure the root directive is not defined inside of a location block.

Ensure DNS is able to resolve server_name to the Docker system that contains the PHP container otherwise the PHP file will be downloaded instead of being presented in the browser.

server {
    listen       80;
    server_name  stage.example.com;
    root         /var/www/html;
    index        index.html index.php;

    location / {
        try_files $uri $uri/ /index.php;
    }
}

 

In this example, both the nginx and PHP FPM containers will need the same exact files located at /var/www/html in each container, thus you'll almost always want the files to reside somewhere on your Docker system, and then to use the --volume option to mount the files on your Docker system to /var/www/html in the Nginx container.

docker run
--publish 80:80
--volume /path/to/html/files:/var/www/html
nginx

 

And also in the PHP FPM container.

docker run
--publish 9000:9000
--volume /path/to/html/files:/var/www/html
php:fpm

 

In this scenario, requests for a PHP file from Nginx will look like this.

 

The iptables command with the --list and --numeric options can be used to validate that connections are allowed to the PHP FPM container on port 9000. Almost always, the IP address will be an IP address in the 172.17.x.x/16 subnet.

~]# iptables --list --numeric
Chain INPUT (policy ACCEPT 110 packets, 9880 bytes)
 target     prot opt     source              destination
ACCEPT     all  --       0.0.0.0./0          172.17.0.3  tcp dpt:9000

 

The ip address command should show that the docker0 interface is bound to the 172.17.x.x/16 subnet.

~]$ ip a
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:18:77:d1:b3 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:18ff:fe77:d1b3/64 scope link
       valid_lft forever preferred_lft forever

 

And the docker inspect command should show the PHP container is bound to the IP address.

~]$ sudo docker inspect container php | grep IPAddress
            "IPAddress": "172.17.0.3",
                    "IPAddress": "172.17.0.3",

 

You may also need to reload or restart the firewalld service.

systemctl restart firewalld

 

And the netstat command should show that Docker is listening for connections on port 9000.

~]# netstat -anp | grep 9000
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:9000            0.0.0.0:*               LISTEN      3515057/docker-prox

 

Ensure /usr/local/etc/php-fpm.d/www.conf in the PHP container has the following.

listen = 127.0.0.1:9000

 

You will need to append a location block to the default.conf file for PHP. 

  • Notice the fastcgi_param directive contains $document_root$fastcgi_script_name. In this example, $document_root is /var/www/html. This means that both the nginx and PHP FPM containers will need the same exact files mounted to /var/www/html. $fastcgi_script_name will be the name of the PHP file that is being requested. For example, if requesting www.example.com/phpinfo.php, then $fastcgi_script_name will be phpinfo.php.
server {
    listen       80;
    server_name  stage.example.com;
    root         /var/www/html;
    index        index.html index.php;

    location / {
        try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {
        fastcgi_pass   10.5.14.3:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}

 

Notice in this example that fastcgi_pass directive has 10.5.14.3:9000. In this example, 10.5.14.3 is the IP address that is used for the request to reach the Docker system, not the Nginx or PHP containers. This would typically be the IP address of the Docker system or the IP address of the load balancer that forwards requests onto the Docker cluster. The ip address command should show that the network interface is bound to the 10.5.x.x/16 subnet.

~]$ ip address
2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:3a:39:61 brd ff:ff:ff:ff:ff:ff
    altname enp11s0
    inet 10.5.14.3/16 brd 10.5.255.255 scope global noprefixroute ens192
       valid_lft forever preferred_lft forever

 

OpenSSL can be used to determine if the nginx container is able to connect to the PHP container on port 9000.

~]$ sudo docker exec nginx openssl s_client -connect 172.31.29.217:9000
write:errno=0
CONNECTED(00000003)
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 283 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---

 




Did you find this article helpful?

If so, consider buying me a coffee over at Buy Me A Coffee



Comments


Add a Comment


Please enter 1d2e18 in the box below so that we can be sure you are a human.