refac: rethought the complete workflow and deployement flow ; docs etc.
This commit is contained in:
1 parent
4a6209a8db
commit
09bd5afa4a
26 files changed
+800
-334
No files matched your search
@@ -0,0 +1,145 @@
|
||||
# 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](development.md#prerequisites):
|
||||
|
||||
```sh
|
||||
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)
|
||||
```
|
||||
|
||||
```sh
|
||||
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](configuration.md) for every variable):
|
||||
|
||||
```sh
|
||||
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`:
|
||||
|
||||
```ini
|
||||
[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
|
||||
```
|
||||
|
||||
```sh
|
||||
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](https://nssm.cc/) or [WinSW](https://github.com/winsw/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](https://caddyserver.com) handles certificates automatically:
|
||||
|
||||
```caddyfile
|
||||
cms.example.com {
|
||||
reverse_proxy localhost:8080
|
||||
}
|
||||
```
|
||||
|
||||
nginx:
|
||||
|
||||
```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:
|
||||
|
||||
```sh
|
||||
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
|
||||
|
||||
1. Back up (see above). The schema is migrated automatically at startup (GORM `AutoMigrate`), and there is no down-migration.
|
||||
2. Replace `/opt/renewcms/renewcms` with the new binary.
|
||||
3. Run `sudo systemctl restart renewcms`, then check `journalctl -u renewcms` for the new version line.
|
||||
|
||||
To roll back, put the previous binary back and restore the database backup if the schema changed.
|
||||
Reference in new issue
Block a user