Deploy laravel dockerize using caddy

1. The problem I’m having:

I have a dockerized laravel app which uses php8.3-fpm as base image, the app works when using nginx without ssl. Default laravel nginx conf provided in docs (Deployment - Laravel 11.x - The PHP Framework For Web Artisans)

Now I want to use caddy for deployment
my Caddyfile

DOMAIN {
    root * /var/www/html/public
    file_server

    php_fastcgi app:9000 {
        index index.php
    }

    @try_files {
        file {
            try_files {path} {path}/ /index.php?{query}
        }
    }
    rewrite @try_files {http.matchers.file.relative}

    respond /.ht* 403
}

DOMAIN is getting replaced by CI/CD.
I can access https://DOMAIN, but I only receive “File not found.”, the 404 is shown in the logs of the php container. “GET /index.php” 404

My docker-compose file:

services:
  app:
    build:
      context: ./docker/php
    volumes:
      - ./:/var/www/html
    environment:
      - APP_ENV=local
      - APP_DEBUG=true
      - DB_HOST=db
      - DB_PORT=3306
      - DB_DATABASE=${DB_DATABASE}
      - DB_USERNAME=${DB_USERNAME}
      - DB_PASSWORD=${DB_PASSWORD}
    networks:
      - laravel

  queue:
    build:
      context: ./docker/php
    restart: unless-stopped
    depends_on:
      - db
      - redis
    volumes:
      - ./:/var/www/html
    command:
      - /bin/bash
      - -c
      - "php artisan horizon"
    networks:
      - laravel

  web:
    image: nginx:latest
    ports:
      - "8000:80"
    volumes:
      - ./:/var/www/html
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - app
    networks:
      - laravel

  caddy:
    image: caddy:latest
    restart: always
    depends_on:
      - app
      - db
      - redis
    volumes:
      - ./docker/Caddyfile:/etc/caddy/Caddyfile
      - ./:/var/www/html
      - caddy_data:/data
      - caddy_config:/config
    ports:
      - "80:80"
      - "443:443"
    networks:
      - laravel

  db:
    image: mariadb:11
    volumes:
      - dbdata:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
      MYSQL_ROOT_HOST: '%'
      MYSQL_DATABASE: '${DB_DATABASE}'
      MYSQL_USER: '${DB_USERNAME}'
      MYSQL_PASSWORD: '${DB_PASSWORD}'
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
    networks:
      - laravel

  redis:
    image: redis:latest
    networks:
      - laravel

networks:
  laravel:
    driver: bridge

volumes:
  dbdata:
  caddy_data:
  caddy_config:

2. Error messages and/or full log output:

{"level":"info","ts":1722434967.1232936,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
Error: adapting config using caddyfile: /etc/caddy/Caddyfile:4: unrecognized directive: logs
{"level":"info","ts":1722434967.845685,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
Error: adapting config using caddyfile: /etc/caddy/Caddyfile:4: unrecognized directive: logs
{"level":"info","ts":1722434968.472727,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
Error: adapting config using caddyfile: /etc/caddy/Caddyfile:4: unrecognized directive: logs
{"level":"info","ts":1722434969.2899618,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
Error: adapting config using caddyfile: /etc/caddy/Caddyfile:4: unrecognized directive: logs
{"level":"info","ts":1722434970.5444362,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
Error: adapting config using caddyfile: /etc/caddy/Caddyfile:4: unrecognized directive: logs
{"level":"info","ts":1722434972.531269,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
Error: adapting config using caddyfile: /etc/caddy/Caddyfile:4: unrecognized directive: logs
{"level":"info","ts":1722434976.2031136,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
Error: adapting config using caddyfile: /etc/caddy/Caddyfile:4: unrecognized directive: logs
{"level":"info","ts":1722434983.0037699,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
Error: adapting config using caddyfile: /etc/caddy/Caddyfile:4: unrecognized directive: logs
{"level":"info","ts":1722434996.1406574,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
Error: adapting config using caddyfile: /etc/caddy/Caddyfile:4: unrecognized directive: logs
{"level":"info","ts":1722435022.066345,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
Error: adapting config using caddyfile: parsing caddyfile tokens for 'php_fastcgi': unrecognized subdirective param, at /etc/caddy/Caddyfile:10
{"level":"info","ts":1722435073.6095667,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
Error: adapting config using caddyfile: parsing caddyfile tokens for 'php_fastcgi': unrecognized subdirective param, at /etc/caddy/Caddyfile:10
{"level":"info","ts":1722435133.9515722,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
{"level":"info","ts":1722435133.9529414,"msg":"adapted config to JSON","adapter":"caddyfile"}
{"level":"warn","ts":1722435133.9529624,"msg":"Caddyfile input is not formatted; run 'caddy fmt --overwrite' to fix inconsistencies","adapter":"caddyfile","file":"/etc/caddy/Caddyfile","line":2}
{"level":"info","ts":1722435133.9539216,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]}
{"level":"info","ts":1722435133.9542818,"logger":"http.auto_https","msg":"server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS","server_name":"srv0","https_port":443}
{"level":"info","ts":1722435133.9543064,"logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
{"level":"info","ts":1722435133.9546776,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0x4000449b00"}
{"level":"info","ts":1722435133.954879,"logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2","h3"]}
{"level":"info","ts":1722435133.954928,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
{"level":"info","ts":1722435133.954984,"msg":"failed to sufficiently increase receive buffer size (was: 208 kiB, wanted: 7168 kiB, got: 416 kiB). See https://github.com/quic-go/quic-go/wiki/UDP-Buffer-Sizes for details."}
{"level":"info","ts":1722435133.9550653,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
{"level":"info","ts":1722435133.9550707,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["***"]}
{"level":"info","ts":1722435133.955816,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
{"level":"info","ts":1722435133.9558358,"msg":"serving initial configuration"}
{"level":"info","ts":1722435133.9574745,"logger":"tls","msg":"storage cleaning happened too recently; skipping for now","storage":"FileStorage:/data/caddy","instance":"4fe47fb6-74a7-4559-bfb6-624abfd89b5a","try_again":1722521533.9574728,"try_again_in":86399.9999996}
{"level":"info","ts":1722435133.9576988,"logger":"tls","msg":"finished cleaning storage units"}

3. Caddy version:

v2.8.4 h1:q3pe0wpBj1OcHFZ3n/1nl4V4bxBrYoSoab7rL9BMYNk=

4. How I installed and ran Caddy:

Using docker-compoe

a. System environment:

Docker on Ubuntu 22.04

Thank you for your help guys.

b. Command:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

c. Service/unit/compose file:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

d. My complete Caddy config:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

5. Links to relevant resources:

If your PHP container logs a 404 then the Caddy config is working. Did you mean to set index to something other than index.php then, if you don’t have an index.php ?

No, Laravels default file is /public/index.php

I tried to adapt my nginx configuration, but I didn’t find some of the php fpm directives in caddy:

server {
    listen 80;
    index index.php index.html;
    root /var/www/html/public;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }
}

This nginx conf works, I can access my laravel app. So therefore I don’t think the error is on the app.

Do you have an index.html as well? I think your nginx config is serving that, while your caddy config is serving /index.php because of that index config line.

You might not need the index line, or perhaps you need to add a matcher on the php_fastcgi clause so it only matches *.php, like the nginx config does.

No, there is only index.php, htaccess, robots and some css files in the public folder. Not sure, why I had index.html in there, but isn’t needed.

So the only 2 directives I don’t have in my caddyfile are

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;

Apperantly, restarting the whole server fixed it.
Now it works with

DOMAIN {
    root * /var/www/html/public
    encode gzip
    php_fastcgi app:9000
    file_server
}

Not sure why a simple docker-compose down and up didn’t fix it.

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