4.5 KiB
Deployment
RenewCMS ships as one self-contained executable. It serves:
| Path | What |
|---|---|
/v1/* |
JSON API |
/healthz |
Liveness check, returns 200 ok |
/* |
The Vue SPA (embedded), with fallback to index.html for client-side routes |
Its only runtime state is the SQLite database (DB_FILE) and the uploads directory (UPLOAD_DIR). Nothing else needs to be installed on the server.
1. Build
On any machine with the dev prerequisites:
task build # this OS/arch → bin/renewcms[.exe]
task release # all targets → bin/renewcms_<version>_<os>_<arch>[.exe]
The frontend is built once and embedded into every binary. The binaries are static (CGO_ENABLED=0), so a Linux build runs on any distribution. The version comes from git describe: tag a release (git tag v1.2.0) before building, and the binary logs its version at startup.
2. Lay out the server
The following is a suggested layout for Linux:
/opt/renewcms/renewcms the binary
/etc/renewcms/renewcms.env configuration (chmod 600, owned by root)
/var/lib/renewcms/ data: renewcms.db, uploads/ (owned by the service user)
sudo useradd --system --home /var/lib/renewcms --shell /usr/sbin/nologin renewcms
sudo install -d -o renewcms -g renewcms /var/lib/renewcms
sudo install -D -m 755 bin/renewcms_v1.2.0_linux_amd64 /opt/renewcms/renewcms
sudo install -D -m 600 /dev/null /etc/renewcms/renewcms.env # then edit it
/etc/renewcms/renewcms.env looks like this (see configuration.md for every variable):
ENVIRONMENT=production
PUBLIC_URL=https://cms.example.com
PORT=8080
DB_FILE=/var/lib/renewcms/renewcms.db
UPLOAD_DIR=/var/lib/renewcms/uploads
JWT_SECRET=<openssl rand -hex 32>
SMTP_EMAIL=noreply@example.com
SMTP_PASSWORD=...
SMTP_HOST=smtp.example.com
SMTP_PORT=465
3. Run it as a service (systemd)
/etc/systemd/system/renewcms.service:
[Unit]
Description=RenewCMS
After=network-online.target
Wants=network-online.target
[Service]
User=renewcms
Group=renewcms
WorkingDirectory=/var/lib/renewcms
EnvironmentFile=/etc/renewcms/renewcms.env
ExecStart=/opt/renewcms/renewcms
Restart=on-failure
# RenewCMS shuts down gracefully on SIGTERM (up to 10 s to finish requests and close the DB)
TimeoutStopSec=15
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
ReadWritePaths=/var/lib/renewcms
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now renewcms
journalctl -u renewcms -f
curl -fsS http://localhost:8080/healthz
On Windows, register the binary as a service with a wrapper such as NSSM or WinSW, and set the same environment variables.
4. Put HTTPS in front
With ENVIRONMENT=production the auth cookie is Secure, so the site must be served over HTTPS. Terminate TLS in a reverse proxy and keep RenewCMS on localhost.
Caddy handles certificates automatically:
cms.example.com {
reverse_proxy localhost:8080
}
nginx:
server {
listen 443 ssl http2;
server_name cms.example.com;
# ssl_certificate ... (e.g. certbot)
client_max_body_size 20m; # image uploads
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
If RenewCMS runs on the same host as the proxy, consider firewalling port 8080.
Backups
Everything worth backing up is under the data directory. Take a consistent SQLite copy while the service is running:
sqlite3 /var/lib/renewcms/renewcms.db ".backup '/backups/renewcms-$(date +%F).db'"
rsync -a /var/lib/renewcms/uploads/ /backups/uploads/
Alternatively, run systemctl stop renewcms, copy the directory, and run systemctl start renewcms.
Upgrading
- Back up (see above). The schema is migrated automatically at startup (GORM
AutoMigrate), and there is no down-migration. - Replace
/opt/renewcms/renewcmswith the new binary. - Run
sudo systemctl restart renewcms, then checkjournalctl -u renewcmsfor the new version line.
To roll back, put the previous binary back and restore the database backup if the schema changed.