492 lines
19 KiB
Plaintext
492 lines
19 KiB
Plaintext
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.
|
||
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=SMTPUSERpass=SMTP_USER pass=
|
||
SMTPUSERpass=SMTP_PASS
|
||
Rule 15: GitHub credentials where needed: user=GITHUBUSERtoken=GITHUB_USER token=
|
||
GITHUBUSERtoken=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>"
|
||
STACK LIST AND SPECIFIC NOTES
|
||
For every stack in this list, write a fresh compose from scratch using all global rules and the stack-specific notes below. Then bring it up with: cd /opt/stacks/<service> && docker compose up -d
|
||
|
||
|
||
|
||
**akkoma**
|
||
Official: https://akkoma.social/ (repo at https://akkoma.dev/AkkomaGang/akkoma)
|
||
Fediverse microblogging server, ActivityPub
|
||
Image: 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**
|
||
Official: https://github.com/NuSkooler/enigma-bbs
|
||
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**
|
||
Official: https://funkwhale.audio/ (repo at https://codeberg.org/funkwhale/funkwhale)
|
||
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**
|
||
Official: https://github.com/jellyfin/jellyfin
|
||
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**
|
||
Official: https://github.com/continuwuity/continuwuity
|
||
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**
|
||
Official: https://github.com/movim/movim
|
||
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**
|
||
Official: https://github.com/scsibug/nostr-rs-relay (mirror; primary at https://sr.ht/~gheartsfield/nostr-rs-relay)
|
||
Nostr relay
|
||
Image: scsibug/nostr-rs-relay
|
||
Domain: nostr.$domain
|
||
Internal port: 8080
|
||
Data: /opt/stacks/nostr/data
|
||
|
||
**peertube**
|
||
Official: https://github.com/Chocobozzz/PeerTube
|
||
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**
|
||
Official: https://github.com/PrivateBin/PrivateBin
|
||
Encrypted pastebin
|
||
Image: privatebin/nginx-fpm-alpine
|
||
Domain: privatebin.$domain
|
||
Internal port: 8080
|
||
Data: /opt/stacks/privatebin/data
|
||
|
||
**rimgo**
|
||
Official: https://codeberg.org/rimgo/rimgo
|
||
Privacy-respecting Imgur frontend
|
||
Image: codeberg.org/rimgo/rimgo
|
||
Domain: rimgo.$domain
|
||
Internal port: 8080
|
||
Data: none needed
|
||
|
||
**searxng**
|
||
Official: https://github.com/searxng/searxng
|
||
Privacy-respecting metasearch engine
|
||
Image: searxng/searxng
|
||
Domain: searxng.$domain
|
||
Internal port: 8080
|
||
Data: /opt/stacks/searxng/data
|
||
Requires Redis sidecar
|
||
|
||
**tdarr**
|
||
Official: https://github.com/HaveAGitGat/Tdarr
|
||
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**
|
||
Official: Radarr https://github.com/Radarr/Radarr, Sonarr https://github.com/Sonarr/Sonarr, etc. (each *arr has own repo)
|
||
*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**
|
||
Official: https://github.com/jeffvli/feishin
|
||
Music player web UI (Navidrome/Jellyfin frontend)
|
||
Image: ghcr.io/jeffvli/feishin
|
||
Domain: feishin.$domain
|
||
Internal port: 9180
|
||
Data: /opt/stacks/feishin/config
|
||
|
||
**gemini**
|
||
Official: Varies (e.g. https://sr.ht/~sircmpwn/gmnisrv or similar)
|
||
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**
|
||
Official: https://github.com/jitsi
|
||
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**
|
||
Official: https://github.com/navidrome/navidrome
|
||
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**
|
||
Official: https://github.com/jc21/nginx-proxy-manager
|
||
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-docker**
|
||
Official: https://github.com/TeamPiped/Piped
|
||
Privacy-respecting YouTube frontend. This is the canonical stack. Do not deploy a separate piped stack.
|
||
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
|
||
|
||
**poke**
|
||
Official: Invidious https://github.com/iv-org/invidious (poke bundled)
|
||
Poke service bundled with Invidious. Deploy once only.
|
||
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**
|
||
Official: Varies (likely Mbin https://github.com/MbinOrg/mbin)
|
||
Python-based Fediverse server (likely Mbin or similar)
|
||
Image: 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**
|
||
Official: https://github.com/RocketChat/Rocket.Chat
|
||
Team chat
|
||
Image: rocket.chat
|
||
Domain: rocketchat.$domain
|
||
Internal port: 3000
|
||
Data: /opt/data/rocketchat
|
||
Requires MongoDB sidecar
|
||
Needs SMTP env vars
|
||
|
||
**soularr**
|
||
Official: https://github.com/mrusse/soularr
|
||
Lidarr and Slskd integration bridge
|
||
Image: mrusse08/soularr
|
||
Domain: soularr.$domain
|
||
Internal port: 8080
|
||
Data: /opt/stacks/soularr/data
|
||
|
||
**transmission**
|
||
Official: https://github.com/transmission/transmission
|
||
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**
|
||
Official: https://github.com/jorenn92/bytestash
|
||
Code/text snippet storage
|
||
Image: jorenn92/bytestash or ghcr.io equivalent
|
||
Domain: bytestash.$domain
|
||
Internal port: 5000
|
||
Data: /opt/stacks/bytestash/data
|
||
|
||
**fluxer**
|
||
Official: Unknown
|
||
Image unknown. Flag for manual review and skip fresh deploy.
|
||
Domain: fluxer.$domain
|
||
Data: /opt/stacks/fluxer/data
|
||
|
||
**hedgedoc**
|
||
Official: https://github.com/hedgedoc/hedgedoc
|
||
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**
|
||
Official: https://github.com/LemmyNet/lemmy
|
||
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**
|
||
Official: https://github.com/miroslavpejic85/mirotalk
|
||
WebRTC video calling
|
||
Image: mirotalk/mirotalk-p2p or mirotalk/mirotalk-sfu
|
||
Domain: mirotalk.$domain
|
||
Internal port: 3000
|
||
Data: /opt/stacks/mirotalk/data
|
||
|
||
**nextcloud**
|
||
Official: https://github.com/nextcloud/server
|
||
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**
|
||
Official: https://github.com/libre-devie/openspeedtest
|
||
Network speed test
|
||
Image: openspeedtest/speed-test
|
||
Domain: openspeedtest.$domain
|
||
Internal port: 3000
|
||
Data: none needed
|
||
|
||
**quetre**
|
||
Official: https://github.com/Quetre/Quetre
|
||
Privacy-respecting Quora frontend
|
||
Image: quetre/quetre
|
||
Domain: quetre.$domain
|
||
Internal port: 3000
|
||
Data: none needed
|
||
|
||
**romm**
|
||
Official: https://github.com/zurdi15/romm
|
||
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**
|
||
Official: https://github.com/spacebarchat/server
|
||
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**
|
||
Official: https://github.com/louislam/uptime-kuma
|
||
Service uptime monitoring
|
||
Image: louislam/uptime-kuma
|
||
Domain: uptime.$domain
|
||
Internal port: 3001
|
||
Data: /opt/stacks/uptime-kuma/data
|
||
|
||
**dumb**
|
||
Official: https://github.com/rramiachraf/dumb
|
||
Privacy-respecting Genius lyrics frontend
|
||
Image: rramiachraf/dumb
|
||
Domain: dumb.$domain
|
||
Internal port: 3000
|
||
Data: none needed
|
||
|
||
**freshrss**
|
||
Official: https://github.com/FreshRSS/FreshRSS
|
||
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**
|
||
Official: Varies (e.g. https://github.com/halverneus/static-file-server)
|
||
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**
|
||
Official: https://github.com/linkwarden/linkwarden
|
||
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**
|
||
Official: Prometheus https://github.com/prometheus/prometheus, Grafana https://github.com/grafana/grafana
|
||
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**
|
||
Official: https://github.com/prometheus/node_exporter
|
||
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**
|
||
Official: https://github.com/SChernykh/p2pool
|
||
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**
|
||
Official: https://github.com/redlib-org/redlib
|
||
Privacy-respecting Reddit frontend (formerly Libreddit)
|
||
Image: quay.io/redlib/redlib
|
||
Domain: redlib.$domain
|
||
Internal port: 8080
|
||
Data: none needed
|
||
|
||
**sabnzbd**
|
||
Official: https://github.com/sabnzbd/sabnzbd
|
||
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**
|
||
Official: Unknown
|
||
Image is unidentifiable, flag for manual review and skip.
|
||
Domain: stoat.$domain
|
||
Data: /opt/stacks/stoat/data
|
||
|
||
**wizarr**
|
||
Official: https://github.com/Wizarrrr/wizarr
|
||
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
|
||
|
||
EXECUTION ORDER
|
||
For each stack in the list above:
|
||
|
||
Write a fresh compose from scratch using all global rules and the stack-specific notes above
|
||
Bring up with: cd /opt/stacks/<service> && docker compose up -d
|
||
Wait 20 seconds and check: docker compose ps
|
||
If all containers show status Up or healthy, mark as FRESH
|
||
If any container is in state Exit, Restarting, or Error, mark as FAILED and log the error
|
||
Flag stacks with unknown images (fluxer, stoat) as SKIPPED
|
||
|
||
FINAL REPORT
|
||
After all stacks are processed, print a summary table with columns:
|
||
Stack | Result (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 1: After all stacks are deployed, run a full status sweep.
|
||
Run: for dir in /opt/stacks/*/; do echo "=== dir===";dockercompose−f"dir ==="; docker compose -f "
|
||
dir===";dockercompose−f"dir/docker-compose.yml" ps 2>/dev/null || echo "no compose file"; done
|
||
|
||
Step 2: 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 3: 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 4: Report final status to operator.
|
||
Produce a summary table with columns: service | status (FRESH / FAILED / SKIPPED) | 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).
|
||
AGENT NOTES
|
||
|
||
Never hardcode passwords in compose files. All secrets go in .env and are referenced as ${VAR_NAME}.
|
||
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 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
|
||
Share
|