Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
APP_KEY=
# When true, request_content in error logs is NOT encrypted
APP_DEBUG=true
APP_DEBUG=false
APP_URL=http://127.0.0.1:8000

REQUEST_SIGNATURE=_CHANGE_ME_
Expand Down
16 changes: 8 additions & 8 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,17 +271,17 @@ The repository contains both the server-side application and the web frontend.
| `resources/frontend/` | Vue frontend application |
| `modules/` | Backend modules |
| `tests/` | Backend unit and feature tests |
| `runtime/` | Runtime configuration for nginx, PHP, and cron |
| `runtime/` | Runtime configuration for Caddy, PHP, and cron |
| `init/` | Container entrypoint and Pebble service configuration |
| `build/base/` | apko definitions for runtime and builder images |
| `build/packages/` | Melange package definitions |
| `.github/workflows/` | GitHub Actions workflows |
| `.helm/` | Helm deployment files |

The production application is distributed as a single container containing the backend, compiled frontend, nginx, Laravel Octane, queue worker, Laravel Reverb, and scheduled jobs.
The production application is distributed as a single container containing the backend, compiled frontend, Caddy, Laravel Octane, queue worker, Laravel Reverb, and scheduled jobs.

The production build is Wolfi-based: the builder uses Node.js 24 with pnpm 12.5.1,
and the runtime uses PHP 8.3, nginx, Pebble, Laravel Octane, and Laravel Reverb.
and the runtime uses PHP 8.3, Caddy, Pebble, Laravel Octane, and Laravel Reverb.

## Development requirements

Expand Down Expand Up @@ -431,8 +431,8 @@ php artisan schedule:work

The local development server does not reproduce the complete production runtime.

Production uses nginx on port 8080 and Laravel Octane with Swoole. Pebble supervises
nginx, Octane, Reverb, the queue worker, and scheduled jobs in the rootless runtime.
Production uses Caddy on port 8080 and Laravel Octane with Swoole. Pebble supervises
Caddy, Octane, Reverb, the queue worker, and scheduled jobs in the rootless runtime.

## Frontend development

Expand Down Expand Up @@ -717,7 +717,7 @@ podman build -t cattr-server .

The final image runs as UID/GID `10000`, uses `/opt/cattr/app` as its working
directory, and stores mutable Laravel data under `/opt/cattr/app/storage`.
The image exposes nginx on `8080`, Reverb on `8081`, and Octane on `8090`.
The image exposes Caddy on `8080`, Reverb on `8081`, and Octane on `8090`.

The base images can be overridden with:

Expand All @@ -737,7 +737,7 @@ The production container uses Pebble to manage its services and initialization s
The runtime includes:

```text
nginx
Caddy
Laravel Octane
Laravel Queue
Laravel Reverb
Expand Down Expand Up @@ -768,7 +768,7 @@ build/base/builder/apko.yaml
```

The Wolfi builder image contains Composer, PHP 8.3 builder extensions, Node.js 24,
Git, OpenSSH, and Corepack. The runtime image contains PHP 8.3, nginx, Pebble,
Git, OpenSSH, and Corepack. The runtime image contains PHP 8.3, Caddy, Pebble,
supercronic, and the packages needed to run Cattr.

Corepack is packaged with Melange:
Expand Down
9 changes: 4 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,10 @@ RUN chown -R 10000:10000 /opt/cattr/app/bootstrap/cache /opt/cattr/app/storage
USER 10000:10000

# Cattr-specific configuration lives under /opt/cattr/etc. Program-specific
# system configuration remains in the conventional /etc/php and /etc/nginx.
# system configuration remains in the conventional /etc/php and /etc/caddy.
COPY --chown=0:0 --chmod=0644 runtime/supercronic/crontab /opt/cattr/crontab
COPY --chown=0:0 --chmod=0644 runtime/php/conf.d/99-cattr.ini /etc/php/conf.d/99-cattr.ini
COPY --chown=0:0 --chmod=0644 runtime/nginx/nginx.conf /etc/nginx/nginx.conf
COPY --chown=0:0 --chmod=0644 runtime/nginx/conf.d/app.conf /etc/nginx/conf.d/app.conf
COPY --chown=0:0 --chmod=0644 runtime/caddy/Caddyfile /etc/caddy/Caddyfile

# Pebble needs a writable per-user state directory; the base image creates it
# as UID/GID 10000. The layer itself is application data copied at image build.
Expand All @@ -108,8 +107,8 @@ USER 10000:10000

VOLUME ["/opt/cattr/app/storage"]

# 8080 nginx, 8081 Reverb, 8090 Octane. The latter two matter when a role is
# deployed without nginx in front of it.
# 8080 Caddy, 8081 Reverb, 8090 Octane. The latter two matter when a role is
# deployed without Caddy in front of it.
EXPOSE 8080 8081 8090

STOPSIGNAL SIGTERM
Expand Down
4 changes: 3 additions & 1 deletion build/base/runtime/apko.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ contents:

- pebble
- supercronic=0.2.49-r3
- nginx-mainline=1.31.6-r0
- caddy
Comment thread
vermorag marked this conversation as resolved.
Outdated

# Local metapackage pins PHP and all required extensions.
- php83-local

environment:
HOME: /opt/cattr
XDG_CONFIG_HOME: /tmp/caddy/config
XDG_DATA_HOME: /tmp/caddy/data
PATH: /usr/sbin:/sbin:/bin:/usr/bin

paths:
Expand Down
2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ services:
condition: service_healthy
volumes:
- backend_storage:/opt/cattr/app/storage
env_file:
- .env
Comment thread
vermorag marked this conversation as resolved.
Comment thread
vermorag marked this conversation as resolved.
Comment thread
vermorag marked this conversation as resolved.
ports:
- "8080:8080"

Expand Down
2 changes: 1 addition & 1 deletion docs/backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ Serve for production
pnpm --filter cattr-docs-backend start
```

> Notice: you should proxy nginx to localhost:4000
> Notice: you can put a reverse proxy in front of localhost:4000.
2 changes: 1 addition & 1 deletion docs/frontend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ Serve for production
pnpm --filter cattr-docs-frontend start
```

> Notice: you should proxy nginx to localhost:4000
> Notice: you can put a reverse proxy in front of localhost:4000.
23 changes: 12 additions & 11 deletions init/container-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,8 @@ prepare_directories() {
/opt/cattr/app/storage/framework/sessions \
/opt/cattr/app/storage/framework/views \
/opt/cattr/app/storage/logs \
/tmp/nginx/client_body \
/tmp/nginx/fastcgi \
/tmp/nginx/proxy \
/tmp/nginx/scgi \
/tmp/nginx/uwsgi
/tmp/caddy/data \
/tmp/caddy/config
}

cache_configuration() {
Expand Down Expand Up @@ -131,23 +128,27 @@ for role in "$@"; do
# Preserve the historical single-container behaviour.
run_migrations=1
run_provision=1
add_service nginx
add_service caddy
add_service reverb
add_service queue
add_service scheduler
;;
web)
# nginx requires app in the Pebble plan. Reverb stays in the web
# pod because the default nginx config proxies WebSockets to
# Caddy requires app in the Pebble plan. Reverb stays in the web
# pod because the default Caddy config proxies WebSockets to
# 127.0.0.1:8081.
add_service nginx
add_service caddy
add_service reverb
;;
app)
add_service app
;;
nginx)
add_service nginx
# Keep the historical role name as an alias for existing deploys.
add_service caddy
;;
caddy)
add_service caddy
;;
queue)
add_service queue
Expand All @@ -170,7 +171,7 @@ for role in "$@"; do
;;
*)
log "ERROR: unknown Cattr role: ${role}"
log "Supported roles: all web app nginx queue reverb scheduler migrate provision setup exec"
log "Supported roles: all web app caddy queue reverb scheduler migrate provision setup exec (nginx is a legacy alias for caddy)"
exit 64
;;
esac
Expand Down
9 changes: 6 additions & 3 deletions init/pebble/001-cattr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@ services:
on-failure: shutdown
kill-delay: 30s

nginx:
caddy:
override: replace
summary: Cattr HTTP reverse proxy and static file server
command: nginx -e stderr -g "daemon off;"
summary: Cattr Caddy reverse proxy and static file server
command: caddy run --config /etc/caddy/Caddyfile --adapter caddyfile
environment:
XDG_CONFIG_HOME: /tmp/caddy/config
XDG_DATA_HOME: /tmp/caddy/data
startup: disabled
requires:
- app
Expand Down
44 changes: 44 additions & 0 deletions runtime/caddy/Caddyfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
admin off
}

:8080 {
root * /opt/cattr/app/public
encode gzip
header {
-Server
-Via
}
Comment thread
vermorag marked this conversation as resolved.
Outdated
log {
output stdout
}
request_body {
max_size 512MiB
}

@websocket {
header Connection *Upgrade*
header Upgrade websocket
}
Comment thread
vermorag marked this conversation as resolved.
Outdated
@php path *.php
@static {
file {path}
Comment thread
vermorag marked this conversation as resolved.
Outdated
not path *.php
}

route {
reverse_proxy @websocket 127.0.0.1:8081

reverse_proxy @php 127.0.0.1:8090 {
header_up SERVER_PORT {server_port}
Comment thread
vermorag marked this conversation as resolved.
Outdated
header_up REMOTE_ADDR {remote_host}
}

file_server @static

reverse_proxy 127.0.0.1:8090 {
header_up SERVER_PORT {server_port}
header_up REMOTE_ADDR {remote_host}
}
}
}
72 changes: 0 additions & 72 deletions runtime/nginx/conf.d/app.conf

This file was deleted.

Loading
Loading