php-fpm & nginx in separated docker container, can not execute .php file - php

I'd like to setup an completely LNMP environment with docker on a machine. But there is something wrong with separated php-fpm & nginx container.
What I'v done is :
pull images from docker.io :
docker pull php:7.1-fpm
docker pull nginx
run with image :
docker run -d --name php-fpm -v /data/Docker/php-fpm/configs/:/usr/local/etc/php-fpm.d -v /data/Docker/nginx/html:/var/www/html php:7.1-fpm
docker run -d --name nginx -v /data/Docker/nginx/configs/:/etc/nginx -v /data/Docker/nginx/html:/var/www/html -p 80:80 --link php-fpm nginx
All directories & files are 755 privileges.
Config files r below :
nginx.conf
server {
listen 80 default_server;
server_name SkyEyeLab;
root /var/www/html;
fastcgi_read_timeout 90;
location ~ \.php {
fastcgi_pass php-fpm:9000;
}
}
And php-fpm.conf(some of important config sections):
listen 0.0.0.0:9000
listen.allowed_clients = any
Then I checked the environment of nginx & php-fpm :
[root#w-Lab01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6faf4a4b4f7e nginx "nginx -g 'daemon off" 19 minutes ago Up 19 minutes 0.0.0.0:80->80/tcp, 443/tcp nginx
9a6caff831d3 php:7.1-fpm "php-fpm" 20 minutes ago Up 20 minutes 9000/tcp php-fpm
[root#w-Lab01 ~]# docker exec 6faf4a4b4f7e ping -c3 php-fpm
PING php-fpm (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: icmp_seq=0 ttl=64 time=0.081 ms
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.018 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.041 ms
--- php-fpm ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.018/0.047/0.081/0.026 ms
[root#w-Lab01 ~]# docker exec 9a6caff831d3 ss -apn
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp LISTEN 0 128 *:9000 *:* users:(("php-fpm",pid=1,fd=7))
Everything seems fine. Then I create a.php under /data/Docker/nginx/html(which is mouted to nginx's /var/www/html directory) with following content :
<?php
phpinfo();
?>
Then access http://localhost:80/a.php in web browser.
But I only got an empty page, I checked the access.log of nginx :
[root#w-Lab01 ~]# docker logs 6faf4a4b4f7e
220.181.171.120 - - [11/Oct/2016:10:25:11 +0000] "GET /a.php HTTP/1.1" 200 31 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0"
220.181.171.120 - - [11/Oct/2016:10:25:12 +0000] "GET /a.php HTTP/1.1" 200 31 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0"
220.181.171.120 - - [11/Oct/2016:10:31:58 +0000] "GET /a.php HTTP/1.1" 200 31 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0"
220.181.171.120 - - [11/Oct/2016:10:31:59 +0000] "GET /a.php HTTP/1.1" 200 31 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0"
It seems a.php is correctly parsed & executed. But why I can not see phpinfo() result in web browser ?

well, after I changed nginx's config file :
server {
listen 80 default_server;
server_name SkyEyeLab;
root /var/www/html;
fastcgi_read_timeout 90;
location ~ \.php {
fastcgi_pass php-fpm:9000;
}
}
to
server {
listen 80 default_server;
server_name SkyEyeLab;
root /var/www/html;
fastcgi_read_timeout 90;
location ~ \.php {
fastcgi_pass php-fpm:9000;
include fastcgi.conf;
}
}
erverything goes fine.
fastcgi.conf is environment config file. you can check under your nginx's config directory(usually /etc/nginx), and see if there is fastcgi.conf or fastcgi_param in it.

maybe, if you want to use the name "php-fpm" in the nginx conf, you need to link the container like this:
docker run -d --name php-fpm -v /data/Docker/php-fpm/configs/:/usr/local/etc/php-fpm.d -v /data/Docker/nginx/html:/var/www/html php:7.1-fpm
and after:
docker run -d --name nginx --link php-fpm:php-fpm -v /data/Docker/nginx/configs/:/etc/nginx -v /data/Docker/nginx/html:/var/www/html -p 80:80 --link php-fpm nginx

Related

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.

docker-compose nginx return 502 to php-fpm

Please help me. There was an error, a minor error. Maybe I just do not see it, but I had no idea. The essence of the problem: I am setting up a docker environment. Brought nginx, fpm. When url get a php file, nginx return 502.
Structure:
/www
/app
/index.php
/index.html
/data
/db
/etc
/nginx
default.conf
/php
php.ini
php-fpm.conf
Compose + env:
version: '3.5'
services:
nginx:
image: nginx:alpine
volumes:
- "./etc/nginx/default.conf:/etc/nginx/conf.d/default.conf"
- "./etc/ssl:/etc/ssl"
- "./app:/var/www/html"
- "./etc/nginx/default.template.conf:/etc/nginx/conf.d/default.template"
ports:
- "80:80"
environment:
- NGINX_HOST=${NGINX_HOST}
command: /bin/sh -c "envsubst '$$NGINX_HOST' < /etc/nginx/conf.d/default.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
restart: always
depends_on:
- php
- mysqldb
- memcached
networks:
- app
php:
image: php:${PHP_VERSION}-fpm
restart: always
volumes:
- "./etc/php/php.ini:/usr/local/etc/php/conf.d/php.ini"
- "./etc/php/php-fpm.conf:/usr/local/etc/php-fpm.conf"
- "./app:/var/www/html"
networks:
- app
ports:
- "9000:9000"
networks:
- app
mysqldb:
image: mysql:${MYSQL_VERSION}
container_name: ${MYSQL_HOST}
restart: always
env_file:
- ".env"
environment:
- MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_USER=${MYSQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
ports:
- "3306:3306"
volumes:
- "./data/db/mysql:/var/lib/mysql"
networks:
- app
memcached:
image: memcached:${MEMCACHED_VERSION}
container_name: ${MEMCACHED_HOST}
ports:
- "11211:11211"
networks:
- app
networks:
app:
driver: bridge
#!/usr/bin/env bash
# See https://docs.docker.com/compose/environment-variables/#the-env-file
# Nginx
NGINX_HOST=localhost
# PHP
PHP_VERSION=5.4
# MySQL
MYSQL_VERSION=5.7.22
MYSQL_HOST=mysql
MYSQL_DATABASE=test
MYSQL_ROOT_USER=root
MYSQL_ROOT_PASSWORD=root
MYSQL_USER=dev
MYSQL_PASSWORD=dev
# Memcached
MEMCACHED_VERSION=latest
MEMCACHED_HOST=memcached
Nginx [/etc/nginx/default.conf]:
upstream phpserver {
server php:9000;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name localhost;
index index.php index.html;
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_pass phpserver;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
PHP [php-fpm.conf]:
[global]
error_log = /proc/self/fd/2
daemonize = no
[www]
; if we send this to /proc/self/fd/1, it never appears
access.log = /proc/self/fd/2
user = www-data
group = www-data
listen = 9000
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
clear_env = no
; Ensure worker stdout and stderr are sent to the main error log.
catch_workers_output = yes
PHP [php.ini] - ini file is default. 5.4. It does not include a user, directories before sessions, etc.
Such a structure. More... The phpv should be exactly this (5,4).
What steps did I take to find my error, but did not find:
curl localhost:80/index.html >> HELLO_WORLD
curl localhost:80/index.php >> 502 nginx
netstat -an |grep 9000 >> tcp6 0 0 :::9000 :::* LISTEN
curl localhost:80/index.php + docker-compose log >> nginx_1 | 2020/08/26 16:16:09 [error] 7#7: *3 connect() failed (113: Host is unreachable) while connecting to upstream, client: 172.26.0.1, server: localhost, request: "GET /index.php HTTP/1.1", upstream: "fastcgi://172.26.0.2:9000", host: "localhost" nginx_1 | 172.26.0.1 - - [26/Aug/2020:16:16:09 +0000] "GET /index.php HTTP/1.1" 502 157 "-" "curl/7.61.1" nginx_1 | 2020/08/26 16:16:09 [info] 7#7: *3 client 172.26.0.1 closed keepalive connection
php conteiner
root#..:/var/www/html# php index.html *>>* HELLO_WORLD
root#..:/var/www/html# php index.php *>>* HELLO_WORLD
php conteiner >> root#..:/var/www/html# ls -ll total 13 -rwxrwxrwx. 1 root root 8518 Aug 14 11:36 index.php -rwxrwxrwx. 1 root root 34 Aug 25 21:04 index.html
error_log /var/log/nginx/error.log debug; >> cat
/var/log/nginx/error.log - empty
Structure www/ - root:root
I'm sorry for wasting time. Please help me. Thank!
I have dealt with the problem. I do not want to write in stages, but I will say it in a nutshell. The problem is caused by the fact that my OS build is centos 8. First of all, the incorrect behavior of containers will show the use of Dockerfile, problems with the repo will be identified. It is possible to solve these problems, but for me it became a trigger, which shows that my environment is not correct. Then I went and installed all the packages for docker as directed for installation under Centos 8.
& see
https://computingforgeeks.com/install-docker-and-docker-compose-on-rhel-8-centos-8/

Nginx+PHP-FPM: connection refused while connecting to upstream (502)

I know there's a ton of posts regarding 502 Bad Gateway, but I haven't been able to solve this problem. I'm using Docker Compose to create separate containers for Nginx and PHP-FPM.
Error I get loading PHP files in the browser (HTML files render fine):
tc-web | 2018/01/22 19:22:46 [error] 5#5: *4 connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.1, server: localhost, request: "GET /info.php HTTP/1.1", upstream: "fastcgi://172.18.0.2:9000", host: "localhost:8080"
tc-web | 172.18.0.1 - - [22/Jan/2018:19:22:46 +0000] "GET /info.php HTTP/1.1" 502 575 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"
I've tried tweaking the various configs, using Unix socket, etc., for hours, and I still get 502 errors with PHP files. Can you spot what's wrong?
Here are all required files..
docker-composer.yml:
version: '3'
services:
web:
build:
context: ./docker/nginx
image: tc-web:0.1.0
container_name: tc-web
volumes:
# test files
- ./temp.html:/var/www/html/index.html
- ./temp.php:/var/www/html/info.php
ports:
- 8080:80
depends_on:
- php-fpm
php-fpm:
build:
context: ./docker/php-fpm
image: tc-php:0.1.0
container_name: tc-php
volumes:
- ./temp.html:/var/www/html/index.html
- ./temp.php:/var/www/html/info.php
docker/nginx/Dockerfile:
FROM nginx:1.13.8
# Install programs
RUN apt-get update
RUN apt-get install -y nano && \
apt-get install -y git && \
apt-get install -y procps
RUN mkdir -p /var/www/html
COPY nginx.conf /etc/nginx/nginx.conf
COPY default.conf /etc/nginx/conf.d/default.conf
docker/nginx/nginx.conf:
user www-data;
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;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/default.conf;
}
docker/nginx/default.conf:
server {
listen 80;
server_name localhost;
root /var/www/html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~* \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
docker/php-fpm/Dockerfile:
FROM php:7.0-fpm
# Install programs
RUN apt-get update
RUN apt-get install -y nano && \
apt-get install -y procps
RUN mkdir -p /var/www/html
COPY php-fpm.conf /usr/local/etc/php-fpm.conf
COPY www.conf /usr/local/etc/php-fpm.d/www.conf
docker/php-fpm/php-fpm.conf:
[global]
include=etc/php-fpm.d/www.conf
docker/php-fpm/www.conf:
[global]
;daemonize = no
; if we send this to /proc/self/fd/1, it never appears
error_log = /proc/self/fd/2
[www]
user = www-data
group = www-data
listen = 127.0.0.1:9000
;listen = /var/run/php-fpm/php7-fpm.sock
;listen.owner = www-data
;listen.group = www-data
;listen.mode = 0660
access.log = /proc/self/fd/2
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
; Ensure worker stdout and stderr are sent to the main error log.
catch_workers_output = yes
Problem could be in the www.conf file.
You are listening to 127.0.0.1:9000 but this way the service won't be reachable outside the container.
Try binding to 0.0.0.0:9000:
listen = 0.0.0.0:9000
This may sound very obvious, but another common issue would be that php-fpm is not installed. This can happen even though systemctl might say that the service is running but it's not really running anything. In my case, I had also installed PHP 8 with it's own fpm package, so if you have multiple php installations, there could have been a mix up with which fpm version you installed.

Connecting PHP-FPM with Nginx in Docker Compose

I'm fiddling with Docker, trying to setup a Docker composition with Nginx and PHP-FPM running on separate Alpine containers. My setup is available on GitHub at https://github.com/sparkbuzz/lemp_docker, my docker-compose.yml looks as follows:
version: '3'
services:
alpine_nginx:
build: ./nginx
container_name: alpine_nginx
links:
- alpine_php
ports:
- "80:80"
alpine_php:
build: ./php
container_name: alpine_php
ports:
- "9000:9000"
I am able to build the images successfully, and when I visit localhost in my browser, I can see the index.html served by Nginx. However, when trying to access phpinfo.php, I get a 502 - Bad Gateway error
I can docker exec -it ... /bin/ash into both the running instances, and it seems the services are running happily, however, it's clear PHP-FPM on port 9000 is never even hit.
Here's some feedback from my console:
Recreating alpine_php ...
Recreating alpine_php ... done
Recreating alpine_nginx ...
Recreating alpine_nginx ... done
Attaching to alpine_php, alpine_nginx
alpine_php | [06-Nov-2017 21:46:39] NOTICE: fpm is running, pid 1
alpine_php | [06-Nov-2017 21:46:39] NOTICE: ready to handle connections
alpine_nginx | 2017/11/06 21:46:46 [error] 6#6: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.20.0.1, server: localhost, request: "GET /index.php HTTP/1.1", upstream: "fastcgi://172.20.0.2:9000", host: "localhost"
alpine_nginx | 172.20.0.1 - - [06/Nov/2017:21:46:46 +0000] "GET /index.php HTTP/1.1" 502 568 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36" "-"```
I'm so close, but not sure why Nginx isn't happy with the PHP upstream. Nginx config is as follows:
server {
listen 80;
server_name localhost;
location / {
root /var/www/localhost/htdocs/;
index index.html;
}
location ~* \.php$ {
fastcgi_index index.php;
fastcgi_pass alpine_php:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /var/www/$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
}
How do I get Nginx talking to PHP FPM?
You are listen 127.0.0.1 in your php-fpm config.
Add this to php/Dockerfile
RUN sed -i 's/127.0.0.1:9000/0.0.0.0:9000/g' /etc/php7/php-fpm.d/www.conf

502 - Bad Gateway / "connection refused while connecting to upstream" through a fully unrestricted unix socket

TL;DR :
I have an application consisting in a nginx container linked to a php container and I get a connection refused (502 - Bad Gateway in the browser) if I try to reach my app while using a fully unrestricted (0777 mode) unix socket that both containers have access to.
I use docker-compose to manage my app and it runs on OSX with a docker-machine.
My problem :
I've set up a little project with two containers (nginx+php) and it works well with TCP sockets.
But I'd like to switch to unix sockets, and I get a 502 - Bad Gateway and the following logs when trying to reach my app :
nginx_1 | 2017/07/27 19:12:09 [error] 5#5: *1 connect() to unix:/sock/php.sock failed (111: Connection refused) while connecting to upstream, client: 192.168.99.1, server: 192.168.99.100, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/sock/php.sock:", host: "192.168.99.100:10080"
nginx_1 | 192.168.99.1 - - [27/Jul/2017:19:12:09 +0000] "GET / HTTP/1.1" 502 173 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:52.0) Gecko/20100101 Firefox/52.0"
nginx_1 | 192.168.99.1 - - [27/Jul/2017:19:12:09 +0000] "GET /favicon.ico HTTP/1.1" 502 173 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:52.0) Gecko/20100101 Firefox/52.0"
I've made the directory containing the sockets a named volume mounted on both containers (cf. docker-compose.yml bellow)
I don't understand why since the unix socket is accessible from both containers and is fully unrestricted :
From the php container :
/sock # ls -la
total 8
drwxrwxrwx 2 root root 4096 Jul 27 17:56 .
drwxr-xr-x 57 root root 4096 Jul 27 17:33 ..
-rwxrwxrwx 1 root root 0 Jul 27 17:30 php.sock
From the nginx container :
# cd /sock
# ls -la
total 8
drwxrwxrwx 2 root root 4096 Jul 27 17:56 .
drwxr-xr-x 31 root root 4096 Jul 27 17:33 ..
-rwxrwxrwx 1 root root 0 Jul 27 17:30 php.sock
I checked : modifying the /sock content in one container modifies also the content of the same directory in the other container.
What could the problem be?
Details about my project :
My project consists in the following arborescence :
.
├── docker-compose.yml
├── index.php
├── services
│   ├── app
│   │   └── Dockerfile
│   └── nginx
│   └── nginx.conf
├── [Other php sources files and directories]
└── static
└── foo.html
Here is my docker-compose.yml :
version: '3'
services:
db: # I have no problem with the DB so far.
image: mysql
environment:
- MYSQL_ROOT_PASSWORD=XXXXXXXX
- MYSQL_USER=XXXXXXXX
- MYSQL_PASSWORD=XXXXXXXX
- MYSQL_DATABASE=XXXXXXXX
volumes:
- /var/lib/app/app_DB:/var/lib/mysql
nginx:
image: nginx
volumes:
- /var/lib/app/media:/var/www/media:ro
- /Users/vmonteco/Code/web/app/static:/var/www/static:ro
- /Users/vmonteco/Code/web/app/services/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- /Users/vmonteco/Code/web/app:/var/www/html:ro
- unix_socket:/sock
ports:
- "10080:80"
- "10443:443"
app:
build:
context: services/app
# ports:
# - "19000:9000"
links:
- db
volumes:
- /var/lib/app/media:/var/www/media
- /Users/vmonteco/Code/web/app/static:/var/www/static:ro
- /Users/vmonteco/Code/web/app:/var/www/html:ro
- unix_socket:/sock
depends_on:
- db
volumes:
unix_socket:
Here is the app Dockerfile :
FROM php:7.1-fpm-alpine
RUN docker-php-ext-install pdo pdo_mysql
RUN mkdir /sock && chmod -R 777 /sock
VOLUME /sock
RUN sed -i '/;listen.mode = 0660/c\listen.mode = 0777' /usr/local/etc/php-fpm.d/www.conf && sed -i '/listen = 127.0.0.1:9000/c\listen = /sock/php.sock' /usr/local/etc/php-fpm.d/www.conf
The nginx configuration file :
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
root /var/www/html/;
server {
listen 80;
server_name 192.168.99.100;
location /media/ {
alias /var/www/media/;
autoindex off;
}
location /static/ {
alias /var/www/static/;
autoindex off;
}
location / {
try_files $uri $uri/ /index.php;
index index.html index.php;
}
location ~ \.php$ {
#try_files $uri =404;
#fastcgi_pass 192.168.99.100:19000;
fastcgi_pass unix:/sock/php.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS off;
fastcgi_index index.php;
}
}
}
(note that I have no problem to access /static/ or /media/ URLs.)
And all the uncommented lines in /usr/local/etc/php-fpm.d/www.conf file in the php container, that is modified at build :
[www]
user = www-data
group = www-data
listen = /sock/php.sock
listen.mode = 0777
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
I finally found the explanation :
The file to configure the fpm service wasn't /usr/local/etc/php-fpm.d/www.conf (or at least not only), but it was /usr/local/etc/php-fpm.d/zz-docker.conf :
[global]
daemonize = no
[www]
listen = [::]:9000
Modifying the listen directive in this file solved the problem.

Categories