Docker setup with PHP FPM isn't redirecting to index.php

1. Caddy version (caddy version): caddy:2.3.0-alpine

2. How I run Caddy:

Caddy Dockerfile

FROM caddy:2.3.0-alpine

COPY Caddyfile /etc/caddy/Caddyfile

a. System environment:

Docker compose environment

Application is any basic starter application either Laravel or Symfony
Ex: An application created with
composer create-project symfony/website-skeleton my_project_name

FROM php:8.0.3-fpm

RUN apt-get update && apt-get install -y \
    bash \
    git \
    curl \
    libpng-dev \
    libonig-dev \
    libxml2-dev \
    zip \
    unzip \
    libpq-dev

COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"
RUN docker-php-ext-install pgsql pdo_pgsql
RUN docker-php-ext-configure pgsql -with-pgsql=/usr/include/postgresql/
WORKDIR /app
COPY src /app
RUN composer install

b. Command:

paste command here

c. Service/unit/compose file:

version: '3.2'

services:
  caddy:
    build: ./server
    restart: unless-stopped
    ports:
      - "2015:2015"
  app:
    build:
      context: ./app
      dockerfile: Dockerfile
    volumes:
      - ./app/src:/app
paste full file contents here

d. My complete Caddyfile or JSON config:

{
  debug
}

:2015
root * /app/public
log
encode gzip
php_fastcgi app:9000
file_server

3. The problem I’m having:

Caddy doesn’t redirect to index.php unless i specifically write index.php to end of the url.

4. Error messages and/or full log output:

caddy_1 | {“level”:“debug”,“ts”:1617630691.9167953,“logger”:“http.handlers.file_server”,“msg”:“sanitized path join”,“site_root”:"/app/public",“request_path”:"/",“result”:"/app/public"}
caddy_1 | {“level”:“error”,“ts”:1617630691.9169376,“logger”:“http.log.access”,“msg”:“handled request”,“request”:{“remote_addr”:“",“proto”:“HTTP/1.1”,“method”:“GET”,“host”:“localhost:2015”,“uri”:"/",“headers”:{“Connection”:[“keep-alive”],“Cookie”:,“Upgrade-Insecure-Requests”:[“1”],“Cache-Control”:[“max-age=0”],“User-Agent”:[“Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0”],“Accept”:[“text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8”],“Accept-Encoding”:[“gzip, deflate”],“Accept-Language”:[“en-US,en;q=0.5”]}},“common_log”:”*** - - [05/Apr/2021:13:51:31 +0000] “GET / HTTP/1.1” 404 0",“duration”:0.000209998,“size”:0,“status”:404,“resp_headers”:{“Server”:[“Caddy”]}}

5. What I already tried:

I tried modifying Caddyfile with hundred different options nothing worked.

6. Links to relevant resources:

You didn’t mount the PHP source to the Caddy container – Caddy needs to be able to see the files as well, so it can use the existence of files on disk to determine how to route the request. You should also add this to your Caddy container:

    volumes:
      - ./app/src:/app
3 Likes

This is not strictly necessary, if this is an API only PHP application (as in no additional assets not running through PHP).
We have this running in a development project.
The Caddyfile is simply this:

http://accounts.example.com {
  root * /var/www
  rewrite * /index.php?{query}
  php_fastcgi accounts:9000
}

and the docker-compose.yml (slightly simplified)

version: "2"
services:
    webserver:
        env_file: 
            - webserver.env
        image: caddy:alpine
        volumes:
            - ./etc/caddy/Caddyfile:/etc/caddy/Caddyfile
        ports:
            - "127.0.0.1::80"
        restart: unless-stopped
        networks:
            - middleware_net

    accounts:
        env_file: 
            - accounts.env
        image: "registry.example.com/accounts:test"
        expose:
             - "9000"
        volumes:
            - "./etc/php/php.ini:/usr/local/etc/php/php.ini"
            - media-volume:/var/www/media
        restart: unless-stopped
        networks:
            - middleware_net

In the accounts image is only the php api application (based on symfony libs, but not created with composer), running everything through the index.php as the front controller.

This is running on a dmz system, running behind an external Caddy reverse proxy (at the moment it runs internally on http, but will rework this to https when 2.4.0 is released and my internal CA configuration is stiil working)

Sure, but that’s besides the point. The large majority of users won’t be serving pure API sites, and in this case the error from the user is clear in that they’re making a request to the path / which Caddy responds to with a 404 because there’s no files on disk to serve.

1 Like

But he wants to redirect it to index.php.
Maybe it is only necessary to add the rewrite line to his Caddyfile:

rewrite * /index.php?{query}

That’s already the default behaviour of php_fastcgi, if index.php exists on disk (and visible to Caddy) because of the try_files logic built in (see the expanded form):

1 Like

Thanks everybody for responses, on top of finding my response I found some extra probable options.
So thanks again

1 Like

FWIW, don’t forget to set up a volume for /data for the Caddy container. See the docs on Docker Hub for an explanation

1 Like