Files
vacationplanner2ics/deploy/README.md
T
2026-09-10 21:05:59 +04:00

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.