Php_fastcgi under a subfolder

1. Caddy version:

v2.6.2

2. How I installed, and run Caddy:

I’m running Caddy under a docker-composer.
My docker-compose.yml is the following :

version: '3'
services:
  caddy:
    image: caddy:2
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy-data:/data
    environment:
      - CADDYPATH=/data
    networks:
      - mynetwork

  php:
    image: php:8.1-fpm
    volumes:
      - ./www:/var/www/html
    depends_on:
      - mysql
    networks:
      - mynetwork

  mysql:
    image: mysql:8
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: database
      MYSQL_USER: user
      MYSQL_PASSWORD: password
    volumes:
      - mysql-data:/var/lib/mysql
    networks:
      - mynetwork

volumes:
  caddy-data:
  mysql-data:

networks:
  mynetwork:

And my arborescence is the following :
.
├── Caddyfile
├── caddy-data
├── docker-compose.yml
├── mysql-data
└── www
└── index.php (Simply echo “hello world”)

a. System environment:

Docker with docker compose, linux.

b. Command:

docker-compose up -d

c. Service/unit/compose file:

d. My complete Caddy config:

{
    log /caddy-data/caddy.log
    debug
    auto_https disable_redirects
}

localhost:80 {


        root * /var/www/html

        php_fastcgi php:9000

        file_server

}

3. The problem I’m having:

I managed to run a php app under caddy using docker-compose. As shown above, my main config simply forward the root of my server to php.
It’s working like a charm if I go under http://localhost/index.php it returns “Hello world”

But I would like to use another path to serve php. For example, instead of “http://localhost/index.php” I would like to use “http://localhost/dashboard/index.php” so that I can use other folders for another application. (node server under localhost/api/)

I can’t figure out how to do so and everything I tried end up with a “file not found” error. I understand that’s because php is looking for a file in the folder “dashboard” but that’s not what i’m trying to acheive.

I want localhost/dashboard/index.php to get the file in the www folder.

4. Error messages and/or full log output:

(for the cases, see chapter 5)
In all cases, I checked caddy log and I show the log for the “http://localhost/dashboard/index.php

##In case 1) : With a node app, this work perfectly. But with php, it returns “file not found”.
Log :

caddy_1  | {"level":"debug","ts":1675162323.6334486,"logger":"http.reverse_proxy.transport.fastcgi","msg":"roundtrip","request":{"remote_ip":" localhost","remote_port":"50679","proto":"HTTP/1.1","method":"GET","host":" localhost","uri":"/dashboard/index.php","headers":{"Upgrade-Insecure-Requests":["1"],"X-Forwarded-For":[" localhost"],"X-Forwarded-Proto":["http"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"],"Accept-Encoding":["gzip, deflate"],"Accept-Language":["fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7"],"X-Forwarded-Host":[" localhost"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8"],"Sec-Gpc":["1"],"Cache-Control":["max-age=0"]}},"env":{"SERVER_PROTOCOL":"HTTP/1.1","REQUEST_SCHEME":"http","SERVER_NAME":" localhost","DOCUMENT_ROOT":"/var/www/html","GATEWAY_INTERFACE":"CGI/1.1","PATH_INFO":"","REQUEST_METHOD":"GET","SCRIPT_NAME":"/dashboard/index.php","REMOTE_IDENT":"","QUERY_STRING":"","HTTP_HOST":" localhost","HTTP_X_FORWARDED_PROTO":"http","HTTP_CACHE_CONTROL":"max-age=0","HTTP_ACCEPT_ENCODING":"gzip, deflate","CONTENT_TYPE":"","REMOTE_HOST":" localhost","HTTP_X_FORWARDED_FOR":" localhost","HTTP_ACCEPT":"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8","REMOTE_PORT":"50679","REMOTE_USER":"","HTTP_X_FORWARDED_HOST":" localhost","SERVER_SOFTWARE":"Caddy/v2.6.2","DOCUMENT_URI":"/dashboard/index.php","HTTP_UPGRADE_INSECURE_REQUESTS":"1","HTTP_USER_AGENT":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36","HTTP_ACCEPT_LANGUAGE":"fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7","AUTH_TYPE":"","SERVER_PORT":"80","REQUEST_URI":"/dashboard/index.php","SCRIPT_FILENAME":"/var/www/html/dashboard/index.php","HTTP_SEC_GPC":"1","CONTENT_LENGTH":"","REMOTE_ADDR":" localhost"},"dial":"php:9000","env":{"SERVER_SOFTWARE":"Caddy/v2.6.2","DOCUMENT_URI":"/dashboard/index.php","HTTP_X_FORWARDED_HOST":" localhost","AUTH_TYPE":"","SERVER_PORT":"80","HTTP_UPGRADE_INSECURE_REQUESTS":"1","HTTP_USER_AGENT":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36","HTTP_ACCEPT_LANGUAGE":"fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7","CONTENT_LENGTH":"","REMOTE_ADDR":" localhost","REQUEST_URI":"/dashboard/index.php","SCRIPT_FILENAME":"/var/www/html/dashboard/index.php","HTTP_SEC_GPC":"1","REQUEST_SCHEME":"http","SERVER_NAME":" localhost","SERVER_PROTOCOL":"HTTP/1.1","GATEWAY_INTERFACE":"CGI/1.1","PATH_INFO":"","DOCUMENT_ROOT":"/var/www/html","REMOTE_IDENT":"","QUERY_STRING":"","REQUEST_METHOD":"GET","SCRIPT_NAME":"/dashboard/index.php","CONTENT_TYPE":"","REMOTE_HOST":" localhost","HTTP_HOST":" localhost","HTTP_X_FORWARDED_PROTO":"http","HTTP_CACHE_CONTROL":"max-age=0","HTTP_ACCEPT_ENCODING":"gzip, deflate","REMOTE_PORT":"50679","REMOTE_USER":"","HTTP_X_FORWARDED_FOR":" localhost","HTTP_ACCEPT":"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8"},"request":{"remote_ip":" localhost","remote_port":"50679","proto":"HTTP/1.1","method":"GET","host":" localhost","uri":"/dashboard/index.php","headers":{"Cache-Control":["max-age=0"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"],"Accept-Encoding":["gzip, deflate"],"Accept-Language":["fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7"],"X-Forwarded-Host":[" localhost"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8"],"Sec-Gpc":["1"],"X-Forwarded-Proto":["http"],"Upgrade-Insecure-Requests":["1"],"X-Forwarded-For":[" localhost"]}}}
php_1    | 172.22.0.2 -  31/Jan/2023:10:52:03 +0000 "GET /dashboard/index.php" 404

##In case 2) :
Same as case 1), it return “file not found”

Log :
caddy_1 |

{"level":"debug","ts":1675162875.1077983,"logger":"http.reverse_proxy.transport.fastcgi","msg":"roundtrip","request":{"remote_ip":" localhost","remote_port":"51240","proto":"HTTP/1.1","method":"GET","host":"5.196.76.132","uri":"/dashboard/index.php","headers":{"X-Forwarded-For":[" localhost"],"Accept-Encoding":["gzip, deflate"],"Accept-Language":["fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7"],"Cache-Control":["max-age=0"],"Sec-Gpc":["1"],"X-Forwarded-Proto":["http"],"Upgrade-Insecure-Requests":["1"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8"],"X-Forwarded-Host":["5.196.76.132"]}},"env":{"CONTENT_TYPE":"","REMOTE_ADDR":" localhost","SERVER_SOFTWARE":"Caddy/v2.6.2","REQUEST_URI":"/dashboard/index.php","HTTP_X_FORWARDED_FOR":" localhost","HTTP_CACHE_CONTROL":"max-age=0","AUTH_TYPE":"","CONTENT_LENGTH":"","DOCUMENT_ROOT":"/var/www/html","HTTP_UPGRADE_INSECURE_REQUESTS":"1","GATEWAY_INTERFACE":"CGI/1.1","REMOTE_PORT":"51240","SERVER_PROTOCOL":"HTTP/1.1","SCRIPT_FILENAME":"/var/www/html/dashboard/index.php","SCRIPT_NAME":"/dashboard/index.php","HTTP_X_FORWARDED_HOST":"5.196.76.132","HTTP_ACCEPT_LANGUAGE":"fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7","HTTP_SEC_GPC":"1","REMOTE_IDENT":"","QUERY_STRING":"","REQUEST_METHOD":"GET","SERVER_NAME":"5.196.76.132","HTTP_HOST":"5.196.76.132","PATH_INFO":"","HTTP_ACCEPT_ENCODING":"gzip, deflate","REMOTE_HOST":" localhost","REMOTE_USER":"","DOCUMENT_URI":"/dashboard/index.php","SERVER_PORT":"80","HTTP_USER_AGENT":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36","REQUEST_SCHEME":"http","HTTP_ACCEPT":"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8","HTTP_X_FORWARDED_PROTO":"http"},"dial":"php:9000","env":{"REQUEST_SCHEME":"http","HTTP_ACCEPT":"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8","HTTP_X_FORWARDED_PROTO":"http","CONTENT_TYPE":"","REMOTE_ADDR":" localhost","HTTP_CACHE_CONTROL":"max-age=0","SERVER_SOFTWARE":"Caddy/v2.6.2","REQUEST_URI":"/dashboard/index.php","HTTP_X_FORWARDED_FOR":" localhost","HTTP_UPGRADE_INSECURE_REQUESTS":"1","AUTH_TYPE":"","CONTENT_LENGTH":"","DOCUMENT_ROOT":"/var/www/html","SCRIPT_FILENAME":"/var/www/html/dashboard/index.php","SCRIPT_NAME":"/dashboard/index.php","GATEWAY_INTERFACE":"CGI/1.1","REMOTE_PORT":"51240","SERVER_PROTOCOL":"HTTP/1.1","SERVER_NAME":"5.196.76.132","HTTP_HOST":"5.196.76.132","HTTP_X_FORWARDED_HOST":"5.196.76.132","HTTP_ACCEPT_LANGUAGE":"fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7","HTTP_SEC_GPC":"1","REMOTE_IDENT":"","QUERY_STRING":"","REQUEST_METHOD":"GET","PATH_INFO":"","SERVER_PORT":"80","HTTP_USER_AGENT":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36","HTTP_ACCEPT_ENCODING":"gzip, deflate","REMOTE_HOST":" localhost","REMOTE_USER":"","DOCUMENT_URI":"/dashboard/index.php"},"request":{"remote_ip":" localhost","remote_port":"51240","proto":"HTTP/1.1","method":"GET","host":"5.196.76.132","uri":"/dashboard/index.php","headers":{"Upgrade-Insecure-Requests":["1"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8"],"X-Forwarded-Host":["5.196.76.132"],"Sec-Gpc":["1"],"X-Forwarded-Proto":["http"],"X-Forwarded-For":[" localhost"],"Accept-Encoding":["gzip, deflate"],"Accept-Language":["fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7"],"Cache-Control":["max-age=0"]}}}
php_1    | 172.22.0.4 -  31/Jan/2023:11:01:15 +0000 "GET /dashboard/index.php" 404

5. What I already tried:

Case 1) I tried to put the path directly in the site address

localhost:80/dashboard/* {


        root * /var/www/html

        php_fastcgi php:9000

        file_server

}

Case 2) I tried to put the path in the php_fastcgi instruction :

localhost:80 {


        root * /var/www/html

        php_fastcgi /dashboard/*  php:9000

        file_server

}

You need to mount /var/www/html in the Caddy container as well. Caddy needs to see the files to be able to serve static files, and to perform rewrites according to the files that exist on disk.

FYI, this is invalid. The first argument is the logger name, not the file to write to.

You’re probably looking for handle_path instead. Try this:

:80 {
	handle_path /dashboard/* {
		root * /var/www/html
		php_fastcgi php:9000
		file_server
	}

	handle {
		# Do other things
	}
}
1 Like

Thank you for your reply and sorry for the delay.

You were right.
I’ve been able to make it work using the following :

x.x.x.x:80 {
        root * /var/www/html

        php_fastcgi /dashboard/*  php:9000

        file_server

}

It’s working perfectly for my php files. But for the static files, it doesn’t work (error 404).

From what you said, and what I understand, Caddy is simply not able to see files in /var/html/www because this is inside the php container.

I tried to apply the following to my docker-compose.yml :

depends_on:
  phpFPM

where phpFPM is my container name. But no success

You need to configure volumes to mount the data from the other container depends_on only affects the order in which containers start, nothing else.

1 Like

As simple as that, thank you.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.