60 lines
3.0 KiB
Markdown
60 lines
3.0 KiB
Markdown
# VPS deployment
|
|
|
|
These files configure the maintainer's Debian 12 server with Podman 4.3,
|
|
systemd and nginx. The nginx configuration uses the existing wildcard
|
|
certificate at `/etc/letsencrypt/live/popov.link/` and the server's TLS settings.
|
|
|
|
| Source | Installed path |
|
|
| --- | --- |
|
|
| `vacationplanner.service` | `/etc/systemd/system/vacationplanner.service` |
|
|
| `vacationplanner.conf` | `/etc/nginx/sites-available/vacationplanner.conf` |
|
|
| `index.html` | `/var/www/vacationplanner/index.html` |
|
|
|
|
Enable the nginx site with a symlink in `/etc/nginx/sites-enabled/`. Validate
|
|
the unit with `systemd-analyze verify`, run `systemctl daemon-reload`, then
|
|
`systemctl enable --now vacationplanner.service`. Run `nginx -t` before
|
|
`systemctl reload nginx`. Back up existing configuration before replacing it.
|
|
|
|
The container listens on `127.0.0.1:8080` using host networking. It runs as
|
|
`65532:65532`, with a read-only filesystem, no capabilities or additional
|
|
privileges, and limits of 128 MiB without swap, 0.5 CPU and 64 processes.
|
|
systemd restarts it after an exit and checks `/healthz` before marking the
|
|
start successful. Graceful shutdown allows 65 seconds.
|
|
|
|
Only `/calendar.ics` is proxied. Other valid GET/HEAD paths serve the same
|
|
HTML 4.01 Strict page; unsupported methods return `405`. Calendar limits are
|
|
6 requests/minute per IP with a burst of 4, 2 requests/second overall with a
|
|
burst of 16, and 4 concurrent requests per IP or 16 overall. Rejections return
|
|
`429` and `Retry-After: 60`. Client addresses come from nginx's existing
|
|
trusted proxy configuration. Both virtual hosts disable access and error
|
|
logging; calendar responses are not cached or buffered to disk.
|
|
|
|
## Updates and recovery
|
|
|
|
The existing `podman-auto-update.timer` checks the registry daily. The
|
|
`io.containers.autoupdate=registry` label and `PODMAN_SYSTEMD_UNIT` connect
|
|
the container to its unit. Podman's default rollback restores the previous
|
|
image if restarting the updated service fails, including its HTTP readiness
|
|
check. Ordinary restarts use the saved image with `--pull=missing`.
|
|
|
|
```sh
|
|
sudo systemctl status vacationplanner.service podman-auto-update.timer
|
|
curl --fail http://127.0.0.1:8080/healthz
|
|
sudo podman auto-update --dry-run
|
|
```
|
|
|
|
Before an update, retain a known-good image under a separate local tag and
|
|
record its digest. This also protects it from the existing timer's image
|
|
pruning. To recover manually, tag that saved image as
|
|
`code.popov.link/valentineus/vacationplanner2ics:latest` and restart
|
|
`vacationplanner.service`. If the registry image is still faulty, temporarily
|
|
remove the container's auto-update label from this unit before restarting;
|
|
restore it when a fixed image is available. Restore nginx files from the
|
|
backup, validate them and reload nginx if the proxy change must be reverted.
|
|
|
|
HTML validation uses OpenSP with the W3C HTML 4.01 Strict DTD, HTML Tidy and
|
|
Lynx in Docker. Deployment checks use a local mock API to exercise query
|
|
forwarding, routes, headers, rate limits and concurrent request limits.
|
|
Use fake credentials for these checks and verify logging before making a
|
|
real calendar request.
|