Hi all,
I am having a problem plugging Caddy to php-fpm. I tried many thing without success, and it’s time to get some help.
Goal
Caddy as a reverse-proxy to a PHP application served with a containerized php-fpm
.
The main point here is that php-fpm is a docker container, exposing port 9000.
Failure
php-fpm does not see the php files. Only 404
are returned.
What works
Caddy successfully calls the php-fpm container.
Question
- It may be a permission problem, but all the user’s ID/GID are the same out and in the container
- Caddy’s
root
may be the problem, I tried setting it to a relative and absolute path - Are rewrite rules required ?
Symptom
When requesting a dumb index.php
with curl -v http://localhost:8080/
, php-fpm logs:
$ docker run --rm -p 9000:9000 -v $(pwd)/html:/var/www/html --user www-data --name php php:7-fpm
...
172.17.0.1 - 11/Oct/2016:13:25:20 +0000 "GET /index.php" 404
Reproducing
- Create the
Caddyfile
below and run caddy:caddy
- Create a dumb
index.php
in thehtml
subfolder - Mount the
html
folder in the container when running the container:docker run --rm -p 9000:9000 -v $(pwd)/html:/var/www/html --name php php:7-fpm
- Test with curl:
curl http://localhost:8080/
Full output
Caddy:
$ ./caddy
Activating privacy features... done.
http://localhost:8080
11/Oct/2016:15:55:33 +0200 [ERROR 0 /index.php] Primary script unknown
127.0.0.1 - [11/Oct/2016:15:55:33 +0200] "GET /index.php HTTP/1.1" 404 16
Php-fpm (running as user www-data
, same result as root
):
$ docker run --rm -p 9000:9000 -v $(pwd)/html:/var/www/html --name php --user www-data php:7-fpm
[11-Oct-2016 13:57:41] NOTICE: [pool www] 'user' directive is ignored when FPM is not running as root
[11-Oct-2016 13:57:41] NOTICE: [pool www] 'user' directive is ignored when FPM is not running as root
[11-Oct-2016 13:57:41] NOTICE: [pool www] 'group' directive is ignored when FPM is not running as root
[11-Oct-2016 13:57:41] NOTICE: [pool www] 'group' directive is ignored when FPM is not running as root
[11-Oct-2016 13:57:41] NOTICE: fpm is running, pid 1
[11-Oct-2016 13:57:41] NOTICE: ready to handle connections
172.17.0.1 - 11/Oct/2016:13:57:46 +0000 "GET /index.php" 404
Curl:
$ curl -v http://localhost:8080/index.php
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /index.php HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Content-Type: text/html; charset=UTF-8
< Server: Caddy
< Status: 404 Not Found
< X-Powered-By: PHP/7.0.11
< Date: Tue, 11 Oct 2016 13:55:33 GMT
< Content-Length: 16
<
File not found.
* Connection #0 to host localhost left intact
Caddy and Caddyfile
Repo with files: GitHub - tomsquest/caddy-with-phpfpm-docker: Sample config to reproduce a problem using Caddy fastcgi to a containerized php-fpm
$ ./caddy -version
Caddy 0.9.3
$ cat Caddyfile
:8080
root html
log stdout
errors stderr
fastcgi / localhost:9000 php
Files
The html
folder is owned locally by www-data
which has the sames UID/GID as in the php-fpm container.
Local files:
$ id www-data
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ ls -lRn
.:
total 14892
drwxrwxr-x 2 33 33 4096 oct. 11 15:40 html/
-rwxrwxr-x 1 1000 1000 15224588 oct. 11 15:40 caddy*
-rw-rw-r-- 1 1000 1000 91 oct. 11 15:41 Caddyfile
./html:
total 12
-rw-rw-r-- 1 33 33 4 oct. 11 15:39 index.php
Files in php-fpm:
$ docker run --rm -p 9000:9000 -v $(pwd)/html:/var/www/html --name php php:7-fpm id www-data
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ docker run --rm -p 9000:9000 -v $(pwd)/html:/var/www/html --name php php:7-fpm ls -lRn /var/www
/var/www:
total 4
drwxrwxr-x 2 33 33 4096 Oct 11 13:40 html
/var/www/html:
total 12
-rw-rw-r-- 1 33 33 4 Oct 11 13:39 index.php
html/index.php
$ cat html/index.php
<?php
phpinfo()
?>
With Nginx
I tried successfully with Nginx talking to the same container.
Files:
$ cat docker-compose.yml
nginx:
build: .
ports:
- "8080:80"
links:
- fpm
fpm:
image: php:fpm
ports:
- "9000:9000"
# seems like fpm receive the full path from nginx
# and try to find the files in this dock, so it must
# be the same as nginx.root
volumes:
- ./:/complex/path/to/files/
$ cat Dockerfile
FROM nginx:latest
COPY default.conf /etc/nginx/conf.d/
server {
listen 80;
# this path MUST be exactly as docker-compose.fpm.volumes,
# even if it doesn't exists in this dock.
root /complex/path/to/files;
location / {
try_files $uri /index.php$is_args$args;
}
location ~ ^/.+\.php(/|$) {
fastcgi_pass fpm:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}