services: pds: image: ghcr.io/bluesky-social/pds:0.4 volumes: - pds-data:/pds environment: # Service Configuration - SERVICE_FQDN_PDS_3000 - PDS_HOSTNAME=${SERVICE_URL_PDS} - PDS_DATA_DIRECTORY=${PDS_DATA_DIRECTORY:-/pds} # Authentication & Security - PDS_JWT_SECRET=${SERVICE_BASE64_PDS} - PDS_ADMIN_PASSWORD=${SERVICE_PASSWORD_PDS} - PDS_ADMIN_EMAIL=${PDS_ADMIN_EMAIL} - PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX=${SERVICE_HEX_32_ROTATIONKEY} # Storage Configuration - PDS_BLOBSTORE_DISK_LOCATION=${PDS_DATA_DIRECTORY:-/pds}/blocks - PDS_BLOB_UPLOAD_LIMIT=${PDS_BLOB_UPLOAD_LIMIT:-104857600} # External Services - PDS_DID_PLC_URL=${PDS_DID_PLC_URL:-https://plc.directory} - PDS_BSKY_APP_VIEW_URL=${PDS_BSKY_APP_VIEW_URL:-https://api.pop1.bsky.app} - PDS_BSKY_APP_VIEW_DID=${PDS_BSKY_APP_VIEW_DID:-did:web:api.bsky.app} - PDS_REPORT_SERVICE_URL=${PDS_REPORT_SERVICE_URL:-https://mod.bsky.app} - PDS_REPORT_SERVICE_DID=${PDS_REPORT_SERVICE_DID:-did:plc:ar7c4by46qjdydhdevvrndac} - PDS_CRAWLERS=${PDS_CRAWLERS:-https://bsky.network} # Email Configuration - PDS_EMAIL_SMTP_URL=${PDS_EMAIL_SMTP_URL} - PDS_EMAIL_FROM_ADDRESS=${PDS_EMAIL_FROM_ADDRESS} - PDS_CONTACT_EMAIL_ADDRESS=${PDS_CONTACT_EMAIL_ADDRESS} # Logging - LOG_ENABLED=${LOG_ENABLED:-false} command: | sh -c ' set -euo pipefail echo "Installing required packages and pdsadmin..." apk add --no-cache openssl curl bash jq coreutils gnupg util-linux-misc >/dev/null echo "Downloading pdsadmin..." curl -o /usr/local/bin/pdsadmin.sh https://raw.githubusercontent.com/bluesky-social/pds/main/pdsadmin.sh chmod 700 /usr/local/bin/pdsadmin.sh ln -sf /usr/local/bin/pdsadmin.sh /usr/local/bin/pdsadmin echo "Generating pds.env with all specified Coolify environment variables..." env | awk -F "=" " /^(PDS|LOG|SERVICE)_[A-Z0-9_]+/ { gsub(/\\x27/, \"\\\"\", \$2); print \$1 \"=\\\"\" \$2 \"\\\"\" }" > ${PDS_DATA_DIRECTORY}/pds.env echo "Launching PDS..." exec node --enable-source-maps index.js ' healthcheck: test: ["CMD", "wget", "--spider", "http://127.0.0.1:3000/xrpc/_health"] interval: 2s timeout: 10s retries: 10 gatekeeper: container_name: gatekeeper image: fatfingers23/pds_gatekeeper:latest restart: unless-stopped volumes: - pds-data:/pds environment: - PDS_DATA_DIRECTORY=${PDS_DATA_DIRECTORY:-/pds} - PDS_BASE_URL=http://pds:3000 - GATEKEEPER_HOST=0.0.0.0 depends_on: pds: condition: service_healthy healthcheck: test: - CMD - timeout - '1' - bash - '-c' - 'cat < /dev/null > /dev/tcp/0.0.0.0/8080' interval: 10s timeout: 5s retries: 3 start_period: 10s labels: # Traefik Configuration (ensure you update the Gatekeeper router Host rule to your PDS hostname) - traefik.enable=true - traefik.http.routers.pds-gatekeeper.rule=Host(`pds.indexx.dev`) && (Path(`/xrpc/com.atproto.server.getSession`) || Path(`/xrpc/com.atproto.server.updateEmail`) || Path(`/xrpc/com.atproto.server.createSession`) || Path(`/xrpc/com.atproto.server.createAccount`) || Path(`/@atproto/oauth-provider/~api/sign-in`)) - traefik.http.routers.pds-gatekeeper.entrypoints=https - traefik.http.routers.pds-gatekeeper.tls=true - traefik.http.routers.pds-gatekeeper.priority=100 - traefik.http.routers.pds-gatekeeper.middlewares=gatekeeper-cors # Load Balancer - traefik.http.services.pds-gatekeeper.loadbalancer.server.port=8080 - traefik.http.services.pds-gatekeeper.loadbalancer.server.scheme=http # CORS Middleware - traefik.http.middlewares.gatekeeper-cors.headers.accesscontrolallowmethods=GET,POST,PUT,DELETE,OPTIONS,PATCH - traefik.http.middlewares.gatekeeper-cors.headers.accesscontrolallowheaders=* - traefik.http.middlewares.gatekeeper-cors.headers.accesscontrolalloworiginlist=* - traefik.http.middlewares.gatekeeper-cors.headers.accesscontrolmaxage=100 - traefik.http.middlewares.gatekeeper-cors.headers.addvaryheader=true - traefik.http.middlewares.gatekeeper-cors.headers.accesscontrolallowcredentials=true volumes: pds-data: