ci: add frontend CD pipeline, server provisioning, TLS scripts
Some checks failed
Architecture Governance / architecture (push) Has been cancelled

There was no CD: pushing to main deployed nothing, and deploys were a manual
copy onto the server. This adds the missing half.

- .github/workflows/deploy.yml - build, upload to a per-commit release
  directory, swap the symlink atomically, reload nginx, verify over HTTP.
  The swap only happens after the upload is verified to contain index.html,
  so a failed deploy leaves the previous release serving.
- scripts/deploy/server-setup.sh - idempotent one-time provisioning: nginx,
  certbot, ufw, and a key-only deploy user whose sole sudo right is
  "systemctl reload nginx".
- scripts/deploy/add-domain.sh - per-domain server block plus TLS issuance,
  run once a domain's A record resolves to the server.
- docs/DEPLOYMENT.md - setup order, required CI secrets, rollback, limits.

Also adds .gitattributes: the shell scripts were being checked out with CRLF
endings, which makes bash fail on the shebang line on Linux.

Host keys are pinned via DEPLOY_KNOWN_HOSTS rather than trusted on first use.
No credentials are committed; all four deploy secrets are supplied by CI.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
sdarbinyan
2026-08-18 11:42:06 +04:00
parent 71da5a8d80
commit 28861953c8
5 changed files with 559 additions and 0 deletions

7
.gitattributes vendored Normal file
View File

@@ -0,0 +1,7 @@
* text=auto
# Anything executed by a Linux shell must keep LF endings. A CRLF checkout
# makes bash fail with "\r: command not found" on the very first line.
*.sh text eol=lf
*.yml text eol=lf
*.yaml text eol=lf