How do I use Nginx and PHP?

Hello,
I want to have Nginx with PHP on my container. Are both the following configurations correct?

Configuration 1:

services:
    nginx:
        ports:
            - 80:80
        volumes:
            - ./src:/var/www/html/index.html
        image: nginx:latest
    php:
        image: php:latest

Configuration 2:

services:
    nginx:
        ports:
            - 80:80
        volumes:
            - ./src:/var/www/html/index.html
        image: nginx:latest
    links:
        - php
            php:
                image: php:latest

Cheers.

Is there a reason for nginx?
else since php has a image where apache is bundled, you can just do this:

services:
    php:
        ports:
            - 80:80
        volumes:
            - ./src:/var/www/html
        image: php:apache
2 Likes

Hi,
Yes. For some reasons, I need Nginx.
On the host OS, I did the following steps:

# mkdir -p /var/www/html
# touch /var/www/html/index.php
# nano /var/www/html/index.php

<?php
echo "Testing PHP-FPM on Docker."
?>

<?php
phpinfo();
?>

I saved the file. Then:

# mkdir -p /etc/nginx/conf.d/
# touch /etc/nginx/conf.d/default.conf
# nano /etc/nginx/conf.d/default.conf

server {
    listen 80;
    server_name phpfpm.local;
    index index.php index.html;
    root /var/www/html;
    location /var/www/html/.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;
    }
}

I saved the file.
The docker-compose.yaml file contains the following lines:

version: '3.9'

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

I tried to start the container, but:

# docker compose up -d
[+] Running 2/2
 âś” Container containers-php-fpm-1  Running                                                                                                                     0.0s 
 âś” Container containers-web-1      Started                                                                                                               

But, I can’t browse “http://IP_Address/index.php”.

I dont think that i can describe the error, better than the error you’re posting

Sorry, I solved that error. I can’t browse “http://IP_Address/index.php”.

what does

docker logs CONTAINERNAME

Give, for both?

Nginx:

# docker logs containers-web-1
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: /etc/nginx/conf.d/default.conf is not a file or does not exist
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2024/03/15 09:24:46 [notice] 1#1: using the "epoll" event method
2024/03/15 09:24:46 [notice] 1#1: nginx/1.25.4
2024/03/15 09:24:46 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14) 
2024/03/15 09:24:46 [notice] 1#1: OS: Linux 6.1.0-9-amd64
2024/03/15 09:24:46 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2024/03/15 09:24:46 [notice] 1#1: start worker processes
2024/03/15 09:24:46 [notice] 1#1: start worker process 20
2024/03/15 09:24:46 [notice] 1#1: start worker process 21
2024/03/15 09:24:46 [notice] 1#1: start worker process 22
2024/03/15 09:24:46 [notice] 1#1: start worker process 23
2024/03/15 09:31:01 [notice] 1#1: signal 3 (SIGQUIT) received, shutting down
2024/03/15 09:31:01 [notice] 20#20: gracefully shutting down
2024/03/15 09:31:01 [notice] 21#21: gracefully shutting down
2024/03/15 09:31:01 [notice] 22#22: gracefully shutting down
2024/03/15 09:31:01 [notice] 21#21: exiting
2024/03/15 09:31:01 [notice] 20#20: exiting
2024/03/15 09:31:01 [notice] 22#22: exiting
2024/03/15 09:31:01 [notice] 21#21: exit
2024/03/15 09:31:01 [notice] 20#20: exit
2024/03/15 09:31:01 [notice] 22#22: exit
2024/03/15 09:31:01 [notice] 23#23: gracefully shutting down
2024/03/15 09:31:01 [notice] 23#23: exiting
2024/03/15 09:31:01 [notice] 23#23: exit
2024/03/15 09:31:01 [notice] 1#1: signal 17 (SIGCHLD) received from 22
2024/03/15 09:31:01 [notice] 1#1: worker process 20 exited with code 0
2024/03/15 09:31:01 [notice] 1#1: worker process 21 exited with code 0
2024/03/15 09:31:01 [notice] 1#1: worker process 22 exited with code 0
2024/03/15 09:31:01 [notice] 1#1: signal 29 (SIGIO) received
2024/03/15 09:31:01 [notice] 1#1: signal 17 (SIGCHLD) received from 20
2024/03/15 09:31:01 [notice] 1#1: signal 17 (SIGCHLD) received from 23
2024/03/15 09:31:01 [notice] 1#1: worker process 23 exited with code 0
2024/03/15 09:31:01 [notice] 1#1: exit
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: /etc/nginx/conf.d/default.conf is not a file or does not exist
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2024/03/15 09:31:13 [notice] 1#1: using the "epoll" event method
2024/03/15 09:31:13 [notice] 1#1: nginx/1.25.4
2024/03/15 09:31:13 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14) 
2024/03/15 09:31:13 [notice] 1#1: OS: Linux 6.1.0-9-amd64
2024/03/15 09:31:13 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2024/03/15 09:31:13 [notice] 1#1: start worker processes
2024/03/15 09:31:13 [notice] 1#1: start worker process 20
2024/03/15 09:31:13 [notice] 1#1: start worker process 21
2024/03/15 09:31:13 [notice] 1#1: start worker process 22
2024/03/15 09:31:13 [notice] 1#1: start worker process 23

PHP-FPM:

# docker logs containers-php-fpm-1
[15-Mar-2024 08:57:32] NOTICE: fpm is running, pid 1
[15-Mar-2024 08:57:32] NOTICE: ready to handle connections
[15-Mar-2024 09:30:56] NOTICE: Finishing ...
[15-Mar-2024 09:30:56] NOTICE: exiting, bye-bye!
[15-Mar-2024 09:31:12] NOTICE: fpm is running, pid 1
[15-Mar-2024 09:31:12] NOTICE: ready to handle connections

Hi, i dont know much abount nginx + fpm, but a change you can try in your nginx conf:

server {
    listen 80;
    server_name phpfpm.local;
    index index.php index.html;
    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;
    }
}

Not that i changed location and SCRIPT_FILENAME

Hi,
The contents of the file are as follows:

# cat /etc/nginx/conf.d/nginx.conf
server {
    listen 80;
    server_name phpfpm.local;
    index index.php index.html;
    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;
    }
}

On the host:

# ss -tupln
Netid       State        Recv-Q       Send-Q               Local Address:Port                Peer Address:Port       Process                                        
tcp         LISTEN       0            128                        0.0.0.0:22                       0.0.0.0:*           users:(("sshd",pid=509,fd=3))                 
tcp         LISTEN       0            4096                       0.0.0.0:80                       0.0.0.0:*           users:(("docker-proxy",pid=14210,fd=4))       
tcp         LISTEN       0            128                           [::]:22                          [::]:*           users:(("sshd",pid=509,fd=4))                 
tcp         LISTEN       0            4096                          [::]:80                          [::]:*           users:(("docker-proxy",pid=14216,fd=4)) 

But:

$ nc 172.20.2.58 -v 80
nc: cannot connect to 172.20.2.58 (172.20.2.58) 80 [http]: Connection refused
nc: unable to connect to address 172.20.2.58, service 80

The problem is the following line:
- ./nginx.conf:/etc/nginx/conf.d/
When I commented it, then port is OK:

$ nc 172.20.2.58 -v 80
nc: 172.20.2.58 (172.20.2.58) 80 [http] open

172.20.2.58, this IP, where do you get this from?

Is this the hosts IP or the containers?
because, from the host, you should be able to do: http://localhost

The 172.20.2.58 is the IP address of the host that containers are running on it.

Hello,
something interesting. I created the default.conf file under the home directory:

# ls -l
-rw-r--r-- 1 root root  452 Mar 15 07:07 default.conf
-rw-r--r-- 1 root root  346 Mar 15 07:08 docker-compose.yaml

And changed the docker-compose.yaml file as below:

volumes:
      - ./src:/var/www/html
#      - ./default.conf:/etc/nginx/conf.d
      - ./default.conf:/home/docki/Containers

Then:

# docker compose up -d
[+] Running 2/2
 âś” Container containers-php-fpm-1  Running                                                                                                                     0.0s 
 âś” Container containers-web-1      Started

After it:

$ nc 172.20.2.58 -v 80
nc: 172.20.2.58 (172.20.2.58) 80 [http] open

Then i guess it would be something to do with your nginx config that has an error, check the docker logs.
If there is no file defined it will use a default one, which i guess is the working one that you’re seeing

How can I clear docker compose logs?

The logs says:

web-1  | 172.21.50.67 - - [15/Mar/2024:11:41:41 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" "-"
web-1  | 2024/03/15 11:42:49 [error] 31#31: *3 open() "/usr/share/nginx/html/index.php" failed (2: No such file or directory), client: 172.21.50.67, server: localhost, request: "GET /index.php HTTP/1.1", host: "172.20.2.58"
web-1  | 172.21.50.67 - - [15/Mar/2024:11:42:49 +0000] "GET /index.php HTTP/1.1" 404 555 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" "-"

again, the logs says it all:

web-1  | 2024/03/15 11:42:49 [error] 31#31: *3 open() "/usr/share/nginx/html/index.php" failed (2: No such file or directory), client: 172.21.50.67, server: localhost, request: "GET /index.php HTTP/1.1", host: "172.20.2.58"

So maybe you mapped into the wrong directory?

I saw /usr/share/nginx/html/index.php and it was odd.
I created a default.conf file under the current directory:

# ls
default.conf  docker-compose.yaml

And changed the docker-compose.yaml file as below:

version: '3.9'
services:
  web:
    image: nginx:latest
    ports:
      - '80:80'
    volumes:
      - ./default.conf:/etc/nginx/conf.d/default.conf
      - /var/www/html:/usr/share/nginx/html
    links:
      - php-fpm
  php-fpm:
    image: php:8-fpm

Now, I can see the Nginx first page, but when I browse http://IP_Address/index.php, then it asks me to download the “index.php” file and can’t execute the file. This means that PHP is not linked to Nginx.
Why?

Hello,
The final configuration is as follows:

version: '3.9'
services:
  web:
    image: nginx:latest
    ports:
      - '80:80'
    volumes:
      - ./default.conf:/etc/nginx/conf.d/default.conf
      - /var/www/html:/usr/share/nginx/html
    links:
      - php-fpm
  php-fpm:
    image: php:8-fpm

And:

server {
   listen 80;
   server_name localhost;
   error_log  /var/log/nginx/error.system-default.log;
   access_log /var/log/nginx/access.system-default.log;
   charset utf-8;

   location / {
       root   /usr/share/nginx/html;
       index  index.html index.php index.htm; 
       try_files $uri $uri/ @mod_rewrite;
   }

   location @mod_rewrite {
       rewrite ^/(.*)$ /index.php?route=/$1;
   }

       # You may need this to prevent return 404 recursion.
   location = /404.html {
       internal;
   }

   location ~ \.php$ {
       try_files $uri =404;
       fastcgi_split_path_info ^(.+\.php)(/.+)$;
       fastcgi_pass php-fpm:9000;
       fastcgi_read_timeout 6000;
       fastcgi_index index.php;
       include fastcgi_params;
       fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
       fastcgi_param PATH_INFO $fastcgi_path_info;
   }
}

When I use http://IP_Address/index.php, then I see 404 Not Found.
What is wrong?

Cheers.