services: nginx: build: context: ./nginx ports: - "80:80" - "443:443" volumes: - ./nginx/conf.d:/etc/nginx/conf.d:ro - ./nginx/certs:/etc/nginx/certs - ./qr:/qr:ro depends_on: ui: condition: service_started api: condition: service_started restart: on-failure api: build: context: ./api environment: DATABASE_URL: ${DATABASE_URL} API_KEYS: ${API_KEYS} API_KEY_ENCRYPTION_KEY: ${API_KEY_ENCRYPTION_KEY} COINGECKO_API_KEY: ${COINGECKO_API_KEY} FOUNDER_PAYMENT_ADDRESS: ${FOUNDER_PAYMENT_ADDRESS} FOUNDER_VIEW_KEY: ${FOUNDER_VIEW_KEY} DONATIONS_ENABLED: ${DONATIONS_ENABLED:-false} QR_STORAGE_DIR: ${QR_STORAGE_DIR:-/qr} MONERO_WALLET_RPC_URLS: ${MONERO_WALLET_RPC_URLS:-http://wallet-rpc-reconciler-1:18083,http://wallet-rpc-reconciler-2:18083,http://wallet-rpc-reconciler-3:18083} MONERO_WALLET_RPC_USER: ${MONERO_WALLET_RPC_USER} MONERO_WALLET_RPC_PASSWORD: ${MONERO_WALLET_RPC_PASSWORD} MONERO_WALLET_RPC_WALLET_PASSWORD: ${MONERO_WALLET_RPC_WALLET_PASSWORD} MONERO_WALLET_RPC_WALLET_DIR: ${MONERO_WALLET_RPC_WALLET_DIR:-/wallets} MONERO_DAEMON_URL: ${MONERO_DAEMON_URL:-http://xmr-node.cakewallet.com:18081} GUNICORN_WORKERS: ${GUNICORN_WORKERS:-5} volumes: - ./qr:/qr depends_on: db: condition: service_healthy restart: on-failure reconciler: build: context: ./api command: ["python", "-m", "app.reconciler"] environment: DATABASE_URL: ${DATABASE_URL} API_KEYS: ${API_KEYS} API_KEY_ENCRYPTION_KEY: ${API_KEY_ENCRYPTION_KEY} INVOICE_RECONCILE_INTERVAL_SECONDS: ${INVOICE_RECONCILE_INTERVAL_SECONDS} LOG_LEVEL: ${LOG_LEVEL:-INFO} MONERO_WALLET_RPC_URLS: ${MONERO_WALLET_RPC_URLS:-http://wallet-rpc-reconciler-1:18083,http://wallet-rpc-reconciler-2:18083,http://wallet-rpc-reconciler-3:18083} MONERO_WALLET_RPC_USER: ${MONERO_WALLET_RPC_USER} MONERO_WALLET_RPC_PASSWORD: ${MONERO_WALLET_RPC_PASSWORD} MONERO_WALLET_RPC_WALLET_PASSWORD: ${MONERO_WALLET_RPC_WALLET_PASSWORD} MONERO_WALLET_RPC_WALLET_DIR: ${MONERO_WALLET_RPC_WALLET_DIR:-/wallets} MONERO_DAEMON_URL: ${MONERO_DAEMON_URL:-http://xmr-node.cakewallet.com:18081} depends_on: api: condition: service_started db: condition: service_healthy restart: on-failure monerod: build: context: ./docker/monero args: MONERO_VERSION: ${MONERO_VERSION:-0.18.4.4} image: monero-local:${MONERO_VERSION:-0.18.4.4} entrypoint: ["monerod"] command: [ "--non-interactive", "--rpc-bind-ip", "0.0.0.0", "--rpc-bind-port", "18081", "--confirm-external-bind", "--prune-blockchain", "--data-dir", "/data", "--log-level", "0" ] volumes: - monerod_data:/data healthcheck: test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:18081/get_height >/dev/null || exit 1"] interval: 30s timeout: 5s retries: 10 start_period: 60s restart: on-failure profiles: ["local-daemon"] wallet-rpc-reconciler-1: build: context: ./docker/monero args: MONERO_VERSION: ${MONERO_VERSION:-0.18.4.4} image: monero-local:${MONERO_VERSION:-0.18.4.4} command: [ "monero-wallet-rpc", "--non-interactive", "--rpc-bind-ip", "0.0.0.0", "--rpc-bind-port", "18083", "--confirm-external-bind", "--daemon-address", "${MONERO_DAEMON_URL:-http://xmr-node.cakewallet.com:18081}", "--rpc-login", "${MONERO_WALLET_RPC_USER}:${MONERO_WALLET_RPC_PASSWORD}", "--wallet-dir", "${MONERO_WALLET_RPC_WALLET_DIR:-/wallets}", "--password", "${MONERO_WALLET_RPC_WALLET_PASSWORD}", "--log-level", "3" ] volumes: - ./wallets/reconciler:/wallets restart: on-failure wallet-rpc-reconciler-2: build: context: ./docker/monero args: MONERO_VERSION: ${MONERO_VERSION:-0.18.4.4} image: monero-local:${MONERO_VERSION:-0.18.4.4} command: [ "monero-wallet-rpc", "--non-interactive", "--rpc-bind-ip", "0.0.0.0", "--rpc-bind-port", "18083", "--confirm-external-bind", "--daemon-address", "${MONERO_DAEMON_URL:-http://xmr-node.cakewallet.com:18081}", "--rpc-login", "${MONERO_WALLET_RPC_USER}:${MONERO_WALLET_RPC_PASSWORD}", "--wallet-dir", "${MONERO_WALLET_RPC_WALLET_DIR:-/wallets}", "--password", "${MONERO_WALLET_RPC_WALLET_PASSWORD}", "--log-level", "3" ] volumes: - ./wallets/reconciler:/wallets restart: on-failure wallet-rpc-reconciler-3: build: context: ./docker/monero args: MONERO_VERSION: ${MONERO_VERSION:-0.18.4.4} image: monero-local:${MONERO_VERSION:-0.18.4.4} command: [ "monero-wallet-rpc", "--non-interactive", "--rpc-bind-ip", "0.0.0.0", "--rpc-bind-port", "18083", "--confirm-external-bind", "--daemon-address", "${MONERO_DAEMON_URL:-http://xmr-node.cakewallet.com:18081}", "--rpc-login", "${MONERO_WALLET_RPC_USER}:${MONERO_WALLET_RPC_PASSWORD}", "--wallet-dir", "${MONERO_WALLET_RPC_WALLET_DIR:-/wallets}", "--password", "${MONERO_WALLET_RPC_WALLET_PASSWORD}", "--log-level", "3" ] volumes: - ./wallets/reconciler:/wallets restart: on-failure ui: build: context: ./ui environment: API_BASE_URL: ${API_BASE_URL:-http://nginx/api} NEXT_PUBLIC_SITE_URL: ${SITE_URL:-http://localhost} NEXT_PUBLIC_DONATIONS_ENABLED: ${DONATIONS_ENABLED:-false} depends_on: api: condition: service_started restart: on-failure db: image: postgres:16-alpine environment: POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} volumes: - postgres_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] interval: 5s timeout: 3s retries: 10 db-backup: build: context: ./docker/pg_backup environment: POSTGRES_HOST: db POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} BACKUP_RETENTION_DAYS: ${BACKUP_RETENTION_DAYS:-7} volumes: - ./backups/postgres:/backups depends_on: db: condition: service_healthy restart: on-failure profiles: ["db-backup"] volumes: postgres_data: monerod_data: