Docker Compose Writer
Overview
Three modes:
Selection Mode — User asks for a category or vague need → present 3–4 real options → user picks → generate complete stack.
Direct Mode — User names a specific app or describes a full custom stack → generate immediately.
Optimize Mode — User pastes existing docker-compose.yml → audit and fix issues → write improved version.
Language: Respond in the user's language. YAML keys and comments always in English.
Step 1 — Detect Mode and Handle "Replace X" Requests
First, map "I want to replace X" requests to the right category:
| User wants to replace / run |
Point to |
| Google Drive / Dropbox |
File Storage → Nextcloud, Seafile |
| Google Photos / iCloud Photos |
Photos → Immich |
| Gmail / email hosting |
Email → Mailcow, Mailu |
| GitHub / GitLab |
Git Hosting → Gitea, Forgejo, GitLab CE |
| Slack / Teams |
Chat → Mattermost, Element/Matrix |
| Notion / Confluence |
Notes/Wiki → Outline, BookStack, Trilium |
| LastPass / 1Password / Bitwarden |
Passwords → Vaultwarden, Passbolt |
| Trello / Jira / Linear |
Project Management → Plane, Vikunja |
| Google Analytics |
Analytics → Plausible, Umami, Matomo |
| ChatGPT / Claude (locally) |
AI → Ollama + Open WebUI |
| Spotify (music streaming) |
Media → Navidrome |
| Netflix (video streaming) |
Media → Jellyfin |
| YouTube (video hosting) |
Media → PeerTube |
| Evernote / Apple Notes sync |
Notes → Joplin Server, Trilium |
| Pocket / Instapaper |
Read Later → Wallabag |
| Feedly / RSS reader |
RSS → FreshRSS, Miniflux |
| Google Bookmarks |
Bookmarks → Linkding, Hoarder |
| Mint / YNAB (budgeting) |
Finance → Firefly III, Actual Budget |
| Goodreads / e-book library |
Books → Calibre-Web, Kavita |
| DNS / ad blocking |
Network → Pi-hole, AdGuard Home |
| Okta / Auth0 / SSO |
Identity → Authelia, Keycloak |
| ngrok / Cloudflare Tunnel |
Tunnels → cloudflared, Pangolin |
| No open ports / CGNAT problem |
Tunnels → cloudflared (free), Tailscale |
| Auto-update containers |
Developer Tools → Watchtower |
Then decide mode:
| User says |
Mode |
| Names specific app ("Vaultwarden", "Gitea", "Nextcloud") |
Direct → generate immediately |
| Pastes existing compose file |
Optimize → audit and fix |
| Names category ("database", "notes", "monitoring") |
Selection → show 3–4 options |
| Describes vague need ("I want to back up my photos") |
Map to category → Selection |
| Custom app stack ("Next.js + Postgres + Redis") |
Direct → generate immediately |
| "I want to replace Google Drive" |
Map → File Storage Selection |
Step 2 — Selection Mode: Present Options
When in Selection Mode, respond with:
Here are the best self-hosted options for [need]. Which fits your use case?
1. [App Name] — [one sentence what it is]
Best for: [who/what it's best for] · RAM: [rough requirement] · Requires: [dependencies]
2. [App Name] — [one sentence]
Best for: ... · RAM: ... · Requires: ...
3. [App Name] — [one sentence]
Best for: ...
(Optional) 4. [App Name] — ...
Type a number to generate the full Docker Compose stack.
Never ask follow-up questions during selection — user picks a number, then generate immediately.
App Catalogue
📦 Databases & Data Stores
| App |
Description |
RAM |
Best for |
| PostgreSQL |
Industry-standard relational DB |
256MB+ |
Most apps, complex queries |
| MariaDB |
MySQL-compatible, fast, reliable |
256MB+ |
WordPress, legacy apps |
| MongoDB |
Document NoSQL database |
512MB+ |
JSON-heavy, flexible schemas |
| Redis |
In-memory cache, session store, queue |
64MB+ |
Caching, pub/sub, rate limiting |
| ClickHouse |
Columnar DB for analytics, extremely fast |
1GB+ |
Time-series data, large-scale analytics |
| InfluxDB |
Purpose-built time-series database |
256MB+ |
IoT metrics, monitoring |
Extras to suggest alongside: pgAdmin (PostgreSQL UI) · RedisInsight (Redis UI) · Mongo Express (MongoDB UI)
📝 Notes, Wikis & Knowledge Base
| App |
Description |
RAM |
Best for |
| Outline |
Modern team wiki, Slack/Google auth, real-time |
512MB+ |
Teams, documentation |
| BookStack |
Structured wiki: books → chapters → pages |
256MB+ |
Simple personal/team docs |
| Trilium Notes |
Hierarchical personal KB, code, relations |
256MB+ |
Power users, large wikis |
| Joplin Server |
Note sync backend for Joplin clients (E2E encrypted) |
128MB+ |
Existing Joplin users |
| SilverBullet |
Markdown-based PKM, self-hosted Obsidian alternative |
64MB+ |
Markdown note-takers |
| Affine |
Next-gen Notion/Miro hybrid — docs + whiteboard |
512MB+ |
Visual knowledge work |
🔒 Password Managers
| App |
Description |
RAM |
Best for |
| Vaultwarden |
Unofficial Bitwarden server, extremely lightweight |
64MB+ |
Personal/family |
| Passbolt CE |
Team password manager with GPG |
256MB+ |
Teams, organizations |
☁️ File Storage & Cloud
| App |
Description |
RAM |
Best for |
| Nextcloud |
Full Google Drive replacement: files, calendar, contacts, office |
512MB+ |
Full cloud suite |
| Seafile |
Fast file sync and share, reliable |
256MB+ |
Pure file sync |
| Filebrowser |
Minimal web file browser and uploader |
32MB+ |
Simple access, no sync needed |
| Syncthing |
Peer-to-peer continuous file sync (no server-side storage) |
128MB+ |
Device sync without central server |
📸 Photos
| App |
Description |
RAM |
Best for |
| Immich |
Self-hosted Google Photos: auto-backup, face recognition, albums, mobile app |
2GB+ |
Phone photo backup |
| PhotoPrism |
AI-powered photo manager, facial recognition, maps |
1GB+ |
Large collections, AI tags |
| Photoview |
Fast, simple photo viewer for existing directory structure |
256MB+ |
Existing photo directories |
| Piwigo |
Traditional photo gallery with albums and sharing |
256MB+ |
Public photo sharing |
Note for Immich: Requires PostgreSQL + Redis + Machine Learning service in the same stack.
🎬 Media Servers
| App |
Description |
RAM |
Best for |
| Jellyfin |
Fully open-source media server, no subscription |
512MB+ |
Privacy-first streaming |
| Plex |
Feature-rich server with mobile apps, remote access |
1GB+ |
Best client support |
| Navidrome |
Lightweight music server (Subsonic API) |
64MB+ |
Music-only, minimal |
| Audiobookshelf |
Audiobook + podcast server with mobile apps |
256MB+ |
Audiobooks, podcasts |
Media automation ( arr stack):* Suggest Sonarr + Radarr + Prowlarr + qBittorrent together when user asks for automated downloads.
📥 Media Automation (*arr Stack)
| App |
Description |
| Sonarr |
TV show monitoring and download automation |
| Radarr |
Movie monitoring and download automation |
| Lidarr |
Music monitoring and download automation |
| Prowlarr |
Indexer manager for Sonarr/Radarr/Lidarr |
| qBittorrent |
Torrent client with web UI |
| SABnzbd |
Usenet downloader |
*Always generate the full arr stack together when user asks for any of these — they're meant to work as a unit.
🤖 AI / LLM
| App |
Description |
RAM / GPU |
Best for |
| Ollama + Open WebUI |
Run LLMs locally (Llama, Mistral, etc.) with a ChatGPT-like UI |
8GB+ RAM, GPU optional |
Local AI chat, privacy |
| LocalAI |
OpenAI-compatible API for local models |
4GB+ |
API-compatible local AI |
| Stable Diffusion WebUI |
Local image generation (AUTOMATIC1111) |
4GB+ GPU |
AI image generation |
| Open WebUI (standalone) |
Chat UI that connects to external OpenAI/Anthropic APIs |
256MB+ |
Self-hosted chat frontend |
Note for Ollama: If user has NVIDIA GPU, add deploy: resources: reservations: devices for GPU passthrough.
📧 Email
| App |
Description |
RAM |
Best for |
| Mailcow |
Full-featured mail server: SMTP, IMAP, web UI, spam filter |
2GB+ |
Complete email hosting |
| Mailu |
Simpler mail server, easier setup than Mailcow |
1GB+ |
Simple email hosting |
| Stalwart Mail |
Modern all-in-one mail server (JMAP/SMTP/IMAP) |
256MB+ |
Modern standards, low resource |
Warning: Email delivery requires proper DNS (SPF, DKIM, DMARC, PTR) — mention this when generating.
🛡️ Identity, SSO & Access
| App |
Description |
RAM |
Best for |
| Authelia |
Lightweight SSO + 2FA proxy for nginx/Traefik |
64MB+ |
Protecting services with single login |
| Keycloak |
Full enterprise identity provider, OIDC/SAML |
512MB+ |
Full SSO platform, many apps |
| Zitadel |
Modern cloud-native identity platform |
256MB+ |
Developer-friendly, modern stack |
| Authentik |
Flexible IdP with beautiful UI |
512MB+ |
Best balance of features and ease |
🔀 Reverse Proxy
| App |
Description |
RAM |
Best for |
| Traefik v3 |
Auto-discovers Docker services, Let's Encrypt TLS |
64MB+ |
Multi-service, automated HTTPS |
| Nginx Proxy Manager |
Web UI for nginx reverse proxy + Let's Encrypt |
256MB+ |
GUI over config files |
| Caddy |
Automatic HTTPS, simple Caddyfile config |
64MB+ |
Simple setups |
🌐 Network & Ad Blocking
| App |
Description |
RAM |
Best for |
| Pi-hole |
DNS-based ad blocker for entire network |
64MB+ |
Network-wide ad blocking |
| AdGuard Home |
DNS ad blocker with modern UI, DoH/DoT support |
64MB+ |
Same as Pi-hole, more modern UI |
| Unbound |
Validating, recursive DNS resolver |
32MB+ |
Privacy-focused recursive DNS |
| WireGuard (wg-easy) |
WireGuard VPN with simple web UI |
32MB+ |
Easy VPN setup with UI |
| DDNS Updater |
Automatic dynamic DNS updater (DuckDNS, Cloudflare, Namecheap, 80+ providers) |
16MB+ |
Dynamic IP home servers |
🚇 Tunnels & Remote Access
Use when the server is behind CGNAT, ISP blocks ports 80/443, or you don't want to open firewall ports.
| App |
Description |
RAM |
Best for |
Cloudflare Tunnel (cloudflared) |
Zero-trust tunnel — exposes services via Cloudflare without opening any ports; free |
32MB+ |
No open ports, CGNAT, Cloudflare DNS users |
| Tailscale |
Mesh VPN with subnet routing; access homelab from anywhere |
32MB+ |
Private remote access, no public exposure |
| Pangolin + Newt |
Self-hosted tunnel server (open-source Cloudflare Tunnel alternative) |
64MB+ |
Full control, no external dependency |
Cloudflare Tunnel pattern:
services:
cloudflared:
image: cloudflare/cloudflared:latest
restart: unless-stopped
command: tunnel --no-autoupdate run --token ${CLOUDFLARE_TUNNEL_TOKEN}
networks:
- app_network
Token from: Cloudflare Zero Trust → Networks → Tunnels → Create tunnel → Docker
📖 RSS & Read Later
| App |
Description |
RAM |
Best for |
| FreshRSS |
Full-featured RSS/Atom aggregator |
128MB+ |
Power RSS users |
| Miniflux |
Minimalist, fast RSS reader |
32MB+ |
Simple, fast, no-frills |
| Wallabag |
Save articles for later reading (Pocket replacement) |
256MB+ |
Read-later queue |
📚 Books, Comics & Audiobooks
| App |
Description |
RAM |
Best for |
| Calibre-Web |
Web UI for Calibre e-book library, OPDS support |
256MB+ |
E-book library management |
| Kavita |
Fast manga/comic/book server, cross-platform reader |
128MB+ |
Comics, manga, mixed library |
| Komga |
Comic/manga server with OPDS + web reader |
256MB+ |
Comics focus, excellent reader |
| Audiobookshelf |
Audiobook and podcast server with mobile apps |
256MB+ |
Audiobooks + podcasts |
🔗 Bookmarks & Links
| App |
Description |
RAM |
Best for |
| Linkding |
Minimal bookmark manager, browser extensions |
64MB+ |
Simple, fast, self-hosted bookmarks |
| Hoarder |
AI-powered bookmark manager with auto-tagging |
512MB+ |
Smart bookmarks with AI tags |
| Shaarli |
Personal link sharing / bookmark tool |
32MB+ |
Simple, PHP-based, no DB |
💰 Finance & Budget
| App |
Description |
RAM |
Best for |
| Firefly III |
Personal finance manager, budgets, accounts, reports |
256MB+ |
Detailed personal finance |
| Actual Budget |
Modern local-first budget app (YNAB alternative) |
64MB+ |
Simple, fast budgeting |
📊 Analytics & Business Intelligence
| App |
Description |
RAM |
Best for |
| Plausible |
Privacy-friendly, GDPR-compliant web analytics |
512MB+ |
Privacy-first website analytics |
| Umami |
Minimal, fast analytics, multi-site |
256MB+ |
Simple GA replacement |
| Matomo |
Full-featured analytics, full data ownership |
512MB+ |
Full Google Analytics replacement |
| Metabase |
BI tool — query databases visually, dashboards |
1GB+ |
SQL queries without SQL knowledge |
| Grafana |
Metric visualization + dashboards |
256MB+ |
Technical dashboards, time-series |
🐙 Git & Code Hosting
| App |
Description |
RAM |
Best for |
| Gitea |
Lightweight self-hosted Git |
128MB+ |
Personal/small team |
| Forgejo |
Community fork of Gitea |
128MB+ |
Same, more open governance |
| GitLab CE |
Full DevOps platform: Git, CI/CD, registry |
4GB+ |
Teams needing full GitLab |
🚀 CI/CD
| App |
Description |
RAM |
Best for |
| Woodpecker CI |
Gitea/Forgejo-native, lightweight |
256MB+ |
Gitea/Forgejo users |
| Drone CI |
Container-native pipeline-as-code |
256MB+ |
Modern container CI |
| Jenkins |
Battle-tested, massively extensible |
1GB+ |
Complex pipelines, many plugins |
| Tekton |
Kubernetes-native CI/CD pipelines |
512MB+ |
K8s environments |
📦 Container Registry
| App |
Description |
RAM |
Best for |
| Harbor |
Enterprise container registry with security scanning |
2GB+ |
Production, security scanning |
| Zot |
OCI-native, minimal, production-ready registry |
64MB+ |
Lightweight, OCI standards |
| Docker Registry |
Official Docker registry (minimal) |
32MB+ |
Simple internal registry |
✅ Project Management & Productivity
| App |
Description |
RAM |
Best for |
| Plane |
Open-source Linear/Jira alternative |
1GB+ |
Teams, software projects |
| Vikunja |
To-do app with tasks, teams, projects |
128MB+ |
Personal/small team tasks |
| Focalboard |
Kanban/calendar boards (open-source Trello) |
128MB+ |
Simple Kanban |
🗓️ Calendar & Contacts
| App |
Description |
RAM |
Best for |
| Radicale |
Lightweight CalDAV + CardDAV server |
32MB+ |
Simple calendar + contacts sync |
| Nextcloud |
Full calendar, contacts, tasks as part of cloud suite |
512MB+ |
Part of full Nextcloud setup |
💬 Chat & Communication
| App |
Description |
RAM |
Best for |
| Mattermost |
Open-source Slack: channels, DMs, integrations |
512MB+ |
Team chat |
| Matrix + Element |
Federated, E2E encrypted chat (Synapse + Element Web) |
1GB+ |
Secure, federated messaging |
| Rocket.Chat |
Full-featured chat platform, video calls |
1GB+ |
Enterprise, video calls |
🔔 Notifications
| App |
Description |
RAM |
Best for |
| Ntfy |
Simple pub/sub push notification server |
32MB+ |
Server alerts, cron failures |
| Gotify |
Self-hosted push notifications with Android app |
32MB+ |
Android push notifications |
📊 Monitoring & Observability
| App |
Description |
RAM |
Best for |
| Prometheus + Grafana |
Industry-standard metrics + visualization |
512MB+ |
Server/app dashboards |
| Uptime Kuma |
Uptime monitor + status page |
128MB+ |
Service availability |
| Netdata |
Real-time metrics, zero config |
256MB+ |
Live system monitoring |
| Dozzle |
Real-time Docker log viewer |
16MB+ |
Quick container log access |
For full observability stacks → use /linux-monitoring-setup instead.
🏠 Home Automation
| App |
Description |
RAM |
Best for |
| Home Assistant |
Gold standard home automation |
512MB+ |
Full smart home |
| Node-RED |
Visual flow-based IoT programming |
128MB+ |
Custom automations |
🛠️ Developer Tools & Utilities
| App |
Description |
RAM |
Best for |
| Portainer CE |
Docker management web UI |
128MB+ |
Visual Docker management |
| pgAdmin 4 |
PostgreSQL web admin |
256MB+ |
PostgreSQL administration |
| Stirling PDF |
50+ PDF operations in browser |
256MB+ |
PDF processing |
| IT-Tools |
Developer utility tools web UI |
32MB+ |
Quick dev utilities |
| Dashdot |
Beautiful server stats dashboard |
64MB+ |
Server overview page |
| Homepage |
Personal dashboard for all your services |
32MB+ |
Homelab start page |
| SearXNG |
Privacy-respecting meta search engine |
128MB+ |
Self-hosted search |
| Shlink |
URL shortener with analytics |
128MB+ |
Link shortening |
| Infisical |
Open-source secrets manager (Vault alternative) |
512MB+ |
App secrets management |
| Watchtower |
Automatically updates Docker images when new versions are published |
16MB+ |
Auto-update homelab containers |
| Dockge |
Compose stack manager UI (alternative to Portainer) |
32MB+ |
Simple compose file management |
| Changedetection.io |
Website change monitoring with alerts |
64MB+ |
Price tracking, content monitoring |
| Scrutiny |
Hard drive S.M.A.R.T. monitoring with web UI |
64MB+ |
Disk health alerts |
| Speedtest Tracker |
Scheduled internet speed tests with history dashboard |
64MB+ |
ISP speed monitoring |
Watchtower note: By default updates all containers. Use --label-enable flag and add com.centurylinklabs.watchtower.enable: "true" only to containers you want auto-updated.
Step 3 — Generate the Compose Stack
After the user selects (or in Direct Mode), generate the complete, working stack immediately. No more questions.
Quality Standards — Every compose file MUST have:
| Element |
Rule |
No version: field |
Omit it — Compose V2 ignores it; Compose V1 compatibility not needed |
| Named networks |
At least one; never rely on default bridge |
| Named volumes |
All persistent data in named volumes — no bind mounts for DB data |
| Health checks |
On every service others depends_on — use real test commands |
depends_on condition |
condition: service_healthy, not service_started |
| Env variables |
Via ${ENV_VAR} — never hardcode passwords or secrets inline |
| Restart policy |
restart: unless-stopped on every service |
| Image tags |
Specific pinned tags (e.g. postgres:16-alpine) — never latest |
| Log limits |
logging: options: max-size: "10m" max-file: "3" to prevent disk fill |
| Security |
cap_drop: [ALL], read-only config mounts :ro, no privileged: true unless required |
| Internal-only ports |
Services not exposed to host must NOT have ports: — use Docker network |
| Resource limits |
For production, add deploy.resources.limits: {cpus: "1.0", memory: 512M} to prevent runaway containers consuming the whole host |
Companion Service Health Check Templates
When generating Redis as a companion service, always include a health check so dependent services use condition: service_healthy:
redis:
image: redis:7-alpine
restart: unless-stopped
volumes:
- redis_data:/data
networks:
- app_network
healthcheck:
test: ["CMD", "redis-cli", "--raw", "ping"]
# redis:7-alpine includes redis-cli. For minimal custom images use:
# test: ["CMD", "sh", "-c", "redis-cli ping | grep -q PONG"]
interval: 10s
timeout: 5s
retries: 5
App-Specific Requirements
Some apps require specific companion services — always include them:
| App |
Required companions |
| Immich |
PostgreSQL 16 + Redis + immich-machine-learning service |
| Nextcloud |
MariaDB or PostgreSQL + Redis (for caching + locking) |
| Mailcow |
Do not use docker-compose-writer — Mailcow has its own installer; direct user to curl -LO https://github.com/mailcow/mailcow-dockerized/archive/master.tar.gz |
| Outline |
PostgreSQL + Redis |
| Plane |
PostgreSQL + Redis + MinIO (object storage) |
| Authentik |
PostgreSQL + Redis |
| Keycloak |
PostgreSQL |
| Matrix/Synapse |
PostgreSQL |
| GitLab CE |
PostgreSQL + Redis (bundled in official image, or external) |
| Metabase |
PostgreSQL (for app metadata) |
| Firefly III |
MariaDB or PostgreSQL |
| Actual Budget |
None (local SQLite, no companion needed) |
| Hoarder |
Redis + meilisearch for full-text search |
| Ollama + Open WebUI |
No companions needed; add GPU passthrough if user has NVIDIA |
NVIDIA GPU Passthrough (for Ollama, Stable Diffusion)
Ask if user has NVIDIA GPU. If yes, add to the service:
runtime: nvidia # Required — separate from deploy.resources
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
Requirements:
- NVIDIA Container Toolkit must be installed on host (both
runtime: and deploy: require it)
- After install:
sudo systemctl restart docker
- Test GPU access:
docker run --rm --runtime=nvidia nvidia/cuda:12.0-base nvidia-smi
Install guide: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html
Traefik Middleware Labels (add when Traefik is in the stack)
When generating services behind Traefik, offer these middleware patterns for exposed services:
Basic Auth (protect internal tools — pgAdmin, Grafana, etc.):
labels:
traefik.http.middlewares.myapp-auth.basicauth.users: "${BASIC_AUTH_USERS}"
# Generate hash: echo $(htpasswd -nB admin) | sed -e s/\\$/\\$\\$/g
traefik.http.routers.myapp.middlewares: "myapp-auth@docker"
Rate Limiting (protect public-facing APIs):
labels:
traefik.http.middlewares.myapp-ratelimit.ratelimit.average: "100"
traefik.http.middlewares.myapp-ratelimit.ratelimit.burst: "50"
traefik.http.middlewares.myapp-ratelimit.ratelimit.period: "1m"
traefik.http.routers.myapp.middlewares: "myapp-ratelimit@docker"
Force HTTPS Redirect (HTTP → HTTPS on port 80):
labels:
traefik.http.middlewares.redirect-https.redirectscheme.scheme: "https"
traefik.http.middlewares.redirect-https.redirectscheme.permanent: "true"
traefik.http.routers.myapp-http.rule: "Host(`${DOMAIN}`)"
traefik.http.routers.myapp-http.entrypoints: "web"
traefik.http.routers.myapp-http.middlewares: "redirect-https@docker"
IP Allowlist (restrict to specific IPs — e.g. internal only):
labels:
traefik.http.middlewares.myapp-ipallowlist.ipallowlist.sourcerange: "192.168.1.0/24,10.0.0.0/8"
traefik.http.routers.myapp.middlewares: "myapp-ipallowlist@docker"
Middlewares can be chained: middlewares: "redirect-https@docker,myapp-auth@docker"
Step 4 — Write Files Silently
Do NOT print the compose file or .env.example content in chat. Write them to disk silently.
File locations — kebab-case subdirectory in current working directory:
[app-name]/
docker-compose.yml ← complete, production-ready
.env.example ← all required vars with descriptions and safe placeholder values
Generate complete .env.example — every env var must have:
- A comment explaining what it is
- A safe placeholder value (not empty —
CHANGE_ME_strong_password_here, your-domain.com, etc.)
- A note if it's auto-generated (e.g.
# Generate with: openssl rand -hex 32)
Output — print ONLY this after writing:
✅ [App Name] stack created in ./[app-name]/
▶ Setup:
cd [app-name]
cp .env.example .env
nano .env # ← edit ALL passwords and domain settings first!
▶ Start:
docker compose up -d
▶ Check health:
docker compose ps
docker compose logs -f [service-name]
📋 Useful commands:
docker compose pull && docker compose up -d # update to latest images
docker compose down # stop (data preserved)
docker compose down -v # ⚠️ stop + DELETE ALL DATA
💾 Backup volumes (before updating or migrating):
docker run --rm -v [volume_name]:/data -v $(pwd):/backup alpine \
tar czf /backup/[volume_name]-$(date +%Y%m%d).tar.gz -C /data .
# Restore: tar xzf [volume_name]-YYYYMMDD.tar.gz -C /data
🌐 Access: http://localhost:[PORT]
[default login credentials if applicable]
⚠️ [Any important warnings — email DNS, firewall ports, first-run setup steps]
💡 Next steps:
[1-2 relevant next steps, e.g. "Set up Traefik for HTTPS → /docker-compose-writer Traefik"]
[e.g. "Back up volumes → /linux-backup-restore Docker volumes"]
[e.g. "Monitor this stack → /linux-monitoring-setup for Prometheus + Grafana"]
List each UI separately if multiple services expose ports:
🌐 App: http://localhost:8080
🌐 Admin UI: http://localhost:9000 (admin / [password from .env])
Optimize Mode (existing compose pasted)
When user pastes an existing compose file:
Audit silently for all issues:
latest image tags → pin to specific version
- Hardcoded secrets → replace with
${ENV_VAR}
- Missing health checks → add working test commands
- Missing restart policy → add
unless-stopped
- Default bridge network → add named network
- Missing log limits → add
logging block
privileged: true without reason → warn and remove if possible
- Bind mounts for DB data → move to named volumes
Write fixed docker-compose.yml to ./[app-name]/docker-compose.yml
If secrets were hardcoded, also write .env.example
Print only:
✅ Optimized compose written to ./[app-name]/docker-compose.yml
Fixed [N] issues:
- Pinned [X] image tags (removed :latest)
- Moved secrets to .env.example
- Added health checks to [services]
- Added log rotation limits
- [other changes]
🌐 Access: http://localhost:[PORT]
Security Rules (non-negotiable)
- No inline secrets —
${ENV_VAR} only, never password: mysecret
- Read-only config mounts — always
:ro for config files that the app only reads
cap_drop: [ALL] — drop all Linux capabilities; add back only what's explicitly needed
- Never
privileged: true — if the user insists, warn with the security risk and require explicit confirmation
- Non-root user —
user: "1000:1000" for app services where the image supports it
- Internal networks — services that communicate only internally must NOT have
ports: exposed to host
- Log limits — always add
logging block to prevent disk fill from container logs
Homelab / Multi-App Stacks
When user asks for a "full homelab setup", "all my self-hosted apps in one compose", or similar:
- Ask which categories they want: file cloud, media, monitoring, git, CI/CD, etc.
- Generate a single
docker-compose.yml with all requested apps + shared infrastructure (Traefik as reverse proxy, shared PostgreSQL, shared Redis)
- Use Traefik labels for routing instead of port mappings where possible
- Group services with comments (
# ── Media ──, # ── Storage ──, etc.)
1---2name: docker-compose-writer3description: Use when user wants to write, generate, create, or optimize a docker-compose.yml — for a new project, an existing stack, any self-hosted app, or when they want to replace a cloud service (Google Drive, Gmail, GitHub, Slack, Notion, ChatGPT, etc.) with a self-hosted alternative.4---56# Docker Compose Writer78## Overview910Three modes:1112**Selection Mode** — User asks for a category or vague need → present 3–4 real options → user picks → generate complete stack.1314**Direct Mode** — User names a specific app or describes a full custom stack → generate immediately.1516**Optimize Mode** — User pastes existing `docker-compose.yml` → audit and fix issues → write improved version.1718**Language:** Respond in the user's language. YAML keys and comments always in English.1920---2122## Step 1 — Detect Mode and Handle "Replace X" Requests2324First, map "I want to replace X" requests to the right category:2526| User wants to replace / run | Point to |27|----------------------------|----------|28| Google Drive / Dropbox | File Storage → Nextcloud, Seafile |29| Google Photos / iCloud Photos | Photos → Immich |30| Gmail / email hosting | Email → Mailcow, Mailu |31| GitHub / GitLab | Git Hosting → Gitea, Forgejo, GitLab CE |32| Slack / Teams | Chat → Mattermost, Element/Matrix |33| Notion / Confluence | Notes/Wiki → Outline, BookStack, Trilium |34| LastPass / 1Password / Bitwarden | Passwords → Vaultwarden, Passbolt |35| Trello / Jira / Linear | Project Management → Plane, Vikunja |36| Google Analytics | Analytics → Plausible, Umami, Matomo |37| ChatGPT / Claude (locally) | AI → Ollama + Open WebUI |38| Spotify (music streaming) | Media → Navidrome |39| Netflix (video streaming) | Media → Jellyfin |40| YouTube (video hosting) | Media → PeerTube |41| Evernote / Apple Notes sync | Notes → Joplin Server, Trilium |42| Pocket / Instapaper | Read Later → Wallabag |43| Feedly / RSS reader | RSS → FreshRSS, Miniflux |44| Google Bookmarks | Bookmarks → Linkding, Hoarder |45| Mint / YNAB (budgeting) | Finance → Firefly III, Actual Budget |46| Goodreads / e-book library | Books → Calibre-Web, Kavita |47| DNS / ad blocking | Network → Pi-hole, AdGuard Home |48| Okta / Auth0 / SSO | Identity → Authelia, Keycloak |49| ngrok / Cloudflare Tunnel | Tunnels → cloudflared, Pangolin |50| No open ports / CGNAT problem | Tunnels → cloudflared (free), Tailscale |51| Auto-update containers | Developer Tools → Watchtower |5253Then decide mode:5455| User says | Mode |56|-----------|------|57| Names specific app ("Vaultwarden", "Gitea", "Nextcloud") | Direct → generate immediately |58| Pastes existing compose file | Optimize → audit and fix |59| Names category ("database", "notes", "monitoring") | Selection → show 3–4 options |60| Describes vague need ("I want to back up my photos") | Map to category → Selection |61| Custom app stack ("Next.js + Postgres + Redis") | Direct → generate immediately |62| "I want to replace Google Drive" | Map → File Storage Selection |6364---6566## Step 2 — Selection Mode: Present Options6768When in Selection Mode, respond with:6970> Here are the best self-hosted options for **[need]**. Which fits your use case?71>72> **1. [App Name]** — [one sentence what it is]73> Best for: [who/what it's best for] · RAM: [rough requirement] · Requires: [dependencies]74>75> **2. [App Name]** — [one sentence]76> Best for: ... · RAM: ... · Requires: ...77>78> **3. [App Name]** — [one sentence]79> Best for: ...80>81> *(Optional)* **4. [App Name]** — ...82>83> Type a number to generate the full Docker Compose stack.8485Never ask follow-up questions during selection — user picks a number, then generate immediately.8687---8889## App Catalogue9091### 📦 Databases & Data Stores9293| App | Description | RAM | Best for |94|-----|-------------|-----|----------|95| **PostgreSQL** | Industry-standard relational DB | 256MB+ | Most apps, complex queries |96| **MariaDB** | MySQL-compatible, fast, reliable | 256MB+ | WordPress, legacy apps |97| **MongoDB** | Document NoSQL database | 512MB+ | JSON-heavy, flexible schemas |98| **Redis** | In-memory cache, session store, queue | 64MB+ | Caching, pub/sub, rate limiting |99| **ClickHouse** | Columnar DB for analytics, extremely fast | 1GB+ | Time-series data, large-scale analytics |100| **InfluxDB** | Purpose-built time-series database | 256MB+ | IoT metrics, monitoring |101102*Extras to suggest alongside:* pgAdmin (PostgreSQL UI) · RedisInsight (Redis UI) · Mongo Express (MongoDB UI)103104---105106### 📝 Notes, Wikis & Knowledge Base107108| App | Description | RAM | Best for |109|-----|-------------|-----|----------|110| **Outline** | Modern team wiki, Slack/Google auth, real-time | 512MB+ | Teams, documentation |111| **BookStack** | Structured wiki: books → chapters → pages | 256MB+ | Simple personal/team docs |112| **Trilium Notes** | Hierarchical personal KB, code, relations | 256MB+ | Power users, large wikis |113| **Joplin Server** | Note sync backend for Joplin clients (E2E encrypted) | 128MB+ | Existing Joplin users |114| **SilverBullet** | Markdown-based PKM, self-hosted Obsidian alternative | 64MB+ | Markdown note-takers |115| **Affine** | Next-gen Notion/Miro hybrid — docs + whiteboard | 512MB+ | Visual knowledge work |116117---118119### 🔒 Password Managers120121| App | Description | RAM | Best for |122|-----|-------------|-----|----------|123| **Vaultwarden** | Unofficial Bitwarden server, extremely lightweight | 64MB+ | Personal/family |124| **Passbolt CE** | Team password manager with GPG | 256MB+ | Teams, organizations |125126---127128### ☁️ File Storage & Cloud129130| App | Description | RAM | Best for |131|-----|-------------|-----|----------|132| **Nextcloud** | Full Google Drive replacement: files, calendar, contacts, office | 512MB+ | Full cloud suite |133| **Seafile** | Fast file sync and share, reliable | 256MB+ | Pure file sync |134| **Filebrowser** | Minimal web file browser and uploader | 32MB+ | Simple access, no sync needed |135| **Syncthing** | Peer-to-peer continuous file sync (no server-side storage) | 128MB+ | Device sync without central server |136137---138139### 📸 Photos140141| App | Description | RAM | Best for |142|-----|-------------|-----|----------|143| **Immich** | Self-hosted Google Photos: auto-backup, face recognition, albums, mobile app | 2GB+ | Phone photo backup |144| **PhotoPrism** | AI-powered photo manager, facial recognition, maps | 1GB+ | Large collections, AI tags |145| **Photoview** | Fast, simple photo viewer for existing directory structure | 256MB+ | Existing photo directories |146| **Piwigo** | Traditional photo gallery with albums and sharing | 256MB+ | Public photo sharing |147148*Note for Immich:* Requires PostgreSQL + Redis + Machine Learning service in the same stack.149150---151152### 🎬 Media Servers153154| App | Description | RAM | Best for |155|-----|-------------|-----|----------|156| **Jellyfin** | Fully open-source media server, no subscription | 512MB+ | Privacy-first streaming |157| **Plex** | Feature-rich server with mobile apps, remote access | 1GB+ | Best client support |158| **Navidrome** | Lightweight music server (Subsonic API) | 64MB+ | Music-only, minimal |159| **Audiobookshelf** | Audiobook + podcast server with mobile apps | 256MB+ | Audiobooks, podcasts |160161*Media automation (* arr stack):* Suggest Sonarr + Radarr + Prowlarr + qBittorrent together when user asks for automated downloads.162163---164165### 📥 Media Automation (*arr Stack)166167| App | Description |168|-----|-------------|169| **Sonarr** | TV show monitoring and download automation |170| **Radarr** | Movie monitoring and download automation |171| **Lidarr** | Music monitoring and download automation |172| **Prowlarr** | Indexer manager for Sonarr/Radarr/Lidarr |173| **qBittorrent** | Torrent client with web UI |174| **SABnzbd** | Usenet downloader |175176*Always generate the full *arr stack together when user asks for any of these — they're meant to work as a unit.*177178---179180### 🤖 AI / LLM181182| App | Description | RAM / GPU | Best for |183|-----|-------------|-----------|----------|184| **Ollama + Open WebUI** | Run LLMs locally (Llama, Mistral, etc.) with a ChatGPT-like UI | 8GB+ RAM, GPU optional | Local AI chat, privacy |185| **LocalAI** | OpenAI-compatible API for local models | 4GB+ | API-compatible local AI |186| **Stable Diffusion WebUI** | Local image generation (AUTOMATIC1111) | 4GB+ GPU | AI image generation |187| **Open WebUI** (standalone) | Chat UI that connects to external OpenAI/Anthropic APIs | 256MB+ | Self-hosted chat frontend |188189*Note for Ollama:* If user has NVIDIA GPU, add `deploy: resources: reservations: devices` for GPU passthrough.190191---192193### 📧 Email194195| App | Description | RAM | Best for |196|-----|-------------|-----|----------|197| **Mailcow** | Full-featured mail server: SMTP, IMAP, web UI, spam filter | 2GB+ | Complete email hosting |198| **Mailu** | Simpler mail server, easier setup than Mailcow | 1GB+ | Simple email hosting |199| **Stalwart Mail** | Modern all-in-one mail server (JMAP/SMTP/IMAP) | 256MB+ | Modern standards, low resource |200201*Warning: Email delivery requires proper DNS (SPF, DKIM, DMARC, PTR) — mention this when generating.*202203---204205### 🛡️ Identity, SSO & Access206207| App | Description | RAM | Best for |208|-----|-------------|-----|----------|209| **Authelia** | Lightweight SSO + 2FA proxy for nginx/Traefik | 64MB+ | Protecting services with single login |210| **Keycloak** | Full enterprise identity provider, OIDC/SAML | 512MB+ | Full SSO platform, many apps |211| **Zitadel** | Modern cloud-native identity platform | 256MB+ | Developer-friendly, modern stack |212| **Authentik** | Flexible IdP with beautiful UI | 512MB+ | Best balance of features and ease |213214---215216### 🔀 Reverse Proxy217218| App | Description | RAM | Best for |219|-----|-------------|-----|----------|220| **Traefik v3** | Auto-discovers Docker services, Let's Encrypt TLS | 64MB+ | Multi-service, automated HTTPS |221| **Nginx Proxy Manager** | Web UI for nginx reverse proxy + Let's Encrypt | 256MB+ | GUI over config files |222| **Caddy** | Automatic HTTPS, simple Caddyfile config | 64MB+ | Simple setups |223224---225226### 🌐 Network & Ad Blocking227228| App | Description | RAM | Best for |229|-----|-------------|-----|----------|230| **Pi-hole** | DNS-based ad blocker for entire network | 64MB+ | Network-wide ad blocking |231| **AdGuard Home** | DNS ad blocker with modern UI, DoH/DoT support | 64MB+ | Same as Pi-hole, more modern UI |232| **Unbound** | Validating, recursive DNS resolver | 32MB+ | Privacy-focused recursive DNS |233| **WireGuard (wg-easy)** | WireGuard VPN with simple web UI | 32MB+ | Easy VPN setup with UI |234| **DDNS Updater** | Automatic dynamic DNS updater (DuckDNS, Cloudflare, Namecheap, 80+ providers) | 16MB+ | Dynamic IP home servers |235236---237238### 🚇 Tunnels & Remote Access239240Use when the server is behind CGNAT, ISP blocks ports 80/443, or you don't want to open firewall ports.241242| App | Description | RAM | Best for |243|-----|-------------|-----|----------|244| **Cloudflare Tunnel** (`cloudflared`) | Zero-trust tunnel — exposes services via Cloudflare without opening any ports; free | 32MB+ | No open ports, CGNAT, Cloudflare DNS users |245| **Tailscale** | Mesh VPN with subnet routing; access homelab from anywhere | 32MB+ | Private remote access, no public exposure |246| **Pangolin + Newt** | Self-hosted tunnel server (open-source Cloudflare Tunnel alternative) | 64MB+ | Full control, no external dependency |247248**Cloudflare Tunnel pattern:**249```yaml250services:251 cloudflared:252 image: cloudflare/cloudflared:latest253 restart: unless-stopped254 command: tunnel --no-autoupdate run --token ${CLOUDFLARE_TUNNEL_TOKEN}255 networks:256 - app_network257```258Token from: Cloudflare Zero Trust → Networks → Tunnels → Create tunnel → Docker259260---261262### 📖 RSS & Read Later263264| App | Description | RAM | Best for |265|-----|-------------|-----|----------|266| **FreshRSS** | Full-featured RSS/Atom aggregator | 128MB+ | Power RSS users |267| **Miniflux** | Minimalist, fast RSS reader | 32MB+ | Simple, fast, no-frills |268| **Wallabag** | Save articles for later reading (Pocket replacement) | 256MB+ | Read-later queue |269270---271272### 📚 Books, Comics & Audiobooks273274| App | Description | RAM | Best for |275|-----|-------------|-----|----------|276| **Calibre-Web** | Web UI for Calibre e-book library, OPDS support | 256MB+ | E-book library management |277| **Kavita** | Fast manga/comic/book server, cross-platform reader | 128MB+ | Comics, manga, mixed library |278| **Komga** | Comic/manga server with OPDS + web reader | 256MB+ | Comics focus, excellent reader |279| **Audiobookshelf** | Audiobook and podcast server with mobile apps | 256MB+ | Audiobooks + podcasts |280281---282283### 🔗 Bookmarks & Links284285| App | Description | RAM | Best for |286|-----|-------------|-----|----------|287| **Linkding** | Minimal bookmark manager, browser extensions | 64MB+ | Simple, fast, self-hosted bookmarks |288| **Hoarder** | AI-powered bookmark manager with auto-tagging | 512MB+ | Smart bookmarks with AI tags |289| **Shaarli** | Personal link sharing / bookmark tool | 32MB+ | Simple, PHP-based, no DB |290291---292293### 💰 Finance & Budget294295| App | Description | RAM | Best for |296|-----|-------------|-----|----------|297| **Firefly III** | Personal finance manager, budgets, accounts, reports | 256MB+ | Detailed personal finance |298| **Actual Budget** | Modern local-first budget app (YNAB alternative) | 64MB+ | Simple, fast budgeting |299300---301302### 📊 Analytics & Business Intelligence303304| App | Description | RAM | Best for |305|-----|-------------|-----|----------|306| **Plausible** | Privacy-friendly, GDPR-compliant web analytics | 512MB+ | Privacy-first website analytics |307| **Umami** | Minimal, fast analytics, multi-site | 256MB+ | Simple GA replacement |308| **Matomo** | Full-featured analytics, full data ownership | 512MB+ | Full Google Analytics replacement |309| **Metabase** | BI tool — query databases visually, dashboards | 1GB+ | SQL queries without SQL knowledge |310| **Grafana** | Metric visualization + dashboards | 256MB+ | Technical dashboards, time-series |311312---313314### 🐙 Git & Code Hosting315316| App | Description | RAM | Best for |317|-----|-------------|-----|----------|318| **Gitea** | Lightweight self-hosted Git | 128MB+ | Personal/small team |319| **Forgejo** | Community fork of Gitea | 128MB+ | Same, more open governance |320| **GitLab CE** | Full DevOps platform: Git, CI/CD, registry | 4GB+ | Teams needing full GitLab |321322---323324### 🚀 CI/CD325326| App | Description | RAM | Best for |327|-----|-------------|-----|----------|328| **Woodpecker CI** | Gitea/Forgejo-native, lightweight | 256MB+ | Gitea/Forgejo users |329| **Drone CI** | Container-native pipeline-as-code | 256MB+ | Modern container CI |330| **Jenkins** | Battle-tested, massively extensible | 1GB+ | Complex pipelines, many plugins |331| **Tekton** | Kubernetes-native CI/CD pipelines | 512MB+ | K8s environments |332333---334335### 📦 Container Registry336337| App | Description | RAM | Best for |338|-----|-------------|-----|----------|339| **Harbor** | Enterprise container registry with security scanning | 2GB+ | Production, security scanning |340| **Zot** | OCI-native, minimal, production-ready registry | 64MB+ | Lightweight, OCI standards |341| **Docker Registry** | Official Docker registry (minimal) | 32MB+ | Simple internal registry |342343---344345### ✅ Project Management & Productivity346347| App | Description | RAM | Best for |348|-----|-------------|-----|----------|349| **Plane** | Open-source Linear/Jira alternative | 1GB+ | Teams, software projects |350| **Vikunja** | To-do app with tasks, teams, projects | 128MB+ | Personal/small team tasks |351| **Focalboard** | Kanban/calendar boards (open-source Trello) | 128MB+ | Simple Kanban |352353---354355### 🗓️ Calendar & Contacts356357| App | Description | RAM | Best for |358|-----|-------------|-----|----------|359| **Radicale** | Lightweight CalDAV + CardDAV server | 32MB+ | Simple calendar + contacts sync |360| **Nextcloud** | Full calendar, contacts, tasks as part of cloud suite | 512MB+ | Part of full Nextcloud setup |361362---363364### 💬 Chat & Communication365366| App | Description | RAM | Best for |367|-----|-------------|-----|----------|368| **Mattermost** | Open-source Slack: channels, DMs, integrations | 512MB+ | Team chat |369| **Matrix + Element** | Federated, E2E encrypted chat (Synapse + Element Web) | 1GB+ | Secure, federated messaging |370| **Rocket.Chat** | Full-featured chat platform, video calls | 1GB+ | Enterprise, video calls |371372---373374### 🔔 Notifications375376| App | Description | RAM | Best for |377|-----|-------------|-----|----------|378| **Ntfy** | Simple pub/sub push notification server | 32MB+ | Server alerts, cron failures |379| **Gotify** | Self-hosted push notifications with Android app | 32MB+ | Android push notifications |380381---382383### 📊 Monitoring & Observability384385| App | Description | RAM | Best for |386|-----|-------------|-----|----------|387| **Prometheus + Grafana** | Industry-standard metrics + visualization | 512MB+ | Server/app dashboards |388| **Uptime Kuma** | Uptime monitor + status page | 128MB+ | Service availability |389| **Netdata** | Real-time metrics, zero config | 256MB+ | Live system monitoring |390| **Dozzle** | Real-time Docker log viewer | 16MB+ | Quick container log access |391392*For full observability stacks → use `/linux-monitoring-setup` instead.*393394---395396### 🏠 Home Automation397398| App | Description | RAM | Best for |399|-----|-------------|-----|----------|400| **Home Assistant** | Gold standard home automation | 512MB+ | Full smart home |401| **Node-RED** | Visual flow-based IoT programming | 128MB+ | Custom automations |402403---404405### 🛠️ Developer Tools & Utilities406407| App | Description | RAM | Best for |408|-----|-------------|-----|----------|409| **Portainer CE** | Docker management web UI | 128MB+ | Visual Docker management |410| **pgAdmin 4** | PostgreSQL web admin | 256MB+ | PostgreSQL administration |411| **Stirling PDF** | 50+ PDF operations in browser | 256MB+ | PDF processing |412| **IT-Tools** | Developer utility tools web UI | 32MB+ | Quick dev utilities |413| **Dashdot** | Beautiful server stats dashboard | 64MB+ | Server overview page |414| **Homepage** | Personal dashboard for all your services | 32MB+ | Homelab start page |415| **SearXNG** | Privacy-respecting meta search engine | 128MB+ | Self-hosted search |416| **Shlink** | URL shortener with analytics | 128MB+ | Link shortening |417| **Infisical** | Open-source secrets manager (Vault alternative) | 512MB+ | App secrets management |418| **Watchtower** | Automatically updates Docker images when new versions are published | 16MB+ | Auto-update homelab containers |419| **Dockge** | Compose stack manager UI (alternative to Portainer) | 32MB+ | Simple compose file management |420| **Changedetection.io** | Website change monitoring with alerts | 64MB+ | Price tracking, content monitoring |421| **Scrutiny** | Hard drive S.M.A.R.T. monitoring with web UI | 64MB+ | Disk health alerts |422| **Speedtest Tracker** | Scheduled internet speed tests with history dashboard | 64MB+ | ISP speed monitoring |423424*Watchtower note: By default updates all containers. Use `--label-enable` flag and add `com.centurylinklabs.watchtower.enable: "true"` only to containers you want auto-updated.*425426---427428## Step 3 — Generate the Compose Stack429430After the user selects (or in Direct Mode), generate the **complete, working** stack immediately. No more questions.431432### Quality Standards — Every compose file MUST have:433434| Element | Rule |435|---------|------|436| No `version:` field | Omit it — Compose V2 ignores it; Compose V1 compatibility not needed |437| Named networks | At least one; never rely on default bridge |438| Named volumes | All persistent data in named volumes — no bind mounts for DB data |439| Health checks | On every service others `depends_on` — use real test commands |440| `depends_on` condition | `condition: service_healthy`, not `service_started` |441| Env variables | Via `${ENV_VAR}` — never hardcode passwords or secrets inline |442| Restart policy | `restart: unless-stopped` on every service |443| Image tags | Specific pinned tags (e.g. `postgres:16-alpine`) — **never** `latest` |444| Log limits | `logging: options: max-size: "10m" max-file: "3"` to prevent disk fill |445| Security | `cap_drop: [ALL]`, read-only config mounts `:ro`, no `privileged: true` unless required |446| Internal-only ports | Services not exposed to host must NOT have `ports:` — use Docker network |447| Resource limits | For production, add `deploy.resources.limits: {cpus: "1.0", memory: 512M}` to prevent runaway containers consuming the whole host |448449### Companion Service Health Check Templates450451When generating Redis as a companion service, always include a health check so dependent services use `condition: service_healthy`:452453```yaml454 redis:455 image: redis:7-alpine456 restart: unless-stopped457 volumes:458 - redis_data:/data459 networks:460 - app_network461 healthcheck:462 test: ["CMD", "redis-cli", "--raw", "ping"]463 # redis:7-alpine includes redis-cli. For minimal custom images use:464 # test: ["CMD", "sh", "-c", "redis-cli ping | grep -q PONG"]465 interval: 10s466 timeout: 5s467 retries: 5468```469470---471472### App-Specific Requirements473474Some apps require specific companion services — always include them:475476| App | Required companions |477|-----|-------------------|478| **Immich** | PostgreSQL 16 + Redis + `immich-machine-learning` service |479| **Nextcloud** | MariaDB or PostgreSQL + Redis (for caching + locking) |480| **Mailcow** | Do not use docker-compose-writer — Mailcow has its own installer; direct user to `curl -LO https://github.com/mailcow/mailcow-dockerized/archive/master.tar.gz` |481| **Outline** | PostgreSQL + Redis |482| **Plane** | PostgreSQL + Redis + MinIO (object storage) |483| **Authentik** | PostgreSQL + Redis |484| **Keycloak** | PostgreSQL |485| **Matrix/Synapse** | PostgreSQL |486| **GitLab CE** | PostgreSQL + Redis (bundled in official image, or external) |487| **Metabase** | PostgreSQL (for app metadata) |488| **Firefly III** | MariaDB or PostgreSQL |489| **Actual Budget** | None (local SQLite, no companion needed) |490| **Hoarder** | Redis + `meilisearch` for full-text search |491| **Ollama + Open WebUI** | No companions needed; add GPU passthrough if user has NVIDIA |492493### NVIDIA GPU Passthrough (for Ollama, Stable Diffusion)494495Ask if user has NVIDIA GPU. If yes, add to the service:496```yaml497runtime: nvidia # Required — separate from deploy.resources498deploy:499 resources:500 reservations:501 devices:502 - driver: nvidia503 count: all504 capabilities: [gpu]505```506507Requirements:508- NVIDIA Container Toolkit must be installed on host (both `runtime:` and `deploy:` require it)509- After install: `sudo systemctl restart docker`510- Test GPU access: `docker run --rm --runtime=nvidia nvidia/cuda:12.0-base nvidia-smi`511512Install guide: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html513514---515516### Traefik Middleware Labels (add when Traefik is in the stack)517518When generating services behind Traefik, offer these middleware patterns for exposed services:519520**Basic Auth** (protect internal tools — pgAdmin, Grafana, etc.):521```yaml522labels:523 traefik.http.middlewares.myapp-auth.basicauth.users: "${BASIC_AUTH_USERS}"524 # Generate hash: echo $(htpasswd -nB admin) | sed -e s/\\$/\\$\\$/g525 traefik.http.routers.myapp.middlewares: "myapp-auth@docker"526```527528**Rate Limiting** (protect public-facing APIs):529```yaml530labels:531 traefik.http.middlewares.myapp-ratelimit.ratelimit.average: "100"532 traefik.http.middlewares.myapp-ratelimit.ratelimit.burst: "50"533 traefik.http.middlewares.myapp-ratelimit.ratelimit.period: "1m"534 traefik.http.routers.myapp.middlewares: "myapp-ratelimit@docker"535```536537**Force HTTPS Redirect** (HTTP → HTTPS on port 80):538```yaml539labels:540 traefik.http.middlewares.redirect-https.redirectscheme.scheme: "https"541 traefik.http.middlewares.redirect-https.redirectscheme.permanent: "true"542 traefik.http.routers.myapp-http.rule: "Host(`${DOMAIN}`)"543 traefik.http.routers.myapp-http.entrypoints: "web"544 traefik.http.routers.myapp-http.middlewares: "redirect-https@docker"545```546547**IP Allowlist** (restrict to specific IPs — e.g. internal only):548```yaml549labels:550 traefik.http.middlewares.myapp-ipallowlist.ipallowlist.sourcerange: "192.168.1.0/24,10.0.0.0/8"551 traefik.http.routers.myapp.middlewares: "myapp-ipallowlist@docker"552```553554Middlewares can be chained: `middlewares: "redirect-https@docker,myapp-auth@docker"`555556---557558## Step 4 — Write Files Silently559560Do NOT print the compose file or .env.example content in chat. Write them to disk silently.561562**File locations** — kebab-case subdirectory in current working directory:563```564[app-name]/565 docker-compose.yml ← complete, production-ready566 .env.example ← all required vars with descriptions and safe placeholder values567```568569**Generate complete .env.example** — every env var must have:570- A comment explaining what it is571- A safe placeholder value (not empty — `CHANGE_ME_strong_password_here`, `your-domain.com`, etc.)572- A note if it's auto-generated (e.g. `# Generate with: openssl rand -hex 32`)573574### Output — print ONLY this after writing:575576```577✅ [App Name] stack created in ./[app-name]/578579▶ Setup:580 cd [app-name]581 cp .env.example .env582 nano .env # ← edit ALL passwords and domain settings first!583584▶ Start:585 docker compose up -d586587▶ Check health:588 docker compose ps589 docker compose logs -f [service-name]590591📋 Useful commands:592 docker compose pull && docker compose up -d # update to latest images593 docker compose down # stop (data preserved)594 docker compose down -v # ⚠️ stop + DELETE ALL DATA595596💾 Backup volumes (before updating or migrating):597 docker run --rm -v [volume_name]:/data -v $(pwd):/backup alpine \598 tar czf /backup/[volume_name]-$(date +%Y%m%d).tar.gz -C /data .599 # Restore: tar xzf [volume_name]-YYYYMMDD.tar.gz -C /data600601🌐 Access: http://localhost:[PORT]602[default login credentials if applicable]603604⚠️ [Any important warnings — email DNS, firewall ports, first-run setup steps]605606💡 Next steps:607 [1-2 relevant next steps, e.g. "Set up Traefik for HTTPS → /docker-compose-writer Traefik"]608 [e.g. "Back up volumes → /linux-backup-restore Docker volumes"]609 [e.g. "Monitor this stack → /linux-monitoring-setup for Prometheus + Grafana"]610```611612List each UI separately if multiple services expose ports:613```614🌐 App: http://localhost:8080615🌐 Admin UI: http://localhost:9000 (admin / [password from .env])616```617618---619620## Optimize Mode (existing compose pasted)621622When user pastes an existing compose file:6236241. Audit silently for all issues:625 - `latest` image tags → pin to specific version626 - Hardcoded secrets → replace with `${ENV_VAR}`627 - Missing health checks → add working test commands628 - Missing restart policy → add `unless-stopped`629 - Default bridge network → add named network630 - Missing log limits → add `logging` block631 - `privileged: true` without reason → warn and remove if possible632 - Bind mounts for DB data → move to named volumes6336342. Write fixed `docker-compose.yml` to `./[app-name]/docker-compose.yml`6353. If secrets were hardcoded, also write `.env.example`6366374. Print only:638```639✅ Optimized compose written to ./[app-name]/docker-compose.yml640 Fixed [N] issues:641 - Pinned [X] image tags (removed :latest)642 - Moved secrets to .env.example643 - Added health checks to [services]644 - Added log rotation limits645 - [other changes]646647🌐 Access: http://localhost:[PORT]648```649650---651652## Security Rules (non-negotiable)653654- **No inline secrets** — `${ENV_VAR}` only, never `password: mysecret`655- **Read-only config mounts** — always `:ro` for config files that the app only reads656- **`cap_drop: [ALL]`** — drop all Linux capabilities; add back only what's explicitly needed657- **Never `privileged: true`** — if the user insists, warn with the security risk and require explicit confirmation658- **Non-root user** — `user: "1000:1000"` for app services where the image supports it659- **Internal networks** — services that communicate only internally must NOT have `ports:` exposed to host660- **Log limits** — always add `logging` block to prevent disk fill from container logs661662---663664## Homelab / Multi-App Stacks665666When user asks for a "full homelab setup", "all my self-hosted apps in one compose", or similar:6676681. Ask which categories they want: file cloud, media, monitoring, git, CI/CD, etc.6692. Generate a single `docker-compose.yml` with all requested apps + shared infrastructure (Traefik as reverse proxy, shared PostgreSQL, shared Redis)6703. Use Traefik labels for routing instead of port mappings where possible6714. Group services with comments (`# ── Media ──`, `# ── Storage ──`, etc.)