Files
homelabstack/portainer-compose.yml
T
ginnoir 51acb44322
Deploy to valhalla / deploy (push) Has been cancelled
Ship homelab quick wins: Recyclarr, infra pins, jd.ginnoir.com, and LAN lockdown.
Add Recyclarr to the media stack, pin database/object-store/Caddy/Vault images with Watchtower disabled, expose JDownloader at jd.ginnoir.com, and restrict minio/homarr/docs to internal_only. Mark TB-002–004 and TB-033 complete; bundle batch-3 OIDC env for FreshRSS, ownCloud, and Reactive Resume.
2026-06-11 02:28:06 -05:00

112 lines
4.0 KiB
YAML

# Management plane: portainer, vault, github-runner, watchtower.
# These manage / underpin the application stacks rather than being part of them,
# so they are deployed by raw `docker compose` (NOT a Portainer-managed stack) —
# Portainer cannot manage the stack that contains Portainer itself.
#
# This file owns the shared infrastructure networks:
# - edge : the single reverse-proxy network. Caddy + every service it
# proxies join this. Replaces caddy's old per-stack network
# membership. App stacks reference it as external.
# - portainer_proxy : legacy net for caddy -> portainer. Kept until the monolith
# is fully dismantled, then dropped (portainer is on edge too).
#
# Vault lives here (moved out of the dev stack): it is estate-wide secrets infra,
# must boot before the app stacks, and should not reseal when a dev tool changes.
# Vault data is the /config/vault bind mount — moving the service definition here
# does not touch any data. Re-unseal after (apply-compose.ps1 -VaultUnseal).
#
# Fresh-install order:
# docker compose -f portainer-compose.yml up -d # networks + mgmt plane first
# (then create the Portainer git stacks for proxy + each app domain)
services:
portainer:
container_name: portainer
image: portainer/portainer-ce:latest
restart: unless-stopped
networks:
- portainer_proxy
- edge
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /config/portainer:/data
ports:
- "9100:9000"
labels:
- "com.centurylabs.watchtower.enable=false"
# ============================================================
# VAULT (estate-wide secret management)
# One-time setup after first start:
# docker exec -it vault vault operator init
# vault operator unseal (3x with unseal keys)
# Unseal keys + root token live in .env (they are the one secret Vault
# itself cannot hold). Re-unseal after a restart with:
# powershell -File apply-compose.ps1 -VaultUnseal
# ============================================================
vault:
container_name: vault
image: hashicorp/vault@sha256:3fd53308acccd9e4e83fde3e6c6cf5b15e0f7fac1ff7510780b8b23f5e4c3de7
restart: unless-stopped
networks:
- edge
cap_add:
- IPC_LOCK
# Newer vault:latest mlocks more than docker's default 64KB memlock ulimit;
# without this it crash-loops with "Failed to lock memory: cannot allocate
# memory" despite IPC_LOCK being granted.
ulimits:
memlock:
soft: -1
hard: -1
environment:
- VAULT_ADDR=http://0.0.0.0:8200
volumes:
- /config/vault/config:/vault/config:ro
- /config/vault/data:/vault/data
- /config/vault/logs:/vault/logs
command: vault server -config=/vault/config/vault.hcl
ports:
- "8200:8200"
labels:
- "com.centurylabs.watchtower.enable=false"
github-runner:
container_name: github_runner
image: myoung34/github-runner:latest
restart: unless-stopped
environment:
- ACCESS_TOKEN=${GITHUB_RUNNER_ACCESS_TOKEN}
- REPO_URL=https://github.com/ginnoir/homelabstack
- RUNNER_NAME=valhalla
- RUNNER_LABELS=self-hosted,Linux,x64
- RUNNER_SCOPE=repo
- DOCKER_GROUP_GID=1001
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /home/ginnoir/valhalla-lab:/valhalla-lab
- /config/caddy:/config/caddy
labels:
- "com.centurylabs.watchtower.enable=false"
watchtower:
container_name: watchtower
image: containrrr/watchtower:latest
restart: unless-stopped
environment:
- DOCKER_API_VERSION=1.40
- WATCHTOWER_NOTIFICATION_SKIP_TITLE=true
- WATCHTOWER_NOTIFICATION_URL=ntfy://ntfy.ginnoir.com/watchtower?title=WatchtowerUpdates
volumes:
- /var/run/docker.sock:/var/run/docker.sock
labels:
- "com.centurylabs.watchtower.enable=false"
networks:
edge:
name: edge
driver: bridge
portainer_proxy:
name: portainer_proxy
driver: bridge