简体   繁体   中英

Minimal Docker Nginx config for multiple PHP-FPM virtual hosts

I need to upgrade some very old PHP sites still running PHP 5.6, and since I have other sites running PHP 7 and 8, I figured I'd leverage Docker for this.

I am using the default Docker PHP-FPM and Nginx images from hub.docker.com .

I am running this on Docker for Windows with WSL2 under Ubuntu 20. In case you are also on Windows 10, here is the best guide I could find on setting up WSL2 with Docker for PHP Development to work flawlessly .

Dockerfile

FROM nginx

COPY nginx.conf /etc/nginx/nginx.conf
COPY site1.conf /etc/nginx/conf.d/site1.conf
COPY site2.conf /etc/nginx/conf.d/site2.conf

nginx.conf

This is the default one in the nginx official image at /etc/nginx/nginx.conf, except for 2 lines where noted.

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    # added this once some other SO posts suggested it for multiple server_name directives
    server_names_hash_bucket_size 64;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    #tcp_nopush     on;
    keepalive_timeout  65;
    #gzip  on;

    include /etc/nginx/conf.d/*.conf;

    # had to add this, the default nginx.conf in the docker image doesn't include sites-enabled
    include /etc/nginx/sites-enabled/*.conf;
}

site1.conf

server {
    listen         80 default_server;
    listen         [::]:80 default_server;
    server_name    example1.com www.example1.com;
    root           /var/www/example1.com;
    index          index.html;

    location / {
        try_files $uri $uri/ =404;
    }

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

}

site2.conf

server {
    listen         80;
    listen         [::]:80;
    server_name    example2.com www.example2.com;
    root           /var/www/example2.com;
    index          index.html;

    location / {
        try_files $uri $uri/ =404;
    }

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

Directory Structure

/home/me/nginx-test/Dockerfile
/home/me/nginx-test/site1/index.html
/home/me/nginx-test/site1/test.php
/home/me/nginx-test/site2/index.html
/home/me/nginx-test/site2/test.php

Put <h1>Site1</h1> into site1/index.html and <h1>Site2</h1> into site2/index.html respectively so it's obvious we're loading the right one.

/etc/hosts

127.0.0.1  example1.com
127.0.0.1  example2.com

Here is my method for standing this up and testing everything.

$ cd ~/nginx-test
$ docker pull nginx
$ docker pull php:5.6.40-fpm
$ docker build -t web:test .
$ docker run --name php -v /home/me/nginx-test/site1:/var/www/example1 -v /home/me/nginx-test/site2:/var/www/example2 -d php:5.6.40-fpm
$ docker run --name test -p 80:80 -v /home/me/nginx-test/site1:/var/www/example1 -v /home/me/nginx-test/site2:/var/www/example2 --link php:php -d web:test

Notice you have to launch the php container first, and name it php so that when you stand up the web container and --link it to the php container, it can find it. This is also required given the fastcgi_pass php:9000 directive in both nginx config files.

docker ps -a

$ docker ps -a
CONTAINER ID   IMAGE            COMMAND                  CREATED          STATUS         PORTS                NAMES
37edb342d7b2   web:test         "/docker-entrypoint.…"   5 seconds ago    Up 4 seconds   0.0.0.0:80->80/tcp   test
45ac2fb3d1d4   php:5.6.40-fpm   "docker-php-entrypoi…"   10 seconds ago   Up 9 seconds   9000/tcp             php

Now, when I browse to http://example1.com and http://example2.com I the respective index.html pages.

docker logs test --follow

/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: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/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
172.17.0.1 - - [23/Mar/2021:22:29:19 +0000] "GET / HTTP/1.1" 200 135 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36" "-"

Now to make it a bit easier to grep logs, let's add the $server_name to nginx.conf log_format. More details on the offical list of nginx variables .

nginx.conf edit, line 16

    log_format  main  '$remote_addr - $remote_user [$time_local] "$server_name $request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

Teardown and rebuild

$ docker stop test && docker rm test && docker stop php && docker rm php
$ docker build -t web:test .
$ docker run --name php -v /home/me/nginx-test/site1:/var/www/example1 -v /home/me/nginx-test/site2:/var/www/example2 -d php:5.6.40-fpm
$ docker run --name test -p 80:80 -v /home/me/nginx-test/site1:/var/www/example1 -v /home/me/nginx-test/site2:/var/www/example2 --link php:php -d web:test
$ docker logs test --follow
172.17.0.1 - - [23/Mar/2021:22:41:25 +0000] "example2.com GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36" "-"
172.17.0.1 - - [23/Mar/2021:22:41:36 +0000] "example1.com GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36" "-"
172.17.0.1 - - [23/Mar/2021:22:41:41 +0000] "example1.com GET /test.php HTTP/1.1" 200 85924 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36" "-"

Here is some more diagnostic details.

did volumes mount?

$ docker exec -it test bash
root@37edb342d7b2:/# cd /var/www/example1
root@37edb342d7b2:/var/www/example1# ls
index.html  test.php

yes.

in both containers?

$ docker exec -it php bash
root@45ac2fb3d1d4:/var/www/html# ls -la /var/www/example2
total 16
drwxr-xr-x 2 1000 1000 4096 Mar 23 21:47 .
drwxr-xr-x 1 root root 4096 Mar 23 22:21 ..
-rw-r--r-- 1 1000 1000  135 Mar 23 21:37 index.html
-rw-r--r-- 1 1000 1000   31 Mar 23 20:33 test.php

In the context of asking some questions, I figured everything out, so I decided to keep this up as a guide for future readers.

Read the guide above.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM