# pgdb (192.168.55.15) — TimescaleDB + pgweb GUI + nightly backup # # Deploy: copy this file to /opt/database/docker-compose.yml on pgdb, # create /opt/database/.env (chmod 600) from .env.example, plus # /opt/database/pgweb-bookmarks/{hass,scribe}.toml (chmod 600, contains DB password). # Then: docker compose config --quiet && docker compose up -d # # Rollback: previous launch command is kept at /opt/database/run # (container is stateless; data lives on /srv/pgdata). services: timescaledb: image: timescale/timescaledb:latest-pg18 container_name: timescaledb restart: unless-stopped ports: - "192.168.55.15:5432:5432" # bind VM IP only (no IPv6 wildcard) environment: POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} volumes: - /srv/pgdata:/var/lib/postgresql # data disk (ext4 /dev/sdb1) healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 30s timeout: 5s retries: 5 start_period: 10s pgweb: image: sosedoff/pgweb:latest container_name: pgweb restart: unless-stopped # bind/listen/readonly/sessions/bookmarks-only/bookmarks-dir are CLI flags (no env equivalent in v0.17.0) command: ["pgweb", "--bind", "0.0.0.0", "--listen", "8081", "--readonly", "--sessions", "--bookmarks-only", "--bookmarks-dir", "/bookmarks"] ports: - "192.168.55.15:8081:8081" # LAN only + basic auth (see .env) environment: PGWEB_AUTH_USER: ${PGWEB_AUTH_USER} PGWEB_AUTH_PASS: ${PGWEB_AUTH_PASS} PGWEB_BOOKMARKS_DIR: /bookmarks volumes: - ./pgweb-bookmarks:/bookmarks:ro # bookmark .toml files (contain DB password, keep 0600) depends_on: timescaledb: condition: service_healthy pg-backup: image: prodrigestivill/postgres-backup-local:latest # latest = postgres 18 base (pg_dump 18.x) container_name: pg-backup restart: unless-stopped environment: POSTGRES_HOST: timescaledb POSTGRES_DB: "hass scribe postgres" POSTGRES_USER: postgres POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_EXTRA_OPTS: "-Fc" # custom-format dumps (pg_restore) SCHEDULE: "0 2 * * *" # nightly 02:00 (TZ=Asia/Shanghai -> local 02:00) BACKUP_ON_START: "TRUE" # immediate backup on first start BACKUP_SUFFIX: ".dump" HEALTHCHECK_PORT: "80" # go-cron health endpoint for the image healthcheck TZ: "Asia/Shanghai" # match original host-cron 02:00 local (container default is UTC) volumes: - /opt/database/backups:/backups # POSIX fs required; root disk, separate from data disk depends_on: timescaledb: condition: service_healthy