Reputation: 2371
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
Upvotes: 0
Views: 1243
Reputation: 2371
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.
Upvotes: 0