Production Hosting
Run the CMS behind HTTPS, preserve uploads, supervise the process, and support real-time connections.
These examples assume a downloaded release in /srv/brad. Adapt users, paths, ports, and storage to your infrastructure. Complete installation and core migrations before starting the supervised service.
Configure HTTPS ingress
Terminate HTTPS at your reverse proxy or hosting platform, then forward requests to the application's listening port. Preserve the public host and scheme so the installer sees the intended domain. Forward WebSocket upgrades for /socket.io.
Set APP_URL=https://app.example.com in the application environment. A working public homepage alone does not confirm that password-reset links or real-time connections use the correct origin.
An Nginx location inside an existing TLS-enabled server block can use:
location / {
proxy_pass http://127.0.0.1:3333;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 120s;
}This is a proxy fragment, not a full certificate or firewall configuration. Set upload limits and timeouts suitable for the files your users send. Keep the application port private when the proxy is the only intended ingress.
Supervise the process
A basic single-process systemd service for a release can look like:
[Unit]
Description=BRAD CMS
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=brad
WorkingDirectory=/srv/brad
ExecStart=/usr/bin/node /srv/brad/bin/server.js
Restart=on-failure
RestartSec=5
TimeoutStopSec=20
[Install]
WantedBy=multi-user.targetCreate the brad service user, grant it access to the application and storage, and adjust the Node path. The application reads /srv/brad/.env. Enable the service through your normal server administration process and verify restart behavior.
If using the repository's PM2 ecosystem file, follow its build layout: the file supervises build/bin/server.js from the parent directory. That source-build layout differs from a release whose entrypoint is bin/server.js at the archive root. Adapt the script path and working directory for a downloaded release; do not copy a mismatched configuration unchanged.
Containers and managed application hosts
The release can include a Dockerfile and entrypoint. The bundled image uses Node.js 24, installs the release dependencies, and applies core migrations at container startup before launching the app.
Provide DATABASE_URL, the canonical APP_URL, and durable storage. In the bundled container, the application lives under /app; use an appropriate APP_ROOT and persistent mount for storage/. Confirm the process can reach PostgreSQL and bind to the ingress port.
Do not regenerate the compiled Prisma client inside the downloaded release. Do not store uploads only in a disposable image layer.
Multiple processes and real-time traffic
The CMS uses Socket.IO with WebSocket transport. Configure REDIS_URL when using independently supervised processes, replicas, or Passenger, and for larger production workloads. Every application process must use the intended Redis instance and the same installation database.
The internal cluster adapter can cover workers managed by the application's own primary process, but it does not connect unrelated primaries. Redis is the production scaling path.
Do not confuse cross-worker socket broadcasting with shared file storage. Multiple replicas must also see the same uploads, or use a supported external upload provider.
Production verification
- Restart the application and confirm it returns without manual shell intervention.
- Check
/api/healthfor HTTP reachability. - Open Settings → System Health for database, storage, license, and module checks.
- Sign in over HTTPS and confirm the session survives a normal page refresh.
- Test a real-time feature between two browser sessions.
- Upload a small file, restart the app, and confirm it still loads.
- Test an outgoing message and inspect its public links.
The lightweight health endpoint returns process availability; it is not a full database or license readiness check. Use it alongside application health and logs.