Deployment and Operations
Deployment-and-Operations.mdDeployment and Operations
Deployment Flow
deployment is GitHub Actions driven.
current chain:
- push to
main code lintworkflow runs- if lint passes,
deploy to fridg3.orgruns from the successful workflow event - repo is rsynced to
/var/www/fridg3.org
Deploy Workflow
/.github/workflows/deploy.yml
main details:
- triggered by successful
code lintworkflow completion - only deploys pushes to
main - installs
rsyncandopenssh-client - uses
DEPLOY_KEY - deploy target is
deploy@45.76.134.105:/var/www/fridg3.org
What Does Not Deploy
deployment uses .rsyncignore, so these are excluded:
/data/**sitemap.xml- repo docs and local config files
.github/**/scripts/**- local editor/codex folders
/others/toast-discord-bot/bot/venv/**
that means production runtime data is expected to already exist on the server.
Server Permissions
from README.md:
- project files should belong to
deploy:http - directories should be
755 - files should be
644 /dataandsitemap.xmlneedhttp:httpownership for webserver writes
Nginx Config Source
the repo-tracked files in .nginx/ are the source for the production nginx config.
.nginx/nginx.confcorresponds to/etc/nginx/nginx.conf.nginx/fridg3.orgcorresponds to/etc/nginx/sites-enabled/fridg3.org- production uses these through symlinks, so edits here are real server config edits, not examples
when adding routes, APIs, uploads, redirects, or private data folders, check .nginx/fridg3.org as part of the feature. a correct PHP route can still fail if nginx redirects POSTs, misses a clean-url rewrite, or accidentally exposes/blocklists the wrong /data path.
Nginx Clean URLs
production nginx needs explicit rewrites for PHP routes that accept path-style ids. without these, nginx falls through to the root /index.php fallback before the route can parse the URL.
the contact route is configured POST-safe at /contact, old /email paths redirect to /contact, and /data/contact/ is blocked from direct web access.
mdpaste share links use /others/mdpaste/s/{id} and need this block before the generic location / fallback. keep the regexes quoted, because nginx treats unquoted {16} like cursed config syntax.
# mdpaste clean URLs
location ~ "^/others/mdpaste/s/[a-fA-F0-9]{16}/?$" {
rewrite "^/others/mdpaste/s/([a-fA-F0-9]{16})/?$" /others/mdpaste/s/index.php?id=$1 last;
}
location /others/mdpaste/s/ { try_files $uri $uri/ /others/mdpaste/s/index.php?$args; }
location /others/mdpaste/ { try_files $uri $uri/ /others/mdpaste/index.php?$args; }
Backup Workflow
/.github/workflows/backup-data.yml
what it does:
- ssh to the server
- zip
/var/www/fridg3.org/data - download the archive to the runner
- upload it to Google Drive using
rclone - keep only the 10 newest backups
- delete temp archives from runner and server
triggers:
- manual
workflow_dispatch - scheduled daily cron at
0 0 *
required secrets:
DEPLOY_KEYGDRIVE_BACKUP_FOLDER_IDRCLONE_CONFIG
setup notes live in /.github/workflows/backup-data-setup.md.
Sitemap Generation
sitemap.xml is not deployed from git. it is generated by /api/sitemap, which means:
- the file must be writable by the server
- the server copy is the one that matters
Operational Truths
- this repo is source code, not a full backup
/datais operational state- if prod data disappears, git will not magically save you
- if file permissions are wrong, deploys and runtime writes will get weird fast