chore: initial commit of Agent Resources
This commit is contained in:
481
deploy_instructions.txt
Normal file
481
deploy_instructions.txt
Normal file
@@ -0,0 +1,481 @@
|
||||
You are a homelab deployment agent. Read and follow these instructions completely before taking any action.
|
||||
|
||||
IDENTITY AND CONTEXT
|
||||
You are deploying Docker Compose stacks for a self-hosted homelab on Debian.
|
||||
The operator's username is gravitas. Stacks path is /opt/stacks. Large data path is /opt/data.
|
||||
Backups from the old server are at /home/sapient/backups.
|
||||
Secrets are loaded from ~/.secrets - source that file now: source ~/.secrets
|
||||
Confirm the following env vars are set before proceeding: GITHUB_TOKEN, SMTP_PASS, GITHUB_USER, SMTP_HOST, SMTP_USER
|
||||
If any are missing, halt and report which ones are unset.
|
||||
|
||||
GLOBAL RULES - READ THESE FIRST, APPLY TO EVERY STACK
|
||||
Rule 1: All stacks live under /opt/stacks/<service>/
|
||||
Rule 2: docker-compose.yml and config always go in /opt/stacks/<service>/
|
||||
Rule 3: Data volumes under 1-2GB estimated size use /opt/stacks/<service>/data/
|
||||
Rule 4: Data volumes expected to exceed 1-2GB (media, databases, large logs) use /opt/data/<service>/
|
||||
Rule 5: All bind mounts use relative path style in compose: ./data:/data
|
||||
Rule 6: Set user: '1000:1000' only when the image does not already define UID/GID
|
||||
Rule 7: Passwords and secrets go in /opt/stacks/<service>/.env only, never hardcoded in compose
|
||||
Rule 8: Generate secrets using: echo -n "<service_name>" | xxhsum | awk '{print $1}'
|
||||
Rule 9: Every service must join the traefik_proxy Docker network
|
||||
Rule 10: The traefik_proxy network is external. Add it at the bottom of every compose file: networks: traefik_proxy: external: true
|
||||
Rule 11: Do not expose ports to the host unless the service absolutely requires it (e.g. TURN servers, torrent peers). Use Traefik labels instead.
|
||||
Rule 12: Every service gets Traefik labels for TLS termination via letsencrypt
|
||||
Rule 13: Port offsets use this formula: offset = default_port + ((default_port * 7 + name_seed) % 2000) + 500 where name_seed = sum of ASCII values of the compose service name. Comment the original default port above the mapped port.
|
||||
Rule 14: SMTP credentials for any service that needs email: host=smtp.mailgun.org port=587 tls=true user=$SMTP_USER pass=$SMTP_PASS
|
||||
Rule 15: GitHub credentials where needed: user=$GITHUB_USER token=$GITHUB_TOKEN
|
||||
Rule 16: The Matrix server stack must use the image coturn/continuwuity, not Synapse or Dendrite
|
||||
Rule 17: The poke stack must include an Invidious container alongside poke itself
|
||||
Rule 18: Watchtower is assumed to be running globally and handles image updates. Do not add watchtower to individual stacks.
|
||||
|
||||
TRAEFIK LABEL TEMPLATE - apply this pattern to every service
|
||||
Replace <service> with the stack folder name and <internal_port> with the container's listening port:
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.<service>.rule=Host(`<service>.$domain`)"
|
||||
- "traefik.http.routers.<service>.entrypoints=websecure"
|
||||
- "traefik.http.routers.<service>.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.services.<service>.loadbalancer.server.port=<internal_port>"
|
||||
|
||||
BACKUP IMPORT PROCEDURE - do this for every single stack before writing a fresh compose
|
||||
Step 1: Check if a backup exists: ls /home/sapient/backups/<service>/
|
||||
Step 2: If a backup exists, attempt to restore it:
|
||||
mkdir -p /opt/stacks/<service>
|
||||
cp -r /home/sapient/backups/<service>/. /opt/stacks/<service>/
|
||||
If the backup includes a docker-compose.yml, read it and check if it is functional.
|
||||
A compose file is considered functional if: it has valid YAML syntax, images still exist on Docker Hub or ghcr.io, and it does not reference old hostnames or absolute paths that no longer exist.
|
||||
Step 3: If the restored compose is functional, bring the stack up: cd /opt/stacks/<service> && docker compose up -d
|
||||
Step 4: Wait 20 seconds and check: docker compose ps
|
||||
If all containers show status Up or healthy, mark this stack as SUCCESS and move on.
|
||||
If any container is in state Exit, Restarting, or Error, mark the restore as FAILED.
|
||||
Step 5: If the restore failed, bring the stack down: docker compose down
|
||||
Remove the broken compose: rm /opt/stacks/<service>/docker-compose.yml
|
||||
Keep any data directories that were restored. Write a fresh compose using the rules above and bring it up again.
|
||||
Step 6: If no backup existed at all, write a fresh stack from scratch using all global rules.
|
||||
|
||||
STACK LIST AND SPECIFIC NOTES
|
||||
Process each stack in this order. For each one, run the backup import procedure above, then apply any specific notes listed here.
|
||||
|
||||
akkoma
|
||||
Description: Fediverse microblogging server, ActivityPub
|
||||
Image: ghcr.io/superseriousbusiness/gotosocial or akkoma-er/akkoma (use akkoma-er/akkoma)
|
||||
Domain: akkoma.$domain
|
||||
Internal port: 4000
|
||||
Data: PostgreSQL db to /opt/data/akkoma/db, uploads to /opt/data/akkoma/uploads, config to /opt/stacks/akkoma/config
|
||||
Needs SMTP env vars
|
||||
Requires PostgreSQL sidecar container
|
||||
|
||||
enigma-bbs
|
||||
Description: Classic BBS software
|
||||
Image: enigmabbs/enigma-bbs
|
||||
Domain: enigma-bbs.$domain
|
||||
Internal port: 8080 (web), also exposes telnet 8888 to host (required for BBS clients)
|
||||
Data: /opt/stacks/enigma-bbs/data
|
||||
|
||||
funkwhale
|
||||
Description: Federated music streaming
|
||||
Image: funkwhale/all-in-one
|
||||
Domain: funkwhale.$domain
|
||||
Internal port: 80
|
||||
Data: music library to /opt/data/funkwhale/music, db to /opt/data/funkwhale/db, data to /opt/stacks/funkwhale/data
|
||||
Needs SMTP env vars
|
||||
Requires PostgreSQL and Redis sidecars
|
||||
|
||||
jellyfin
|
||||
Description: Media server
|
||||
Image: jellyfin/jellyfin
|
||||
Domain: jellyfin.$domain
|
||||
Internal port: 8096
|
||||
Data: config to /opt/stacks/jellyfin/config, cache to /opt/stacks/jellyfin/cache, media library at /opt/data/jellyfin/media
|
||||
If hardware acceleration is available add: devices: /dev/dri:/dev/dri
|
||||
|
||||
matrix
|
||||
Description: Matrix homeserver - MUST use continuwuity, not Synapse
|
||||
Image: ghcr.io/continuwuity/continuwuity
|
||||
Domain: matrix.$domain
|
||||
Internal port: 6167
|
||||
Data: /opt/data/matrix
|
||||
Note: This is the continuwuity (formerly conduwuit) Rust Matrix server. Do not substitute Synapse or Dendrite under any circumstances.
|
||||
|
||||
movim
|
||||
Description: XMPP-based social platform
|
||||
Image: movim/movim
|
||||
Domain: movim.$domain
|
||||
Internal port: 80
|
||||
Data: /opt/stacks/movim/data
|
||||
Requires PostgreSQL sidecar
|
||||
Needs SMTP env vars
|
||||
|
||||
nostr
|
||||
Description: Nostr relay
|
||||
Image: scsibug/nostr-rs-relay
|
||||
Domain: nostr.$domain
|
||||
Internal port: 8080
|
||||
Data: /opt/stacks/nostr/data
|
||||
|
||||
peertube
|
||||
Description: Federated video hosting
|
||||
Image: chocobozzz/peertube
|
||||
Domain: peertube.$domain
|
||||
Internal port: 9000
|
||||
Data: videos and large files to /opt/data/peertube, config to /opt/stacks/peertube/config
|
||||
Requires PostgreSQL and Redis sidecars
|
||||
Needs SMTP env vars
|
||||
|
||||
privatebin
|
||||
Description: Encrypted pastebin
|
||||
Image: privatebin/nginx-fpm-alpine
|
||||
Domain: privatebin.$domain
|
||||
Internal port: 8080
|
||||
Data: /opt/stacks/privatebin/data
|
||||
|
||||
rimgo
|
||||
Description: Privacy-respecting Imgur frontend
|
||||
Image: codeberg.org/rimgo/rimgo
|
||||
Domain: rimgo.$domain
|
||||
Internal port: 8080
|
||||
Data: none needed
|
||||
|
||||
searxng
|
||||
Description: Privacy-respecting metasearch engine
|
||||
Image: searxng/searxng
|
||||
Domain: searxng.$domain
|
||||
Internal port: 8080
|
||||
Data: /opt/stacks/searxng/data
|
||||
Requires Redis sidecar
|
||||
|
||||
tdarr
|
||||
Description: Media transcoding automation
|
||||
Image: ghcr.io/haveagitgat/tdarr
|
||||
Domain: tdarr.$domain
|
||||
Internal port: 8265
|
||||
Data: config and logs to /opt/stacks/tdarr/data, media at /opt/data/tdarr
|
||||
Also deploy tdarr-node sidecar in same compose
|
||||
|
||||
arrs
|
||||
Description: *arr media automation suite - this is one stack containing all of: Radarr, Sonarr, Lidarr, Readarr, Prowlarr, Bazarr
|
||||
Domains: radarr.$domain, sonarr.$domain, lidarr.$domain, readarr.$domain, prowlarr.$domain, bazarr.$domain
|
||||
Each service gets its own Traefik router label with its own subdomain
|
||||
Data: each arr's config goes to /opt/stacks/arrs/<arrname>/config, shared downloads at /opt/data/arrs/downloads, shared media at /opt/data/arrs/media
|
||||
|
||||
feishin
|
||||
Description: Music player web UI (Navidrome/Jellyfin frontend)
|
||||
Image: ghcr.io/jeffvli/feishin
|
||||
Domain: feishin.$domain
|
||||
Internal port: 9180
|
||||
Data: /opt/stacks/feishin/config
|
||||
|
||||
gemini
|
||||
Description: Gemini protocol server
|
||||
Image: a-gemini-server image such as gemini-server or gmnisrv
|
||||
Domain: gemini.$domain
|
||||
Internal port: 1965
|
||||
Note: Gemini uses its own protocol, expose port 1965 to host directly as Traefik does not proxy Gemini. Use host port 1965.
|
||||
Data: /opt/stacks/gemini/data
|
||||
|
||||
jitsi
|
||||
Description: Video conferencing
|
||||
Image: jitsi/web, jitsi/prosody, jitsi/jicofo, jitsi/jvb (full stack)
|
||||
Domain: jitsi.$domain
|
||||
Internal port: 80 on web container
|
||||
Note: JVB requires UDP port 10000 exposed to host for media. Add to compose: ports: - "10000:10000/udp"
|
||||
Data: config to /opt/stacks/jitsi/config
|
||||
|
||||
|
||||
navidrome
|
||||
Description: Music streaming server
|
||||
Image: deluan/navidrome
|
||||
Domain: navidrome.$domain
|
||||
Internal port: 4533
|
||||
Data: config to /opt/stacks/navidrome/data, music library at /opt/data/navidrome/music
|
||||
|
||||
npm
|
||||
Description: Nginx Proxy Manager
|
||||
Image: jc21/nginx-proxy-manager
|
||||
Domain: npm.$domain
|
||||
Internal port: 81 (admin UI)
|
||||
Note: This coexists with Traefik. Only manage non-Traefik routes through this. Do not conflict with Traefik on ports 80/443.
|
||||
Data: /opt/stacks/npm/data, /opt/stacks/npm/letsencrypt
|
||||
|
||||
piped
|
||||
Description: Privacy-respecting YouTube frontend
|
||||
Image: uses piped-docker compose setup (see piped-docker stack below - treat as same stack)
|
||||
Domain: piped.$domain
|
||||
Note: piped and piped-docker are the same stack. Use the piped-docker folder as canonical. Do not deploy twice.
|
||||
|
||||
poke
|
||||
Description: Poke service bundled with Invidious
|
||||
Note: This stack MUST contain both the poke container AND an Invidious container. They are deployed together in one compose file.
|
||||
Poke domain: poke.$domain
|
||||
Invidious domain: invidious.$domain
|
||||
Poke internal port: 8080
|
||||
Invidious internal port: 3000
|
||||
Each gets its own Traefik router label
|
||||
Invidious image: quay.io/invidious/invidious
|
||||
Data: /opt/stacks/poke/data for poke config, /opt/stacks/poke/invidious for Invidious config
|
||||
Invidious requires PostgreSQL sidecar in the same compose
|
||||
|
||||
pyfedi
|
||||
Description: Python-based Fediverse server (likely Mbin or similar)
|
||||
Image: check backup for image name, fallback to pytholabs/pyfedi or mbin/mbin
|
||||
Domain: pyfedi.$domain
|
||||
Internal port: 80
|
||||
Data: /opt/stacks/pyfedi/data
|
||||
Requires PostgreSQL and Redis sidecars
|
||||
Needs SMTP env vars
|
||||
|
||||
rocketchat
|
||||
Description: Team chat
|
||||
Image: rocket.chat
|
||||
Domain: rocketchat.$domain
|
||||
Internal port: 3000
|
||||
Data: /opt/data/rocketchat
|
||||
Requires MongoDB sidecar
|
||||
Needs SMTP env vars
|
||||
|
||||
soularr
|
||||
Description: Lidarr and Slskd integration bridge
|
||||
Image: mrusse08/soularr
|
||||
Domain: soularr.$domain
|
||||
Internal port: 8080
|
||||
Data: /opt/stacks/soularr/data
|
||||
|
||||
transmission
|
||||
Description: BitTorrent client
|
||||
Image: linuxserver/transmission
|
||||
Domain: transmission.$domain
|
||||
Internal port: 9091
|
||||
Data: config to /opt/stacks/transmission/config, downloads at /opt/data/transmission/downloads
|
||||
Peer port 51413 must be exposed to host on both TCP and UDP
|
||||
|
||||
bytestash
|
||||
Description: Code/text snippet storage
|
||||
Image: jorenn92/bytestash or ghcr.io equivalent
|
||||
Domain: bytestash.$domain
|
||||
Internal port: 5000
|
||||
Data: /opt/stacks/bytestash/data
|
||||
|
||||
fluxer
|
||||
Description: Check backup for exact image. If unknown, note it and skip fresh deploy, flag for manual review.
|
||||
Domain: fluxer.$domain
|
||||
Data: /opt/stacks/fluxer/data
|
||||
|
||||
hedgedoc
|
||||
Description: Collaborative markdown editor
|
||||
Image: quay.io/hedgedoc/hedgedoc
|
||||
Domain: hedgedoc.$domain
|
||||
Internal port: 3000
|
||||
Data: /opt/stacks/hedgedoc/data, uploads to /opt/stacks/hedgedoc/uploads
|
||||
Requires PostgreSQL sidecar
|
||||
Needs SMTP env vars
|
||||
|
||||
lemmy
|
||||
Description: Federated link aggregator
|
||||
Image: dessalines/lemmy + dessalines/lemmy-ui
|
||||
Domain: lemmy.$domain
|
||||
Internal port: 8536 (backend), lemmy-ui on 1234
|
||||
Traefik routes to lemmy-ui on 1234
|
||||
Data: config to /opt/stacks/lemmy/config, db to /opt/data/lemmy/db, images to /opt/data/lemmy/pictrs
|
||||
Requires PostgreSQL and pict-rs sidecars
|
||||
Needs SMTP env vars
|
||||
|
||||
mirotalk
|
||||
Description: WebRTC video calling
|
||||
Image: mirotalk/mirotalk-p2p or mirotalk/mirotalk-sfu
|
||||
Domain: mirotalk.$domain
|
||||
Internal port: 3000
|
||||
Data: /opt/stacks/mirotalk/data
|
||||
|
||||
nextcloud
|
||||
Description: File sync and collaboration suite
|
||||
Image: nextcloud:apache or nextcloud:fpm with nginx sidecar
|
||||
Domain: nextcloud.$domain
|
||||
Internal port: 80
|
||||
Data: nextcloud data to /opt/data/nextcloud/data, apps and config to /opt/stacks/nextcloud/html, db to /opt/data/nextcloud/db
|
||||
Requires PostgreSQL and Redis sidecars
|
||||
Needs SMTP env vars
|
||||
|
||||
openspeedtest
|
||||
Description: Network speed test
|
||||
Image: openspeedtest/speed-test
|
||||
Domain: openspeedtest.$domain
|
||||
Internal port: 3000
|
||||
Data: none needed
|
||||
|
||||
piped-docker
|
||||
Description: Same as piped stack. This is the canonical folder. Deploy here, skip the piped folder.
|
||||
Image: uses multiple containers: piped-backend, piped-frontend, piped-proxy
|
||||
Domain: piped.$domain (frontend), pipedapi.$domain (backend), pipedproxy.$domain (proxy)
|
||||
Each container gets its own Traefik router label and subdomain
|
||||
Data: /opt/stacks/piped-docker/data
|
||||
Requires PostgreSQL sidecar
|
||||
|
||||
quetre
|
||||
Description: Privacy-respecting Quora frontend
|
||||
Image: quetre/quetre
|
||||
Domain: quetre.$domain
|
||||
Internal port: 3000
|
||||
Data: none needed
|
||||
|
||||
romm
|
||||
Description: ROM management and game library
|
||||
Image: rommapp/romm
|
||||
Domain: romm.$domain
|
||||
Internal port: 8080
|
||||
Data: config to /opt/stacks/romm/config, roms at /opt/data/romm/library, db to /opt/data/romm/db
|
||||
Requires MariaDB sidecar
|
||||
|
||||
spacebar
|
||||
Description: Open source Discord-compatible server (formerly Fosscord)
|
||||
Image: spacebar/server
|
||||
Domain: spacebar.$domain
|
||||
Internal port: 3001
|
||||
Data: /opt/stacks/spacebar/data
|
||||
Needs SMTP env vars
|
||||
|
||||
uptime-kuma
|
||||
Description: Service uptime monitoring
|
||||
Image: louislam/uptime-kuma
|
||||
Domain: uptime.$domain
|
||||
Internal port: 3001
|
||||
Data: /opt/stacks/uptime-kuma/data
|
||||
|
||||
dumb
|
||||
Description: Privacy-respecting Genius lyrics frontend
|
||||
Image: rramiachraf/dumb
|
||||
Domain: dumb.$domain
|
||||
Internal port: 3000
|
||||
Data: none needed
|
||||
|
||||
freshrss
|
||||
Description: RSS feed aggregator
|
||||
Image: freshrss/freshrss
|
||||
Domain: freshrss.$domain
|
||||
Internal port: 80
|
||||
Data: /opt/stacks/freshrss/data, extensions to /opt/stacks/freshrss/extensions
|
||||
Needs SMTP env vars
|
||||
|
||||
httpserver
|
||||
Description: Simple static file HTTP server
|
||||
Image: halverneus/static-file-server or nginx:alpine
|
||||
Domain: httpserver.$domain
|
||||
Internal port: 8080
|
||||
Data: served files at /opt/stacks/httpserver/www
|
||||
|
||||
linkwarden
|
||||
Description: Bookmark and link archiving
|
||||
Image: ghcr.io/linkwarden/linkwarden
|
||||
Domain: linkwarden.$domain
|
||||
Internal port: 3000
|
||||
Data: /opt/stacks/linkwarden/data
|
||||
Requires PostgreSQL sidecar
|
||||
Needs SMTP env vars
|
||||
|
||||
monitoring
|
||||
Description: Metrics stack - deploy Prometheus and Grafana together in this one compose
|
||||
Prometheus domain: prometheus.$domain
|
||||
Grafana domain: grafana.$domain
|
||||
Prometheus internal port: 9090, Grafana internal port: 3000
|
||||
Each gets its own Traefik router label
|
||||
Data: Prometheus data to /opt/data/monitoring/prometheus, Grafana data to /opt/stacks/monitoring/grafana
|
||||
Prometheus config at /opt/stacks/monitoring/prometheus.yml
|
||||
|
||||
node-exporter
|
||||
Description: Prometheus system metrics exporter
|
||||
Image: prom/node-exporter
|
||||
Domain: node-exporter.$domain
|
||||
Internal port: 9100
|
||||
Note: Must mount host /proc, /sys, /rootfs as read-only. Standard node-exporter mounts:
|
||||
/proc:/host/proc:ro
|
||||
/sys:/host/sys:ro
|
||||
/:/rootfs:ro
|
||||
Add flags: --path.procfs=/host/proc --path.sysfs=/host/sys --collector.filesystem.mount-points-exclude=...
|
||||
|
||||
p2pool
|
||||
Description: Decentralized Monero mining pool
|
||||
Image: sethsimmons/p2pool
|
||||
Domain: p2pool.$domain
|
||||
Internal port: 3333
|
||||
Note: p2pool requires Monero daemon. Include monerod sidecar in same compose.
|
||||
Data: /opt/data/p2pool for blockchain, /opt/stacks/p2pool/config for p2pool config
|
||||
Monerod data at /opt/data/p2pool/monero
|
||||
|
||||
redlib
|
||||
Description: Privacy-respecting Reddit frontend (formerly Libreddit)
|
||||
Image: quay.io/redlib/redlib
|
||||
Domain: redlib.$domain
|
||||
Internal port: 8080
|
||||
Data: none needed
|
||||
|
||||
sabnzbd
|
||||
Description: Usenet downloader
|
||||
Image: linuxserver/sabnzbd
|
||||
Domain: sabnzbd.$domain
|
||||
Internal port: 8080
|
||||
Data: config to /opt/stacks/sabnzbd/config, downloads at /opt/data/sabnzbd/downloads, incomplete at /opt/data/sabnzbd/incomplete
|
||||
|
||||
stoat
|
||||
Description: Unknown image. Check backup for docker-compose.yml and image name. If backup is unusable and image is unidentifiable, flag for manual review and skip.
|
||||
Domain: stoat.$domain
|
||||
Data: /opt/stacks/stoat/data
|
||||
|
||||
wizarr
|
||||
Description: User invitation and onboarding portal for Jellyfin/Plex/Emby
|
||||
Image: ghcr.io/wizarrrr/wizarr
|
||||
Domain: wizarr.$domain
|
||||
Internal port: 5690
|
||||
Data: /opt/stacks/wizarr/data
|
||||
|
||||
DEDUPLICATION NOTES Check backups. If both have data, deploy both on separate subdomains. If one is empty, skip it.
|
||||
poke is listed twice in the input. Only deploy once.
|
||||
|
||||
EXECUTION ORDER
|
||||
For each stack in the list above, do the following in sequence:
|
||||
1. Run backup import procedure
|
||||
2. If restore succeeded, verify containers are up and healthy
|
||||
3. If restore failed or no backup, write fresh compose using all global rules and stack-specific notes
|
||||
4. Bring up with: cd /opt/stacks/<service> && docker compose up -d
|
||||
5. Log result as either: RESTORED, FRESH, FAILED, or SKIPPED (for deduplicates and unknowns)
|
||||
|
||||
FINAL REPORT
|
||||
After all stacks are processed, print a summary table with columns:
|
||||
Stack | Result (RESTORED/FRESH/FAILED/SKIPPED) | URL | Notes
|
||||
Flag any stacks that need manual review.
|
||||
Flag any stacks where the image could not be confirmed.
|
||||
List any stacks that require DNS records to be added for their subdomains.
|
||||
save to "Deployment_Report.md"
|
||||
|
||||
POST-DEPLOY VERIFICATION
|
||||
=========================
|
||||
|
||||
Step 14: After all stacks are deployed, run a full status sweep.
|
||||
Run: for dir in /opt/stacks/*/; do echo "=== $dir ==="; docker compose -f "$dir/docker-compose.yml" ps 2>/dev/null || echo "no compose file"; done
|
||||
|
||||
Step 15: Check for any containers in restart loops.
|
||||
Run: docker ps --filter "status=restarting"
|
||||
For each restarting container, run: docker logs <container_name> --tail 50
|
||||
Attempt to resolve, or flag for operator review.
|
||||
|
||||
Step 16: Verify Traefik is routing correctly.
|
||||
For each service with a web UI, confirm the subdomain resolves and returns a valid HTTP response.
|
||||
Run: curl -sk https://<service>.$domain | head -20
|
||||
A non-empty response that is not a Traefik 404 indicates successful routing.
|
||||
|
||||
Step 17: Report final status to operator.
|
||||
Produce a summary table with columns: service | status (RESTORED / FRESH / FAILED) | url | notes
|
||||
List any services skipped due to unknown image or unresolvable errors.
|
||||
List any services that need manual post-deploy configuration (admin password changes, initial setup wizards, API keys).
|
||||
|
||||
NOTES FOR THE AGENT
|
||||
===================
|
||||
|
||||
- Never hardcode passwords in compose files. All secrets go in .env and are referenced as ${VAR_NAME}.
|
||||
- If a backup exists and restores cleanly, prefer it over a fresh deploy.
|
||||
- If you encounter a service not in this list that exists in /home/sapient/backups, deploy it using the same conventions and include it in the final report.
|
||||
- Fish shell is the interactive shell on this server. If you need to write a script, use bash and note the Fish incompatibilities. Do not use Fish-specific syntax in scripts intended to run non-interactively.
|
||||
- The domain for all services is $domain. Substitute this wherever you see $hostdomain or $HOSTDOMAIN.
|
||||
- Source ~/.secrets at the start of every new shell session before running compose commands that need credentials.
|
||||
- All xxhsum commands use the -H0 (xxHash32) or default algorithm. Be consistent across all secret generation.
|
||||
- When in doubt about an image tag, pull latest and check: docker inspect <image> | grep -i version
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user