Add all swarm service definitions, CLAUDE.md, and gen-env.sh
Track all active Proxmox swarm stack YMLs, NATS config, Postgres init SQL, and env generation script. Update .gitignore for homelab project. Add CLAUDE.md for project context. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ca16c1d815
commit
f3017b9ab5
15 changed files with 561 additions and 34 deletions
42
.gitignore
vendored
42
.gitignore
vendored
|
|
@ -1,22 +1,8 @@
|
|||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
build/
|
||||
dist/
|
||||
wheels/
|
||||
*.egg-info/
|
||||
*.egg
|
||||
|
||||
# Virtual environments
|
||||
.venv/
|
||||
venv/
|
||||
ENV/
|
||||
# Secrets
|
||||
.env
|
||||
.env.*
|
||||
*.pem
|
||||
*.key
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
|
|
@ -25,21 +11,9 @@ ENV/
|
|||
*.swo
|
||||
*~
|
||||
|
||||
# Jupyter
|
||||
.ipynb_checkpoints/
|
||||
|
||||
# Testing
|
||||
.pytest_cache/
|
||||
.coverage
|
||||
htmlcov/
|
||||
|
||||
# Type checking
|
||||
.mypy_cache/
|
||||
|
||||
# Environment variables
|
||||
.env
|
||||
.env.*
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Claude Code
|
||||
.claude/
|
||||
|
|
|
|||
57
CLAUDE.md
Normal file
57
CLAUDE.md
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Overview
|
||||
|
||||
Proxmox VE homelab cluster running Docker Swarm services. Three Proxmox hosts (pve, adder, game) connected via VXLAN overlay on vmbr1 (10.10.10.0/24). VMs run Docker CE and form a swarm with pve-postgres as manager.
|
||||
|
||||
## Deployment
|
||||
|
||||
All services deploy as Docker Swarm stacks from the manager node (pve-postgres). The active service definitions are in `proxmox/services/`. The `services/` directory contains older pre-migration copies.
|
||||
|
||||
```bash
|
||||
# Generate env var prefix from pass (run locally)
|
||||
./proxmox/services/gen-env.sh <service.yml>
|
||||
|
||||
# Copy yml to manager and deploy
|
||||
scp proxmox/services/<service>.yml pve-postgres:~/
|
||||
ssh pve-postgres "<ENV_VARS> docker stack deploy -c <service>.yml <stack_name>"
|
||||
|
||||
# Remove a stack
|
||||
ssh pve-postgres "docker stack rm <stack_name>"
|
||||
```
|
||||
|
||||
Secrets come from `pass` under the `homelab/` prefix. Use `gen-env.sh` to extract required `${VAR}` references from a yml and resolve them. Never hardcode secrets in files.
|
||||
|
||||
## Service YML Conventions
|
||||
|
||||
- All use `version: '3.8'` and Docker Swarm deploy mode
|
||||
- Each service is pinned to a specific node via `node.hostname` constraint
|
||||
- All connect to the external overlay network `homelab-net` via `${OVERLAY_NETWORK:-homelab-net}`
|
||||
- Named volumes for persistence, `on-failure` restart policy with 3 max attempts
|
||||
- Every service that has a web UI or accepts external connections must publish its ports
|
||||
- Only include environment variables required to start the service — no optional/nice-to-have vars
|
||||
|
||||
## Cluster Topology
|
||||
|
||||
| Node | Host IP | Swarm IP | Role |
|
||||
|------|---------|----------|------|
|
||||
| pve | 192.168.40.198 | 10.10.10.1 | Proxmox host |
|
||||
| adder | 192.168.40.150 | 10.10.10.86 | Proxmox host |
|
||||
| game | 192.168.40.109 | 10.10.10.172 | Proxmox host |
|
||||
| pve-postgres | — | 10.10.10.2 | VM on pve, swarm manager |
|
||||
| pve-tools | — | 10.10.10.3 | VM on pve, swarm worker |
|
||||
| adder-ghost | — | 10.10.10.20 | VM on adder, swarm worker |
|
||||
|
||||
## SSH Access
|
||||
|
||||
Use SSH config aliases (`pve-postgres`, `pve-tools`, `adder-ghost`, `pve`, `adder`, `game`). ProxyJump is configured in `~/.ssh/config`. Never manually hop through intermediate nodes.
|
||||
|
||||
## Key Files
|
||||
|
||||
- `proxmox/services/*.yml` — Active swarm stack definitions
|
||||
- `proxmox/services/gen-env.sh` — Extracts env vars from yml, resolves from `pass homelab/`
|
||||
- `proxmox/services/nats.conf` — NATS server config (JetStream, websocket, monitoring)
|
||||
- `proxmox/services/01-init.sql` — Postgres init script (creates users/databases)
|
||||
- `proxmox/post_init_node.org` — Fresh Proxmox node setup steps
|
||||
18
proxmox/services/01-init.sql
Normal file
18
proxmox/services/01-init.sql
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
-- Postgres init script
|
||||
-- Runs once on first boot when data volume is empty.
|
||||
-- Creates a database and scoped user for each service.
|
||||
|
||||
-- FusionAuth
|
||||
CREATE USER fusionauth_user WITH PASSWORD 'lXG9oNwbj0DEVaCjwjI9Fomhjs7mSgRd';
|
||||
CREATE DATABASE fusionauth_db OWNER fusionauth_user;
|
||||
GRANT ALL PRIVILEGES ON DATABASE fusionauth_db TO fusionauth_user;
|
||||
|
||||
-- n8n
|
||||
CREATE USER n8n_user WITH PASSWORD 'peiKxDe3X7QWZhhrP1M8jKlnV2nLgqSp';
|
||||
CREATE DATABASE n8n_db OWNER n8n_user;
|
||||
GRANT ALL PRIVILEGES ON DATABASE n8n_db TO n8n_user;
|
||||
|
||||
-- c4trou
|
||||
CREATE USER c4trou_user WITH PASSWORD 'mlhWiZcp5I2kXwRmyFEMPjZz6BX6ZjLi';
|
||||
CREATE DATABASE c4trou_db OWNER c4trou_user;
|
||||
GRANT ALL PRIVILEGES ON DATABASE c4trou_db TO c4trou_user;
|
||||
74
proxmox/services/authentik.yml
Normal file
74
proxmox/services/authentik.yml
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
version: '3.8'
|
||||
|
||||
# Deploy with:
|
||||
# docker stack deploy -c authentik.yml authentik
|
||||
#
|
||||
# Runs on: docker-swarm-1
|
||||
# Authentik server + worker, using the shared postgres stack.
|
||||
# No Redis required as of 2026.2.x.
|
||||
# Initial setup wizard at http://<host>:9000/if/flow/initial-setup/
|
||||
|
||||
services:
|
||||
server:
|
||||
image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG:-2026.2.1}
|
||||
command: server
|
||||
environment:
|
||||
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
|
||||
AUTHENTIK_POSTGRESQL__HOST: postgres_postgres
|
||||
AUTHENTIK_POSTGRESQL__PORT: 5432
|
||||
AUTHENTIK_POSTGRESQL__NAME: authentik_db
|
||||
AUTHENTIK_POSTGRESQL__USER: authentik_user
|
||||
AUTHENTIK_POSTGRESQL__PASSWORD: ${AUTHENTIK_DB_PASSWORD}
|
||||
ports:
|
||||
- "9000:9000"
|
||||
- "9443:9443"
|
||||
volumes:
|
||||
- authentik_media:/media
|
||||
- authentik_templates:/templates
|
||||
networks:
|
||||
- overlay-net
|
||||
deploy:
|
||||
replicas: 1
|
||||
placement:
|
||||
constraints:
|
||||
- node.hostname == pve-tools
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
delay: 5s
|
||||
max_attempts: 3
|
||||
|
||||
worker:
|
||||
image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG:-2026.2.1}
|
||||
command: worker
|
||||
environment:
|
||||
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
|
||||
AUTHENTIK_POSTGRESQL__HOST: postgres_postgres
|
||||
AUTHENTIK_POSTGRESQL__PORT: 5432
|
||||
AUTHENTIK_POSTGRESQL__NAME: authentik_db
|
||||
AUTHENTIK_POSTGRESQL__USER: authentik_user
|
||||
AUTHENTIK_POSTGRESQL__PASSWORD: ${AUTHENTIK_DB_PASSWORD}
|
||||
volumes:
|
||||
- authentik_media:/media
|
||||
- authentik_templates:/templates
|
||||
- authentik_certs:/certs
|
||||
networks:
|
||||
- overlay-net
|
||||
deploy:
|
||||
replicas: 1
|
||||
placement:
|
||||
constraints:
|
||||
- node.hostname == pve-tools
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
delay: 5s
|
||||
max_attempts: 3
|
||||
|
||||
volumes:
|
||||
authentik_media:
|
||||
authentik_templates:
|
||||
authentik_certs:
|
||||
|
||||
networks:
|
||||
overlay-net:
|
||||
external: true
|
||||
name: ${OVERLAY_NETWORK:-homelab-net}
|
||||
40
proxmox/services/caddy.yml
Normal file
40
proxmox/services/caddy.yml
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
version: '3.8'
|
||||
|
||||
# Deploy with:
|
||||
# docker stack deploy -c caddy.yml caddy
|
||||
#
|
||||
# Runs on: CADDY_INSTANCE (ip-10-0-1-168)
|
||||
# Caddy handles TLS automatically via Let's Encrypt.
|
||||
# Reverse proxies all public subdomains to the correct services on erda-net.
|
||||
# Caddyfile is bind mounted from the host — edit /etc/caddy/Caddyfile on the caddy instance.
|
||||
|
||||
services:
|
||||
caddy:
|
||||
image: caddy:latest
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- /etc/caddy/Caddyfile:/etc/caddy/Caddyfile
|
||||
- caddy_data:/data
|
||||
- caddy_config:/config
|
||||
networks:
|
||||
- overlay-net
|
||||
deploy:
|
||||
replicas: 1
|
||||
placement:
|
||||
constraints:
|
||||
- node.hostname == ip-10-0-1-168
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
delay: 5s
|
||||
max_attempts: 3
|
||||
|
||||
volumes:
|
||||
caddy_data:
|
||||
caddy_config:
|
||||
|
||||
networks:
|
||||
overlay-net:
|
||||
external: true
|
||||
name: ${OVERLAY_NETWORK:-homelab-net}
|
||||
37
proxmox/services/fusionauth.yml
Normal file
37
proxmox/services/fusionauth.yml
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
version: '3.8'
|
||||
|
||||
# Deploy with:
|
||||
# docker stack deploy -c fusionauth.yml fusionauth
|
||||
#
|
||||
# Runs on: CADDY_INSTANCE (ip-10-0-1-168)
|
||||
# FusionAuth is Java-based and memory hungry — deployed on caddy node (t3.large, 8GB)
|
||||
# Accessible publicly via Caddy reverse proxy at auth.yourdomain.com
|
||||
|
||||
services:
|
||||
fusionauth:
|
||||
image: fusionauth/fusionauth-app:latest
|
||||
environment:
|
||||
DATABASE_URL: jdbc:postgresql://postgres:5432/fusionauth_db
|
||||
DATABASE_ROOT_USERNAME: postgres
|
||||
DATABASE_ROOT_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
DATABASE_USERNAME: fusionauth_user
|
||||
DATABASE_PASSWORD: ${FUSIONAUTH_DB_PASSWORD}
|
||||
FUSIONAUTH_APP_MEMORY: 512M
|
||||
FUSIONAUTH_APP_RUNTIME_MODE: production
|
||||
SEARCH_TYPE: database
|
||||
networks:
|
||||
- overlay-net
|
||||
deploy:
|
||||
replicas: 1
|
||||
placement:
|
||||
constraints:
|
||||
- node.hostname == ip-10-0-1-168
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
delay: 5s
|
||||
max_attempts: 3
|
||||
|
||||
networks:
|
||||
overlay-net:
|
||||
external: true
|
||||
name: ${OVERLAY_NETWORK:-homelab-net}
|
||||
17
proxmox/services/gen-env.sh
Executable file
17
proxmox/services/gen-env.sh
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
#!/usr/bin/env bash
|
||||
set -uo pipefail
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Usage: gen-env.sh <service.yml>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PREFIX="homelab"
|
||||
out=""
|
||||
|
||||
for var in $(sed -n 's/.*\${{\([A-Z_]*\)}}.*/\1/p' "$1" | grep -v OVERLAY_NETWORK | sort -u); do
|
||||
val=$(pass "$PREFIX/$var" 2>/dev/null) || continue
|
||||
out+="$var=$val "
|
||||
done
|
||||
|
||||
echo "$out"
|
||||
99
proxmox/services/ghost.yml
Normal file
99
proxmox/services/ghost.yml
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
version: '3.8'
|
||||
|
||||
# Deploy with:
|
||||
# docker stack deploy -c ghost.yml ghost
|
||||
#
|
||||
# Runs on: adder-ghost
|
||||
# Three Ghost blog instances, each with its own port and MariaDB database.
|
||||
# Ghost 1: port 2368, Ghost 2: port 2369, Ghost 3: port 2370
|
||||
|
||||
services:
|
||||
ghost1:
|
||||
image: ghost:5-alpine
|
||||
environment:
|
||||
database__client: mysql
|
||||
database__connection__host: mariadb_mariadb
|
||||
database__connection__port: 3306
|
||||
database__connection__user: ghost1_user
|
||||
database__connection__password: ${GHOST1_DB_PASSWORD}
|
||||
database__connection__database: ghost1_db
|
||||
url: ${GHOST1_URL:-http://localhost:2368}
|
||||
ports:
|
||||
- "2368:2368"
|
||||
volumes:
|
||||
- ghost1_data:/var/lib/ghost/content
|
||||
networks:
|
||||
- overlay-net
|
||||
deploy:
|
||||
replicas: 1
|
||||
placement:
|
||||
constraints:
|
||||
- node.hostname == adder-ghost
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
delay: 5s
|
||||
max_attempts: 3
|
||||
|
||||
ghost2:
|
||||
image: ghost:5-alpine
|
||||
environment:
|
||||
database__client: mysql
|
||||
database__connection__host: mariadb_mariadb
|
||||
database__connection__port: 3306
|
||||
database__connection__user: ghost2_user
|
||||
database__connection__password: ${GHOST2_DB_PASSWORD}
|
||||
database__connection__database: ghost2_db
|
||||
url: ${GHOST2_URL:-http://localhost:2369}
|
||||
server__port: 2369
|
||||
ports:
|
||||
- "2369:2369"
|
||||
volumes:
|
||||
- ghost2_data:/var/lib/ghost/content
|
||||
networks:
|
||||
- overlay-net
|
||||
deploy:
|
||||
replicas: 1
|
||||
placement:
|
||||
constraints:
|
||||
- node.hostname == adder-ghost
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
delay: 5s
|
||||
max_attempts: 3
|
||||
|
||||
ghost3:
|
||||
image: ghost:5-alpine
|
||||
environment:
|
||||
database__client: mysql
|
||||
database__connection__host: mariadb_mariadb
|
||||
database__connection__port: 3306
|
||||
database__connection__user: ghost3_user
|
||||
database__connection__password: ${GHOST3_DB_PASSWORD}
|
||||
database__connection__database: ghost3_db
|
||||
url: ${GHOST3_URL:-http://localhost:2370}
|
||||
server__port: 2370
|
||||
ports:
|
||||
- "2370:2370"
|
||||
volumes:
|
||||
- ghost3_data:/var/lib/ghost/content
|
||||
networks:
|
||||
- overlay-net
|
||||
deploy:
|
||||
replicas: 1
|
||||
placement:
|
||||
constraints:
|
||||
- node.hostname == adder-ghost
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
delay: 5s
|
||||
max_attempts: 3
|
||||
|
||||
volumes:
|
||||
ghost1_data:
|
||||
ghost2_data:
|
||||
ghost3_data:
|
||||
|
||||
networks:
|
||||
overlay-net:
|
||||
external: true
|
||||
name: ${OVERLAY_NETWORK:-homelab-net}
|
||||
35
proxmox/services/mariadb.yml
Normal file
35
proxmox/services/mariadb.yml
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
version: '3.8'
|
||||
|
||||
# Deploy with:
|
||||
# docker stack deploy -c mariadb.yml mariadb
|
||||
#
|
||||
# Runs on: adder-ghost
|
||||
|
||||
services:
|
||||
mariadb:
|
||||
image: mariadb:11
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD}
|
||||
ports:
|
||||
- "3306:3306"
|
||||
volumes:
|
||||
- mariadb_data:/var/lib/mysql
|
||||
networks:
|
||||
- overlay-net
|
||||
deploy:
|
||||
replicas: 1
|
||||
placement:
|
||||
constraints:
|
||||
- node.hostname == adder-ghost
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
delay: 5s
|
||||
max_attempts: 3
|
||||
|
||||
volumes:
|
||||
mariadb_data:
|
||||
|
||||
networks:
|
||||
overlay-net:
|
||||
external: true
|
||||
name: ${OVERLAY_NETWORK:-homelab-net}
|
||||
0
proxmox/services/monerod-ban-list.txt
Normal file
0
proxmox/services/monerod-ban-list.txt
Normal file
42
proxmox/services/monerod.yml
Normal file
42
proxmox/services/monerod.yml
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
version: '3.8'
|
||||
|
||||
# Deploy with:
|
||||
# docker stack deploy -c monerod.yml monerod
|
||||
#
|
||||
# Runs on: game node
|
||||
# Restricted RPC node with pruning enabled to reduce disk usage.
|
||||
# Blockchain data is bind-mounted from NAS at /mnt/nas/.bitmonero.
|
||||
# Restricted RPC exposed on port 18089 for external wallet access.
|
||||
|
||||
services:
|
||||
monerod:
|
||||
image: ghcr.io/sethforprivacy/simple-monerod:latest
|
||||
command:
|
||||
- --rpc-restricted-bind-ip=0.0.0.0
|
||||
- --rpc-restricted-bind-port=18089
|
||||
- --no-igd
|
||||
- --enable-dns-blocklist
|
||||
- --ban-list=/home/monero/ban_list.txt
|
||||
- --prune-blockchain
|
||||
ports:
|
||||
- "18080:18080"
|
||||
- "18089:18089"
|
||||
volumes:
|
||||
- /mnt/nas/.bitmonero:/home/monero/.bitmonero
|
||||
- ./monerod-ban-list.txt:/home/monero/ban_list.txt:ro
|
||||
networks:
|
||||
- overlay-net
|
||||
deploy:
|
||||
replicas: 1
|
||||
placement:
|
||||
constraints:
|
||||
- node.hostname == game
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
delay: 5s
|
||||
max_attempts: 3
|
||||
|
||||
networks:
|
||||
overlay-net:
|
||||
external: true
|
||||
name: ${OVERLAY_NETWORK:-homelab-net}
|
||||
40
proxmox/services/n8n.yml
Normal file
40
proxmox/services/n8n.yml
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
version: '3.8'
|
||||
|
||||
# Deploy with:
|
||||
# docker stack deploy -c n8n.yml n8n
|
||||
#
|
||||
# Runs on: pve-tools
|
||||
|
||||
services:
|
||||
n8n:
|
||||
image: n8nio/n8n:latest
|
||||
environment:
|
||||
DB_TYPE: postgresdb
|
||||
DB_POSTGRESDB_HOST: postgres_postgres
|
||||
DB_POSTGRESDB_PORT: 5432
|
||||
DB_POSTGRESDB_DATABASE: n8n_db
|
||||
DB_POSTGRESDB_USER: n8n_user
|
||||
DB_POSTGRESDB_PASSWORD: ${N8N_DB_PASSWORD}
|
||||
ports:
|
||||
- "5678:5678"
|
||||
volumes:
|
||||
- n8n_data:/home/node/.n8n
|
||||
networks:
|
||||
- overlay-net
|
||||
deploy:
|
||||
replicas: 1
|
||||
placement:
|
||||
constraints:
|
||||
- node.hostname == pve-tools
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
delay: 5s
|
||||
max_attempts: 3
|
||||
|
||||
volumes:
|
||||
n8n_data:
|
||||
|
||||
networks:
|
||||
overlay-net:
|
||||
external: true
|
||||
name: ${OVERLAY_NETWORK:-homelab-net}
|
||||
10
proxmox/services/nats.conf
Normal file
10
proxmox/services/nats.conf
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
jetstream {
|
||||
store_dir: /data
|
||||
}
|
||||
|
||||
http_port: 8222
|
||||
|
||||
websocket {
|
||||
port: 8080
|
||||
no_tls: true
|
||||
}
|
||||
46
proxmox/services/nats.yml
Normal file
46
proxmox/services/nats.yml
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
version: '3.8'
|
||||
|
||||
# Deploy with:
|
||||
# docker stack deploy -c nats.yml nats
|
||||
#
|
||||
# Runs on: pve-tools
|
||||
# JetStream enabled for persistent messaging.
|
||||
# Services connect to nats_nats:4222 via overlay, or host:4222 externally.
|
||||
|
||||
services:
|
||||
nats:
|
||||
image: nats:latest
|
||||
command:
|
||||
- -c=/etc/nats/nats.conf
|
||||
ports:
|
||||
- "4222:4222"
|
||||
- "8080:8080"
|
||||
- "8223:8222"
|
||||
volumes:
|
||||
- nats_data:/data
|
||||
configs:
|
||||
- source: nats_conf
|
||||
target: /etc/nats/nats.conf
|
||||
networks:
|
||||
- overlay-net
|
||||
deploy:
|
||||
replicas: 1
|
||||
placement:
|
||||
constraints:
|
||||
- node.hostname == pve-tools
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
delay: 5s
|
||||
max_attempts: 3
|
||||
|
||||
configs:
|
||||
nats_conf:
|
||||
file: ./nats.conf
|
||||
|
||||
volumes:
|
||||
nats_data:
|
||||
|
||||
networks:
|
||||
overlay-net:
|
||||
external: true
|
||||
name: ${OVERLAY_NETWORK:-homelab-net}
|
||||
38
proxmox/services/postgres.yml
Normal file
38
proxmox/services/postgres.yml
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
version: '3.8'
|
||||
|
||||
# Deploy with:
|
||||
# docker stack deploy -c postgres.yml postgres
|
||||
#
|
||||
# Runs on: POSTGRES_INSTANCE (ip-10-0-1-173)
|
||||
# Creates databases and users for all services on first boot via init scripts.
|
||||
# Data is persisted in a named Docker volume on the postgres node.
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:16
|
||||
environment:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
ports:
|
||||
- "5432:5432"
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
networks:
|
||||
- overlay-net
|
||||
deploy:
|
||||
replicas: 1
|
||||
placement:
|
||||
constraints:
|
||||
- node.hostname == pve-postgres
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
delay: 5s
|
||||
max_attempts: 3
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
|
||||
networks:
|
||||
overlay-net:
|
||||
external: true
|
||||
name: ${OVERLAY_NETWORK:-homelab-net}
|
||||
Loading…
Reference in a new issue