Skip to content

Instantly share code, notes, and snippets.

@mstaack
Forked from devhammed/Caddyfile
Created May 3, 2026 06:23
Show Gist options
  • Select an option

  • Save mstaack/550a81192b73b96fcf5e2bbe9b790b89 to your computer and use it in GitHub Desktop.

Select an option

Save mstaack/550a81192b73b96fcf5e2bbe9b790b89 to your computer and use it in GitHub Desktop.
Laravel Docker Setup (Caddy, Frankenphp, Queue Worker, Octane, Scheduler, Reverb)
{
{$CADDY_GLOBAL_OPTIONS}
admin {$CADDY_SERVER_ADMIN_HOST}:{$CADDY_SERVER_ADMIN_PORT}
frankenphp {
worker {
file "{$APP_PUBLIC_PATH}/frankenphp-worker.php"
{$CADDY_SERVER_WORKER_DIRECTIVE}
{$CADDY_SERVER_WATCH_DIRECTIVES}
}
}
}
{$CADDY_EXTRA_CONFIG}
{$CADDY_SERVER_SERVER_NAME} {
log {
level {$CADDY_SERVER_LOG_LEVEL}
# Redact the authorization parameters...
format filter {
wrap {$CADDY_SERVER_LOGGER}
fields {
request>headers>X-Xsrf-Token replace REDACTED
request>query>authorization replace REDACTED
}
}
}
route {
root * "{$APP_PUBLIC_PATH}"
encode zstd br gzip
# Mercure configuration is injected here...
{$CADDY_SERVER_EXTRA_DIRECTIVES}
request_body {
max_size 256MB
}
@static {
file
path *.js *.css *.jpg *.jpeg *.webp *.weba *.webm *.gif *.png *.ico *.cur *.gz *.svg *.svgz *.mp4 *.mp3 *.ogg *.ogv *.htc *.woff2 *.woff
}
header @static Cache-Control "public, immutable, stale-while-revalidate, max-age=31536000"
@staticshort {
file
path *.json *.xml *.rss
}
header @staticshort Cache-Control "no-cache, max-age=3600"
@reverbApp path /app/*
reverse_proxy @reverbApp 127.0.0.1:8080
@reverbApps path /apps/*
reverse_proxy @reverbApps 127.0.0.1:8080
@rejected `path('*.bak', '*.conf', '*.dist', '*.fla', '*.ini', '*.inc', '*.inci', '*.log', '*.orig', '*.psd', '*.sh', '*.sql', '*.swo', '*.swp', '*.swop', '*/.*') && !path('*/.well-known/*')`
error @rejected 401
php_server {
index frankenphp-worker.php
try_files {path} frankenphp-worker.php
# Required for the public/storage/ directory...
resolve_root_symlink
}
}
}
# Setup base image
FROM dunglas/frankenphp:1-php8.5-bookworm
# Setup application root
WORKDIR /var/www/html
# Copy application source
COPY . .
# Install dependencies
RUN apt-get update && apt-get install -y \
git \
zip \
unzip \
libpq-dev \
libpng-dev \
libonig-dev \
libxml2-dev \
libicu-dev \
libuv1-dev \
curl \
supervisor \
ffmpeg \
&& install-php-extensions pdo_pgsql mbstring bcmath pcntl gd exif intl redis \
&& pecl install uv-beta \
&& docker-php-ext-enable uv \
&& rm -rf /var/lib/apt/lists/* \
&& curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer \
&& composer install --prefer-dist --no-ansi --no-dev --no-interaction --no-plugins --no-progress --no-scripts --optimize-autoloader --ignore-platform-reqs \
&& composer clear-cache \
&& composer dump-autoload --optimize \
&& php artisan storage:link \
&& curl -fsSL https://deb.nodesource.com/setup_24.x | bash - \
&& apt-get install -y nodejs \
&& npm install -g npm \
&& npm ci \
&& mkdir -p /var/www/html/storage/xdg/{data,config} \
&& chown -R www-data:www-data /var/www/html \
&& cp .docker/Caddyfile /etc/caddy/Caddyfile \
&& cp .docker/php.ini /usr/local/etc/php/conf.d/user-php.ini \
&& cp .docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf \
&& cp .docker/run.sh /usr/local/bin/run.sh \
&& chmod +x /usr/local/bin/run.sh
# Switch user
USER www-data
# Set XDG directories
ENV XDG_DATA_HOME=/var/www/html/storage/xdg/data
ENV XDG_CONFIG_HOME=/var/www/html/storage/xdg/config
# Expose FrankenPHP
EXPOSE 8000
# Start container
ENTRYPOINT ["/usr/local/bin/run.sh"]
upload_max_filesize = 128M
post_max_size = 256M
memory_limit = 512M
max_execution_time = 256
#!/bin/bash
# Exit on error
set -eux
# Run database migrations
php artisan migrate --force --seed
# Clear Laravel caches
php artisan optimize:clear
# Rebuild Laravel caches
php artisan optimize
# Build frontend assets
npm run build
# Start supervisor
exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
[supervisord]
user=www-data
nodaemon=true
minfds=50000
[program:frankenphp]
command=php artisan octane:frankenphp --host 0.0.0.0 --port 8000 --caddyfile /etc/caddy/Caddyfile --log-level INFO
directory=/var/www/html
autostart=true
autorestart=true
priority=5
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
[program:queue-worker]
command=php artisan queue:work database --sleep=3 --tries=3 --max-time=3600
process_name=%(program_name)s_%(process_num)02d
numprocs=10
directory=/var/www/html
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
stopwaitsecs=3600
priority=10
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
[program:scheduler]
command=php artisan schedule:work --run-output-file=/dev/stdout
directory=/var/www/html
autostart=true
autorestart=true
priority=10
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
[program:reverb]
command=php artisan reverb:start --host=127.0.0.1 --port=8080
directory=/var/www/html
autostart=true
autorestart=true
priority=10
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment