All checks were successful
Deploy Docker Images / Build, push, and deploy (push) Successful in 1m19s
Restore CHOWN/SETUID/SETGID/etc. after cap_drop ALL so containers boot. Attach bluesky_pds to the proxy network so Caddy can resolve it.
444 lines
16 KiB
YAML
444 lines
16 KiB
YAML
# Shared security for BEAM roles that do not need host networking / NET_ADMIN.
|
|
# Keep a small cap set: entrypoint runs as root to chown /data, su to nobody,
|
|
# and symlink uploads under /app. cap_drop ALL with no adds crashes the boot.
|
|
x-beam-security: &beam_security
|
|
cap_drop:
|
|
- ALL
|
|
cap_add:
|
|
- CHOWN
|
|
- DAC_OVERRIDE
|
|
- FOWNER
|
|
- SETGID
|
|
- SETUID
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
tmpfs:
|
|
- /tmp:size=64M,mode=1777
|
|
|
|
services:
|
|
postgres:
|
|
image: pgvector/pgvector:pg16@sha256:00ba258a66dac104fd5171074a0084462a64a1369d8513f3d0a634e2f24d15bc
|
|
container_name: elektrine_db
|
|
shm_size: ${POSTGRES_SHM_SIZE:-512m}
|
|
command:
|
|
[
|
|
"postgres",
|
|
"-c",
|
|
"shared_preload_libraries=pg_stat_statements",
|
|
"-c",
|
|
"pg_stat_statements.max=10000",
|
|
"-c",
|
|
"pg_stat_statements.track=all"
|
|
]
|
|
environment:
|
|
POSTGRES_USER: elektrine
|
|
POSTGRES_PASSWORD: ${DB_PASSWORD:?set DB_PASSWORD}
|
|
POSTGRES_DB: elektrine_prod
|
|
volumes:
|
|
- postgres_data:/var/lib/postgresql/data
|
|
- ./initdb:/docker-entrypoint-initdb.d:ro
|
|
ports:
|
|
- "${DB_BIND:-127.0.0.1:5432:5432}"
|
|
# Backend network only — Caddy never joins this network.
|
|
networks:
|
|
- elektrine_network
|
|
restart: unless-stopped
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U elektrine -d elektrine_prod"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
cap_drop:
|
|
- ALL
|
|
cap_add:
|
|
- CHOWN
|
|
- DAC_OVERRIDE
|
|
- FOWNER
|
|
- SETGID
|
|
- SETUID
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
|
|
app:
|
|
<<: *beam_security
|
|
image: ${ELEKTRINE_IMAGE:-elektrine:local}
|
|
build:
|
|
context: ../..
|
|
dockerfile: deploy/docker/Dockerfile
|
|
args:
|
|
RELEASE_NAME: ${RELEASE_NAME:-elektrine}
|
|
ELEKTRINE_RELEASE_MODULES: ${ELEKTRINE_RELEASE_MODULES:-all}
|
|
INSTALL_TOR: ${INSTALL_TOR:-auto}
|
|
INSTALL_VPN_TOOLS: ${INSTALL_VPN_TOOLS:-auto}
|
|
PRIMARY_DOMAIN: ${PRIMARY_DOMAIN:-example.com}
|
|
EMAIL_DOMAIN: ${EMAIL_DOMAIN:-${PRIMARY_DOMAIN:-example.com}}
|
|
SUPPORTED_DOMAINS: ${SUPPORTED_DOMAINS:-${PRIMARY_DOMAIN:-example.com}}
|
|
PROFILE_BASE_DOMAINS: ${PROFILE_BASE_DOMAINS:-${PRIMARY_DOMAIN:-example.com}}
|
|
container_name: elektrine_app
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
env_file:
|
|
- ../../.env.production
|
|
environment:
|
|
DATABASE_URL: ecto://elektrine:${DB_PASSWORD:?set DB_PASSWORD}@postgres/elektrine_prod
|
|
POOL_SIZE: ${APP_POOL_SIZE:-10}
|
|
PHX_HOST: ${PHX_HOST:-example.com}
|
|
CADDY_ADMIN_HOST: ${CADDY_ADMIN_HOST:-admin.elektrine.com}
|
|
PHX_SERVER: "true"
|
|
PORT: ${PORT:-8080}
|
|
PHX_HTTP_IP: ${DOCKER_PHX_HTTP_IP:-0.0.0.0}
|
|
TRUSTED_PROXY_CIDRS: ${TRUSTED_PROXY_CIDRS:-172.30.0.0/24}
|
|
CADDY_ASK_TRUSTED_CIDRS: ${CADDY_ASK_TRUSTED_CIDRS:-${TRUSTED_PROXY_CIDRS:-172.30.0.0/24}}
|
|
MIX_ENV: prod
|
|
ELEKTRINE_RUNTIME_ROLE: app
|
|
ELEKTRINE_ENABLED_MODULES: ${ELEKTRINE_ENABLED_MODULES:-all}
|
|
ELEKTRINE_ENABLE_MAIL: "false"
|
|
ELEKTRINE_ENABLE_TOR: ${ELEKTRINE_ENABLE_TOR:-false}
|
|
TURN_ENABLED: ${TURN_ENABLED:-false}
|
|
ONION_TLS_ENABLED: ${ONION_TLS_ENABLED:-true}
|
|
MIGRATION_POOL_SIZE: ${MIGRATION_POOL_SIZE:-2}
|
|
ports:
|
|
- "${APP_HTTP_BIND:-127.0.0.1:8080:8080}"
|
|
volumes:
|
|
- app_data:/data
|
|
- uploads:/data/uploads
|
|
networks:
|
|
elektrine_network:
|
|
caddy_proxy_network:
|
|
aliases:
|
|
- app_proxy
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:$${PORT:-8080}/health >/dev/null || curl -g -fsS http://[::1]:$${PORT:-8080}/health >/dev/null || exit 1"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 12
|
|
start_period: 30s
|
|
restart: unless-stopped
|
|
|
|
worker:
|
|
<<: *beam_security
|
|
image: ${ELEKTRINE_IMAGE:-elektrine:local}
|
|
build:
|
|
context: ../..
|
|
dockerfile: deploy/docker/Dockerfile
|
|
args:
|
|
RELEASE_NAME: ${RELEASE_NAME:-elektrine}
|
|
ELEKTRINE_RELEASE_MODULES: ${ELEKTRINE_RELEASE_MODULES:-all}
|
|
INSTALL_TOR: ${INSTALL_TOR:-auto}
|
|
INSTALL_VPN_TOOLS: ${INSTALL_VPN_TOOLS:-auto}
|
|
PRIMARY_DOMAIN: ${PRIMARY_DOMAIN:-example.com}
|
|
EMAIL_DOMAIN: ${EMAIL_DOMAIN:-${PRIMARY_DOMAIN:-example.com}}
|
|
SUPPORTED_DOMAINS: ${SUPPORTED_DOMAINS:-${PRIMARY_DOMAIN:-example.com}}
|
|
PROFILE_BASE_DOMAINS: ${PROFILE_BASE_DOMAINS:-${PRIMARY_DOMAIN:-example.com}}
|
|
container_name: elektrine_worker
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
env_file:
|
|
- ../../.env.production
|
|
environment:
|
|
DATABASE_URL: ecto://elektrine:${DB_PASSWORD:?set DB_PASSWORD}@postgres/elektrine_prod
|
|
POOL_SIZE: ${WORKER_POOL_SIZE:-5}
|
|
PHX_HOST: ${PHX_HOST:-example.com}
|
|
MIX_ENV: prod
|
|
ELEKTRINE_RUNTIME_ROLE: worker
|
|
ELEKTRINE_ENABLED_MODULES: ${ELEKTRINE_ENABLED_MODULES:-all}
|
|
ELEKTRINE_ENABLE_MAIL: "false"
|
|
ELEKTRINE_ENABLE_TOR: "false"
|
|
TURN_ENABLED: ${TURN_ENABLED:-false}
|
|
MIGRATION_POOL_SIZE: ${MIGRATION_POOL_SIZE:-2}
|
|
ACME_HOME: ${ACME_HOME:-/data/acme.sh}
|
|
ACME_SH_BIN: ${ACME_SH_BIN:-/data/acme.sh/acme.sh}
|
|
ACME_WILDCARD_RENEWAL_ENABLED: ${ACME_WILDCARD_RENEWAL_ENABLED:-false}
|
|
ELEKTRINE_API_BASE: ${ELEKTRINE_API_BASE:-http://app:8080}
|
|
CADDY_TLS_MOUNT_DIR: ${CADDY_TLS_MOUNT_DIR:-/opt/elektrine/certs}
|
|
RELOAD_CMD: ${ACME_RELOAD_CMD:-true}
|
|
volumes:
|
|
- app_data:/data
|
|
- uploads:/data/uploads
|
|
- ${CADDY_TLS_MOUNT_DIR:-/opt/elektrine/certs}:/opt/elektrine/certs
|
|
networks:
|
|
- elektrine_network
|
|
restart: unless-stopped
|
|
|
|
vpn:
|
|
profiles: ["vpn"]
|
|
image: ${ELEKTRINE_IMAGE:-elektrine:local}
|
|
build:
|
|
context: ../..
|
|
dockerfile: deploy/docker/Dockerfile
|
|
args:
|
|
RELEASE_NAME: ${RELEASE_NAME:-elektrine}
|
|
ELEKTRINE_RELEASE_MODULES: ${ELEKTRINE_RELEASE_MODULES:-all}
|
|
INSTALL_TOR: ${INSTALL_TOR:-auto}
|
|
INSTALL_VPN_TOOLS: ${INSTALL_VPN_TOOLS:-auto}
|
|
PRIMARY_DOMAIN: ${PRIMARY_DOMAIN:-example.com}
|
|
EMAIL_DOMAIN: ${EMAIL_DOMAIN:-${PRIMARY_DOMAIN:-example.com}}
|
|
SUPPORTED_DOMAINS: ${SUPPORTED_DOMAINS:-${PRIMARY_DOMAIN:-example.com}}
|
|
PROFILE_BASE_DOMAINS: ${PROFILE_BASE_DOMAINS:-${PRIMARY_DOMAIN:-example.com}}
|
|
container_name: elektrine_vpn
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
env_file:
|
|
- ../../.env.production
|
|
environment:
|
|
DATABASE_URL: ecto://elektrine:${DB_PASSWORD:?set DB_PASSWORD}@127.0.0.1/elektrine_prod
|
|
POOL_SIZE: ${VPN_POOL_SIZE:-2}
|
|
MIX_ENV: prod
|
|
ELEKTRINE_RUNTIME_ROLE: vpn
|
|
ELEKTRINE_ENABLED_MODULES: ${ELEKTRINE_ENABLED_MODULES:-all}
|
|
ELEKTRINE_ENABLE_WEB: "false"
|
|
ELEKTRINE_ENABLE_JOBS: "false"
|
|
ELEKTRINE_ENABLE_MAIL: "false"
|
|
ELEKTRINE_ENABLE_TOR: "false"
|
|
VPN_SELFHOST_NODE: "true"
|
|
VPN_SELFHOST_PROTOCOL: ${VPN_SELFHOST_PROTOCOL:-wireguard}
|
|
VPN_SELFHOST_PROTOCOLS: ${VPN_SELFHOST_PROTOCOLS:-${VPN_SELFHOST_PROTOCOL:-wireguard}}
|
|
VPN_SELFHOST_WG_INTERFACE: ${VPN_SELFHOST_WG_INTERFACE:-wg0}
|
|
VPN_SELFHOST_ADDRESS: ${VPN_SELFHOST_ADDRESS:-10.8.0.1/24}
|
|
VPN_SELFHOST_LISTEN_PORT: ${VPN_SELFHOST_LISTEN_PORT:-51820}
|
|
VPN_SELFHOST_SS_LISTEN_PORT: ${VPN_SELFHOST_SS_LISTEN_PORT:-8388}
|
|
VPN_SELFHOST_SS_PORT_RANGE_START: ${VPN_SELFHOST_SS_PORT_RANGE_START:-8388}
|
|
VPN_SELFHOST_SS_PORT_RANGE_END: ${VPN_SELFHOST_SS_PORT_RANGE_END:-9387}
|
|
VPN_SELFHOST_SS_CIPHER: ${VPN_SELFHOST_SS_CIPHER:-chacha20-ietf-poly1305}
|
|
# Unix socket ss-server pushes per-port traffic stats to for quota accounting.
|
|
VPN_SELFHOST_SS_MANAGER_SOCKET: ${VPN_SELFHOST_SS_MANAGER_SOCKET:-/data/vpn/shadowsocks/manager.sock}
|
|
network_mode: host
|
|
cap_add:
|
|
- NET_ADMIN
|
|
volumes:
|
|
- app_data:/data
|
|
- uploads:/data/uploads
|
|
restart: unless-stopped
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
|
|
mail:
|
|
<<: *beam_security
|
|
profiles: ["email"]
|
|
image: ${ELEKTRINE_IMAGE:-elektrine:local}
|
|
build:
|
|
context: ../..
|
|
dockerfile: deploy/docker/Dockerfile
|
|
args:
|
|
RELEASE_NAME: ${RELEASE_NAME:-elektrine}
|
|
ELEKTRINE_RELEASE_MODULES: ${ELEKTRINE_RELEASE_MODULES:-all}
|
|
INSTALL_TOR: ${INSTALL_TOR:-auto}
|
|
INSTALL_VPN_TOOLS: ${INSTALL_VPN_TOOLS:-auto}
|
|
PRIMARY_DOMAIN: ${PRIMARY_DOMAIN:-example.com}
|
|
EMAIL_DOMAIN: ${EMAIL_DOMAIN:-${PRIMARY_DOMAIN:-example.com}}
|
|
SUPPORTED_DOMAINS: ${SUPPORTED_DOMAINS:-${PRIMARY_DOMAIN:-example.com}}
|
|
PROFILE_BASE_DOMAINS: ${PROFILE_BASE_DOMAINS:-${PRIMARY_DOMAIN:-example.com}}
|
|
container_name: elektrine_mail
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
env_file:
|
|
- ../../.env.production
|
|
environment:
|
|
DATABASE_URL: ecto://elektrine:${DB_PASSWORD:?set DB_PASSWORD}@postgres/elektrine_prod
|
|
POOL_SIZE: ${MAIL_POOL_SIZE:-5}
|
|
PHX_HOST: ${PHX_HOST:-example.com}
|
|
MIX_ENV: prod
|
|
ELEKTRINE_RUNTIME_ROLE: mail
|
|
ELEKTRINE_ENABLED_MODULES: ${ELEKTRINE_ENABLED_MODULES:-all}
|
|
ELEKTRINE_ENABLE_MAIL: ${ELEKTRINE_ENABLE_MAIL:-true}
|
|
ELEKTRINE_ENABLE_TOR: "false"
|
|
SMTP_PORT: ${SMTP_PORT:-2587}
|
|
SMTPS_PORT: ${SMTPS_PORT:-2465}
|
|
IMAPS_PORT: 2993
|
|
POP3S_PORT: 2995
|
|
volumes:
|
|
- app_data:/data
|
|
- uploads:/data/uploads
|
|
- ${MAIL_TLS_MOUNT_DIR:-/opt/elektrine/certs}:/opt/elektrine/certs:ro
|
|
networks:
|
|
- elektrine_network
|
|
ports:
|
|
- "${SMTP_BIND:-127.0.0.1:587:2587}"
|
|
- "${SMTPS_BIND:-465:2465}"
|
|
- "${IMAP_BIND:-127.0.0.1:143:2143}"
|
|
- "${POP3_BIND:-127.0.0.1:110:2110}"
|
|
- "${IMAP_TLS_BIND:-993:2993}"
|
|
- "${POP3_TLS_BIND:-995:2995}"
|
|
restart: unless-stopped
|
|
# Mail listeners (SMTP/IMAP/POP3 + TLS variants) hold one file descriptor per
|
|
# connection, plus in-flight TLS handshakes. The Docker default soft nofile
|
|
# (1024) is far too low and leads to :emfile ("too many open files") storms
|
|
# under connection floods. Recreate the container for changes to take effect.
|
|
ulimits:
|
|
nofile:
|
|
soft: 65536
|
|
hard: 65536
|
|
|
|
dns:
|
|
<<: *beam_security
|
|
profiles: ["dns"]
|
|
image: ${ELEKTRINE_IMAGE:-elektrine:local}
|
|
build:
|
|
context: ../..
|
|
dockerfile: deploy/docker/Dockerfile
|
|
args:
|
|
RELEASE_NAME: ${RELEASE_NAME:-elektrine}
|
|
ELEKTRINE_RELEASE_MODULES: ${ELEKTRINE_RELEASE_MODULES:-all}
|
|
INSTALL_TOR: ${INSTALL_TOR:-auto}
|
|
INSTALL_VPN_TOOLS: ${INSTALL_VPN_TOOLS:-auto}
|
|
PRIMARY_DOMAIN: ${PRIMARY_DOMAIN:-localhost}
|
|
EMAIL_DOMAIN: ${EMAIL_DOMAIN:-${PRIMARY_DOMAIN:-localhost}}
|
|
SUPPORTED_DOMAINS: ${SUPPORTED_DOMAINS:-${PRIMARY_DOMAIN:-localhost}}
|
|
PROFILE_BASE_DOMAINS: ${PROFILE_BASE_DOMAINS:-${PRIMARY_DOMAIN:-localhost}}
|
|
container_name: elektrine_dns
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
env_file:
|
|
- ../../.env.production
|
|
environment:
|
|
DATABASE_URL: ecto://elektrine:${DB_PASSWORD:?set DB_PASSWORD}@postgres/elektrine_prod
|
|
POOL_SIZE: ${DNS_POOL_SIZE:-3}
|
|
MIX_ENV: prod
|
|
RELEASE_NAME: ${RELEASE_NAME:-elektrine}
|
|
ELEKTRINE_ENABLED_MODULES: ${ELEKTRINE_ENABLED_MODULES:-all}
|
|
ELEKTRINE_RUNTIME_ROLE: worker
|
|
ELEKTRINE_ENABLE_WEB: "false"
|
|
ELEKTRINE_ENABLE_JOBS: "false"
|
|
ELEKTRINE_ENABLE_MAIL: "false"
|
|
ELEKTRINE_ENABLE_TOR: "false"
|
|
DNS_AUTHORITY_ENABLED: "true"
|
|
DNS_RECURSIVE_ENABLED: ${DNS_RECURSIVE_ENABLED:-false}
|
|
ports:
|
|
- "${DNS_UDP_BIND:-53:5300/udp}"
|
|
- "${DNS_TCP_BIND:-53:5300/tcp}"
|
|
volumes:
|
|
- app_data:/data
|
|
networks:
|
|
- elektrine_network
|
|
restart: unless-stopped
|
|
|
|
turn:
|
|
image: ${TURN_IMAGE:-coturn/coturn:latest@sha256:867607152c6ed9504a0b59a2546a9bd2872dcf74313b3bc6cf9b69cc81be6fb3}
|
|
container_name: elektrine_turn
|
|
profiles:
|
|
- turn
|
|
environment:
|
|
TURN_HOST: ${TURN_HOST:-${PRIMARY_DOMAIN:-example.com}}
|
|
TURN_PORT: ${TURN_PORT:-3478}
|
|
TURN_MIN_PORT: ${TURN_MIN_PORT:-49160}
|
|
TURN_MAX_PORT: ${TURN_MAX_PORT:-49200}
|
|
TURN_REALM: ${TURN_REALM:-${PRIMARY_DOMAIN:-example.com}}
|
|
TURN_EXTERNAL_IP: ${TURN_EXTERNAL_IP:-}
|
|
TURN_RELAY_IP: ${TURN_RELAY_IP:-}
|
|
TURN_SHARED_SECRET: ${TURN_SHARED_SECRET:?set TURN_SHARED_SECRET}
|
|
network_mode: host
|
|
command:
|
|
- --no-cli
|
|
- --fingerprint
|
|
- --use-auth-secret
|
|
- --static-auth-secret=${TURN_SHARED_SECRET:?set TURN_SHARED_SECRET}
|
|
- --realm=${TURN_REALM:-${PRIMARY_DOMAIN:-example.com}}
|
|
- --server-name=${TURN_REALM:-${PRIMARY_DOMAIN:-example.com}}
|
|
- --listening-ip=0.0.0.0
|
|
- --listening-port=${TURN_PORT:-3478}
|
|
- --min-port=${TURN_MIN_PORT:-49160}
|
|
- --max-port=${TURN_MAX_PORT:-49200}
|
|
- --lt-cred-mech
|
|
- --stale-nonce
|
|
- --simple-log
|
|
restart: unless-stopped
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
|
|
caddy_edge:
|
|
build:
|
|
context: ../..
|
|
dockerfile: deploy/caddy/Dockerfile
|
|
container_name: elektrine_caddy_edge
|
|
profiles:
|
|
- caddy
|
|
depends_on:
|
|
app:
|
|
condition: service_healthy
|
|
env_file:
|
|
- ../../.env.production
|
|
environment:
|
|
ACME_EMAIL: ${ACME_EMAIL:-admin@example.com}
|
|
CADDY_ASK_URL: ${CADDY_ASK_URL:-http://app_proxy:8080/_edge/tls/v1/allow}
|
|
CADDY_ADMIN_HOST: ${CADDY_ADMIN_HOST:-admin.elektrine.com}
|
|
CADDY_PROXY_PROTOCOL_ALLOWED_CIDRS: ${CADDY_PROXY_PROTOCOL_ALLOWED_CIDRS:-192.0.2.0/32}
|
|
# NETBIRD_ALLOWED_CIDRS kept for Phoenix / docs; Caddy reads literal CIDRs
|
|
# from the netbird_allowlist.caddy snippet (synced + caddy reload).
|
|
NETBIRD_ALLOWED_CIDRS: ${NETBIRD_ALLOWED_CIDRS:-192.0.2.0/32}
|
|
ORIGIN_UPSTREAM: ${CADDY_ORIGIN_UPSTREAM:-app_proxy:8080}
|
|
ports:
|
|
- "${CADDY_HTTP_BIND:-80:80}"
|
|
- "${CADDY_HTTPS_BIND:-443:443}"
|
|
volumes:
|
|
- ${CADDY_CONFIG_PATH:-../caddy/Caddyfile.baremetal}:/etc/caddy/Caddyfile:ro
|
|
- ${CADDY_NETBIRD_ALLOWLIST_PATH:-../caddy/netbird_allowlist.caddy}:/etc/caddy/netbird_allowlist.caddy:ro
|
|
- ${CADDY_TLS_MOUNT_DIR:-/opt/elektrine/certs}:/opt/elektrine/certs:ro
|
|
- caddy_data:/data
|
|
# Proxy network only — no path to Postgres.
|
|
networks:
|
|
- caddy_proxy_network
|
|
restart: unless-stopped
|
|
cap_drop:
|
|
- ALL
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
# Caddy needs to bind privileged ports when published as 80/443.
|
|
cap_add:
|
|
- NET_BIND_SERVICE
|
|
|
|
bluesky_pds:
|
|
image: ghcr.io/bluesky-social/pds:0.4@sha256:e0b756701c924410532c61b546a61810b6a0059bcebb0c21718d161f5b7880db
|
|
container_name: elektrine_bluesky_pds
|
|
profiles:
|
|
- bluesky
|
|
environment:
|
|
PDS_HOSTNAME: ${BLUESKY_MANAGED_DOMAIN:-bsky.local}
|
|
PDS_JWT_SECRET: ${BLUESKY_PDS_JWT_SECRET:?set BLUESKY_PDS_JWT_SECRET}
|
|
PDS_ADMIN_PASSWORD: ${BLUESKY_MANAGED_ADMIN_PASSWORD:?set BLUESKY_MANAGED_ADMIN_PASSWORD}
|
|
PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX: ${BLUESKY_PDS_ROTATION_KEY_HEX:-}
|
|
PDS_DATA_DIRECTORY: /pds
|
|
PDS_BLOBSTORE_DISK_LOCATION: /pds/blocks
|
|
PDS_BLOB_UPLOAD_LIMIT: 52428800
|
|
PDS_DID_PLC_URL: "https://plc.directory"
|
|
PDS_BSKY_APP_VIEW_URL: "https://api.bsky.app"
|
|
PDS_BSKY_APP_VIEW_DID: "did:web:api.bsky.app"
|
|
PDS_REPORT_SERVICE_URL: "https://mod.bsky.app"
|
|
PDS_REPORT_SERVICE_DID: "did:plc:ar7c4by46qjdydhdevvrndac"
|
|
PDS_CRAWLERS: "https://bsky.network"
|
|
LOG_ENABLED: true
|
|
ports:
|
|
- "127.0.0.1:${BLUESKY_PDS_PORT:-3000}:3000"
|
|
volumes:
|
|
- bluesky_pds_data:/pds
|
|
networks:
|
|
# App/backend network for admin/API; proxy network so Caddy can resolve bluesky_pds
|
|
- elektrine_network
|
|
- caddy_proxy_network
|
|
restart: unless-stopped
|
|
cap_drop:
|
|
- ALL
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
|
|
volumes:
|
|
postgres_data:
|
|
uploads:
|
|
app_data:
|
|
caddy_data:
|
|
bluesky_pds_data:
|
|
|
|
networks:
|
|
# Backend: app/worker/mail/dns/postgres. Edge proxies must not join this.
|
|
elektrine_network:
|
|
driver: bridge
|
|
# Edge: app + Caddy only. No database on this network.
|
|
caddy_proxy_network:
|
|
driver: bridge
|
|
ipam:
|
|
config:
|
|
- subnet: ${CADDY_PROXY_DOCKER_SUBNET:-172.30.0.0/24}
|