Production deployment
Pre-built images from GHCR (recommended)
The fastest deployment path: no source code required. Images are published automatically on every release to GitHub Container Registry.
curl -O https://raw.githubusercontent.com/lad-sapienza/BraDypUS/v5/bradypus.yml
docker compose -f bradypus.yml pull
docker compose -f bradypus.yml up -dTo pin a specific version:
BDUS_VERSION=5.0.3 docker compose -f bradypus.yml up -dSee Deploy with pre-built images for the full guide.
Build from source
If you have cloned the repository and want to build the images locally:
docker compose -f docker-compose.prod.yml up -d --buildIn production, the node container (Vite dev server) is replaced by a static Nginx container serving the pre-built dist/ files.
Environment variables
Set these in docker-compose.prod.yml or via a .env file:
| Variable | Default | Description |
|---|---|---|
BRADYPUS_DEBUG | 0 | Set to 1 only for debugging |
BRADYPUS_ALLOW_NEW_APP | 0 | Set to 1 temporarily to create the first app |
BRADYPUS_CORS_ORIGIN | — | Space-separated allowed origins for cross-origin API access |
RESEND_API_KEY | — | API key for Resend, used to send password-reset and self-registration emails. One key covers every application on this instance. Leave unset to keep those features reported as unavailable instead of failing silently — see Login & authentication. |
MAIL_FROM_ADDRESS | — | Sender address for those emails. Must be on a domain verified in your Resend account. |
MAIL_FROM_NAME | BraDypUS | Sender display name. |
File uploads
The bdus-api image ships with upload_max_filesize = 64M / post_max_size = 72M (PHP's own defaults are 2M / 8M — too small for photos). The bdus-app frontend sets client_max_body_size 100m to match.
To allow larger files, bind-mount your own PHP config over the shipped one and raise client_max_body_size on every proxy in front:
# in the api service of docker-compose.prod.yml / bradypus.yml
volumes:
- ./php-uploads.ini:/usr/local/etc/php/conf.d/zz-bradypus.ini:ro# php-uploads.ini
upload_max_filesize = 256M
post_max_size = 300M
memory_limit = 512MShared hosting (PHP-only)
For hosts that support PHP but not Docker, follow the Manual installation guide and upload the files via SFTP/SSH.
SQLite on shared hosting
SQLite databases are stored as files in projects/{app}/db/. They can be downloaded and uploaded like any other file, making backups and migrations trivial.
HTTPS
Always run BraDypUS behind HTTPS in production. JWT tokens are transmitted in headers — without HTTPS they are exposed in transit.
When using a reverse proxy (Nginx, Caddy, Traefik), set the X-Forwarded-Proto header so BraDypUS knows the connection is over HTTPS. The backend trusts this header when building absolute URLs (e.g. the OAuth redirect_uri), so the proxy must set it explicitly and overwrite any value supplied by the client. The bundled bdus-app frontend already forwards it unchanged to the API.
The frontend container also sends baseline response headers (X-Content-Type-Options, X-Frame-Options, Referrer-Policy). Add Strict-Transport-Security — and a Content-Security-Policy if you maintain one — on the outer proxy, where TLS is terminated.
# Nginx example — proxy to a BraDypUS container exposing port 80
server {
server_name myapp.example.com;
location / {
proxy_pass http://127.0.0.1:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Data persistence
All application data (SQLite databases, uploaded files, configuration, backups) lives in the projects/ directory inside the bdus-api container. Both Compose files map this directory to a persistent Docker named volume called projects_data, so data survives container restarts and image updates.
To find where Docker stores the volume on disk:
docker volume inspect $(docker volume ls -q | grep projects_data)For backup and restore commands, see the Data persistence section of the pre-built images guide.
WARNING
On Docker Desktop (Mac / Windows) the volume lives inside the Docker VM and is not directly accessible from the host filesystem. Use docker run --rm -v projects_data:/data alpine ... to read or write files inside the volume.