closes board-viewer-cron-deploy Two-service stack at /opt/stacks/board-viewer/ on VDS: - board-viewer-build (node:22-alpine): cron-loop `while true; do node cli.ts; sleep 300`, writes to shared docker volume `dist` - board-viewer-web (nginx:alpine): serves dist read-only, Traefik route Host(`board.kzntsv.site`) → letsEncrypt + basic-auth middleware Files: - deploy/Dockerfile.build — build image (registry.kzntsv.site/board-viewer-build) - deploy/docker-compose.yml — stack with traefik labels (`proxy` network, same as Gitea) - deploy/nginx.conf — static serving with Cache-Control - deploy/auth.toml.example — Gitea token + board_viewer_repos whitelist - deploy/.env.example — BOARD_VIEWER_USERS for basic-auth (with $$ escape note) - deploy/README.md — DNS setup + image build/push + bootstrap + smoke + DR steps Configs are declarative ([skip-tdd: visual]). Acceptance = deploy + curl (see README §4 'Verify'). Both auth.toml and .env are gitignored. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
24 lines
473 B
Nginx Configuration File
24 lines
473 B
Nginx Configuration File
server {
|
|
listen 80 default_server;
|
|
server_name _;
|
|
root /usr/share/nginx/html;
|
|
index index.html;
|
|
|
|
charset utf-8;
|
|
charset_types text/plain text/css application/javascript text/html;
|
|
|
|
location = / {
|
|
try_files /index.html =404;
|
|
add_header Cache-Control "no-cache, must-revalidate" always;
|
|
}
|
|
|
|
location /static/ {
|
|
expires 5m;
|
|
add_header Cache-Control "public, max-age=300" always;
|
|
}
|
|
|
|
location / {
|
|
try_files $uri $uri/ /index.html;
|
|
}
|
|
}
|