valknar 067d017ea6 feat(stacks): add --static flag to completion command
Bakes the current stack list into the generated completion script instead
of using runtime directory discovery. Useful for remote hosts where the
stacks dir path differs from the local repo.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 19:52:55 +02:00
2026-06-10 13:43:21 +02:00
2026-06-12 18:18:17 +02:00

Stacks

Self-contained Docker Compose stacks for pivoine.art infrastructure.

Each stack is independently deployable with its own compose.yml and .env. All persistent data lives in ../.data/<stack>/.

Stacks

Stack Description Services
traefik Reverse proxy, TLS termination traefik
mailpit SMTP relay (no web UI) mailpit
umami Web analytics umami, db
immich Photo & video management immich, ml, redis, db
n8n Workflow automation & notification relay n8n, db
gitea Git hosting + CI runner gitea, runner, db
coolify Deployment platform coolify, realtime, redis, db
passbolt Password manager (GPG-encrypted, team sharing) passbolt, db
code Browser-based VS Code IDE with Anthropic API access code

Tools

Directory Description
_backup Daily restic backups to HiDrive (host script + systemd timer)
_update Nightly image update check + prune (host script + systemd timer)

Deployment

# Copy example env and fill in secrets
cp <stack>/.env.example <stack>/.env

# Sync a stack to VPS
rsync -avz <stack>/ vps:~/stacks/<stack>/

# Start a stack
ssh vps 'cd ~/stacks/<stack> && docker compose up -d'

Network

All stacks share the external falcon_network Docker network for inter-service communication (e.g. traefik routing, mailpit SMTP).

Backup

The _backup stack runs a daily restic backup at 3:00 AM. It dumps all Postgres databases, then backs up the entire .data/ directory to HiDrive. Retention: 7 daily, 4 weekly, 6 monthly snapshots. Notifications go to Telegram via n8n.

# Deploy backup stack
rsync -avz _backup/ vps:~/stacks/_backup/

# Initialize restic repo (first time only)
ssh vps 'source ~/stacks/_backup/.env && restic init -r /mnt/hidrive/users/valknar/Backup/stacks'

# Install systemd units
ssh vps 'ln -sf ~/stacks/_backup/stacks-backup.service /etc/systemd/system/ && \
         ln -sf ~/stacks/_backup/stacks-backup.timer /etc/systemd/system/ && \
         systemctl daemon-reload && systemctl enable --now stacks-backup.timer'

# Manual test run
ssh vps '~/stacks/_backup/backup.sh'

# Check timer status
ssh vps 'systemctl status stacks-backup.timer'

# View snapshots
ssh vps 'source ~/stacks/_backup/.env && restic -r /mnt/hidrive/users/valknar/Backup/stacks snapshots'

Updates

The _update script runs nightly at 2:00 AM. It pulls the latest image for every stack, recreates any containers whose image changed, prunes dangling images, and sends a Telegram notification via n8n.

# Deploy update stack
rsync -avz _update/ vps:~/stacks/_update/
ssh vps 'chmod +x ~/stacks/_update/update.sh'

# Install systemd units
ssh vps 'ln -sf ~/stacks/_update/stacks-update.service /etc/systemd/system/ && \
         ln -sf ~/stacks/_update/stacks-update.timer /etc/systemd/system/ && \
         systemctl daemon-reload && systemctl enable --now stacks-update.timer'

# Manual test run
ssh vps '~/stacks/_update/update.sh'

# Check timer status
ssh vps 'systemctl status stacks-update.timer'

Notifications

The update script and the backup script both POST to an n8n webhook, which forwards messages to Telegram.

The webhook URL is set in:

  • _backup/.envWEBHOOK_URL
  • _update/.envWEBHOOK_URL

Both point to the same n8n workflow at https://n8n.pivoine.art. The workflow accepts { "message": "..." } and forwards it to Telegram.

Data

Persistent data is stored in ~/stacks/.data/<stack>/ on the VPS using bind mounts. Database stacks use dedicated Postgres instances with simple credentials.

S
Description
Self-contained Docker Compose stacks for pivoine.art infrastructure.
Readme 373 KiB
Languages
Shell 99.6%
Go Template 0.4%