services: tor: image: btcpayserver/tor:0.4.8.10 container_name: tor-proxy volumes: - ./logs/tor:/var/log/tor - ./scripts/healthchecks:/scripts/healthchecks:ro networks: btcnet: aliases: - tor healthcheck: test: ["CMD", "sh", "/scripts/healthchecks/tor-progress.sh"] interval: 10s timeout: 5s retries: 50 restart: unless-stopped bitcoin: build: ./bitcoin container_name: bitcoin-signet depends_on: tor: condition: service_healthy volumes: - bitcoin_data:/home/bitcoin/.bitcoin - ./conf/bitcoin/bitcoin.conf:/etc/bitcoin/bitcoin.conf:ro - ./logs/bitcoin:/var/log/bitcoin - ./scripts/healthchecks:/scripts/healthchecks:ro networks: btcnet: aliases: - bitcoin user: root entrypoint: > /bin/sh -c " chown -R bitcoin:bitcoin /home/bitcoin/.bitcoin || echo 'warn: chown partiel (fichiers bind-mount Windows)'; exec su-exec bitcoin bitcoind -conf=/etc/bitcoin/bitcoin.conf -signet" healthcheck: test: ["CMD", "sh", "/scripts/healthchecks/bitcoin-progress.sh"] interval: 30s timeout: 10s retries: 50 restart: unless-stopped blindbit: image: git.4nkweb.com/4nk/blindbit-oracle:dev container_name: blindbit-oracle depends_on: bitcoin: condition: service_healthy volumes: - blindbit_data:/root/.blindbit-oracle - ./blindbit/blindbit.toml:/tmp/blindbit.toml:ro - bitcoin_data:/home/bitcoin/.bitcoin - ./logs/blindbit:/var/log/blindbit - ./scripts/healthchecks:/scripts/healthchecks:ro entrypoint: > sh -c "mkdir -p /root/.blindbit-oracle && if [ ! -f /root/.blindbit-oracle/blindbit.toml ]; then cp /tmp/blindbit.toml /root/.blindbit-oracle/blindbit.toml; fi && echo 'Waiting for Bitcoin to be ready...' && while ! nc -z bitcoin 38332; do sleep 2; done && echo 'Bitcoin is ready, starting BlindBit...' && exec ./main -datadir /root/.blindbit-oracle" networks: btcnet: aliases: - blindbit ports: - "0.0.0.0:8000:8000" healthcheck: test: ["CMD", "sh", "/scripts/healthchecks/blindbit-progress.sh"] interval: 15s timeout: 5s retries: 50 restart: unless-stopped sdk_relay: image: git.4nkweb.com/4nk/sdk_relay:int-dev container_name: sdk_relay depends_on: blindbit: condition: service_healthy volumes: - ./conf/relay/sdk_relay.conf:/app/.conf:ro - sdk_data:/app/.4nk - bitcoin_data:/app/.bitcoin - ./scripts/funds:/scripts/funds:ro - ./logs/sdk_relay:/var/log/sdk_relay - ./scripts/healthchecks:/scripts/healthchecks:ro ports: - "0.0.0.0:8090:8090" - "0.0.0.0:8091:8091" networks: btcnet: aliases: - sdk_relay logging: driver: "json-file" options: max-size: "10m" max-file: "3" environment: - HOME=/app - CORE_URL=${SDK_RELAY_CORE_URL} - WS_URL=${SDK_RELAY_WS_URL} - WALLET_NAME=${SDK_RELAY_WALLET_NAME} - NETWORK=${SDK_RELAY_NETWORK} - BLINDBIT_URL=${SDK_RELAY_BLINDBIT_URL} - ZMQ_URL=${SDK_RELAY_ZMQ_URL} - STORAGE=${SDK_RELAY_STORAGE} - DATA_DIR=${SDK_RELAY_DATA_DIR} - BITCOIN_DATA_DIR=${SDK_RELAY_BITCOIN_DATA_DIR} - BOOTSTRAP_URL=${SDK_RELAY_BOOTSTRAP_URL} - BOOTSTRAP_FAUCET=${SDK_RELAY_BOOTSTRAP_FAUCET} - RUST_LOG=INFO healthcheck: test: ["CMD", "sh", "/scripts/healthchecks/sdk-relay-progress.sh"] interval: 30s timeout: 10s retries: 50 restart: unless-stopped lecoffre-back: image: git.4nkweb.com/4nk/lecoffre-back-mini:int-dev container_name: lecoffre-back environment: - NODE_OPTIONS=${NODE_OPTIONS} - NODE_ENV=${NODE_ENV} - IDNOT_ANNUARY_BASE_URL=${IDNOT_ANNUARY_BASE_URL} - IDNOT_REDIRECT_URI=${IDNOT_REDIRECT_URI} - IDNOT_TOKEN_URL=${IDNOT_TOKEN_URL} - IDNOT_API_BASE_URL=${IDNOT_API_BASE_URL} - APP_HOST=${APP_HOST} - API_BASE_URL=${API_BASE_URL} - DEFAULT_STORAGE=${DEFAULT_STORAGE} - STRIPE_SECRET_KEY=${STRIPE_SECRET_KEY} - STRIPE_PUBLISHABLE_KEY=${STRIPE_PUBLISHABLE_KEY} - STRIPE_WEBHOOK_SECRET=${STRIPE_WEBHOOK_SECRET} - MAILCHIMP_API_KEY=${MAILCHIMP_API_KEY} - MAILCHIMP_SERVER_PREFIX=${MAILCHIMP_SERVER_PREFIX} - MAILCHIMP_LIST_ID=${MAILCHIMP_LIST_ID} - OVH_APPLICATION_KEY=${OVH_APPLICATION_KEY} - OVH_APPLICATION_SECRET=${OVH_APPLICATION_SECRET} - OVH_CONSUMER_KEY=${OVH_CONSUMER_KEY} - OVH_SERVICE_NAME=${OVH_SERVICE_NAME} ports: - "0.0.0.0:8080:8080" volumes: - /var/run/docker.sock:/var/run/docker.sock - ./logs/lecoffre-back:/var/log/lecoffre-back networks: btcnet: aliases: - lecoffre-back depends_on: sdk_relay: condition: service_healthy user: appuser command: ["node", "dist/server.js"] healthcheck: test: ["CMD", "sh", "-c", "if curl -f http://localhost:8080/api/v1/health >/dev/null 2>&1; then echo 'LeCoffre Backend ready: API responding'; exit 0; else echo 'LeCoffre Backend starting: API not yet ready'; exit 1; fi"] interval: 30s timeout: 10s retries: 50 start_period: 60s labels: - "com.centurylinklabs.watchtower.enable=true" restart: unless-stopped lecoffre-front: image: git.4nkweb.com/4nk/lecoffre-front:int-dev container_name: lecoffre-front working_dir: /leCoffre-front environment: - NODE_OPTIONS=${NODE_OPTIONS} - NODE_ENV=${NODE_ENV} - NEXT_PUBLIC_4NK_URL=${NEXT_PUBLIC_4NK_URL} - NEXT_PUBLIC_FRONT_APP_HOST=${NEXT_PUBLIC_FRONT_APP_HOST} - NEXT_PUBLIC_IDNOT_BASE_URL=${NEXT_PUBLIC_IDNOT_BASE_URL} - NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT=${NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT} - NEXT_PUBLIC_BACK_API_PROTOCOL=${NEXT_PUBLIC_BACK_API_PROTOCOL} - NEXT_PUBLIC_BACK_API_HOST=${NEXT_PUBLIC_BACK_API_HOST} - NEXT_PUBLIC_BACK_API_PORT=${NEXT_PUBLIC_BACK_API_PORT} - NEXT_PUBLIC_BACK_API_ROOT_URL=${NEXT_PUBLIC_BACK_API_ROOT_URL} - NEXT_PUBLIC_BACK_API_VERSION=${NEXT_PUBLIC_BACK_API_VERSION} ports: - "0.0.0.0:3004:3000" volumes: - ./logs/lecoffre-front:/var/log/lecoffre-front networks: btcnet: aliases: - lecoffre-front depends_on: lecoffre-back: condition: service_healthy ihm_client: condition: service_healthy sdk_storage: condition: service_healthy sdk_signer: condition: service_healthy user: lecoffreuser command: ["node", "server.js"] healthcheck: test: ["CMD", "sh", "-c", "if ps aux | grep -v grep | grep next-server >/dev/null 2>&1; then echo 'LeCoffre Frontend ready: Next.js server running'; exit 0; else echo 'LeCoffre Frontend starting: Next.js server not yet ready'; exit 1; fi"] interval: 30s timeout: 10s retries: 50 start_period: 30s labels: - "com.centurylinklabs.watchtower.enable=true" restart: unless-stopped ihm_client: image: git.4nkweb.com/4nk/ihm_client:int-dev container_name: ihm_client environment: - VITE_JWT_SECRET_KEY=${VITE_JWT_SECRET_KEY} - VITE_API_BASE_URL=${VITE_API_BASE_URL} - VITE_WS_URL=${VITE_WS_URL} - VITE_STORAGE_URL=${VITE_STORAGE_URL} - VITE_SIGNER_URL=${VITE_SIGNER_URL} - VITE_BOOTSTRAPURL=wss://dev4.4nkweb.com/ws/ ports: - "0.0.0.0:3003:3003" volumes: - ./logs/ihm_client:/var/log/ihm_client networks: btcnet: aliases: - ihm_client depends_on: sdk_relay: condition: service_healthy sdk_storage: condition: service_healthy sdk_signer: condition: service_healthy user: root command: ["npm", "start"] healthcheck: test: ["CMD", "sh", "-c", "if curl -f http://localhost:3003/ >/dev/null 2>&1; then echo 'IHM Client ready: Vite dev server responding'; exit 0; else echo 'IHM Client starting: Vite dev server not yet ready'; exit 1; fi"] interval: 30s timeout: 10s retries: 50 start_period: 30s labels: - "com.centurylinklabs.watchtower.enable=true" restart: unless-stopped sdk_signer: image: git.4nkweb.com/4nk/sdk_signer:int-dev container_name: sdk_signer ports: - "0.0.0.0:3001:9090" volumes: - sdk_signer_data:/app/data - ./logs/sdk_signer:/var/log/sdk_signer - ./scripts/healthchecks:/scripts/healthchecks:ro networks: btcnet: aliases: - sdk_signer user: appuser depends_on: sdk_storage: condition: service_healthy command: ["node", "/app/dist/index.js"] healthcheck: test: ["CMD", "sh", "/scripts/healthchecks/sdk-signer-progress.sh"] interval: 30s timeout: 10s retries: 50 start_period: 30s labels: - "com.centurylinklabs.watchtower.enable=true" restart: unless-stopped environment: - PORT=${SIGNER_PORT} - API_KEY=${SIGNER_API_KEY} - DATABASE_PATH=${SIGNER_DATABASE_PATH} - RELAY_URLS=${SIGNER_RELAY_URLS} - AUTO_RESTART=${SIGNER_AUTO_RESTART} - MAX_RESTARTS=${SIGNER_MAX_RESTARTS} - LOG_LEVEL=${SIGNER_LOG_LEVEL} - SIGNER_WS_URL=ws://dev3.4nkweb.com:9090 - SIGNER_BASE_URL=https://dev3.4nkweb.com sdk_storage: image: git.4nkweb.com/4nk/sdk_storage:int-dev container_name: sdk_storage ports: - "0.0.0.0:8081:8080" volumes: - sdk_storage_data:/app/data - ./logs/sdk_storage:/var/log/sdk_storage healthcheck: test: ["CMD", "sh", "-c", "if curl -f http://localhost:8080/health >/dev/null 2>&1; then echo 'SDK Storage ready: API responding'; exit 0; else echo 'SDK Storage starting: API not yet ready'; exit 1; fi"] interval: 30s timeout: 10s retries: 50 start_period: 30s networks: btcnet: aliases: - sdk_storage labels: - "com.centurylinklabs.watchtower.enable=true" restart: unless-stopped watchtower: image: containrrr/watchtower container_name: watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock command: --interval 30 --label-enable networks: - btcnet restart: unless-stopped signet_miner: build: context: ./miner container_name: signet_miner depends_on: bitcoin: condition: service_healthy env_file: - ./miner/.env volumes: - bitcoin_data:/bitcoin:ro - ./logs/miner:/var/log/miner networks: btcnet: aliases: - signet_miner profiles: ["miner"] restart: unless-stopped grafana: image: grafana/grafana:latest container_name: grafana ports: - "0.0.0.0:3005:3000" volumes: - grafana_data:/var/lib/grafana - ./conf/grafana/provisioning:/etc/grafana/provisioning - ./conf/grafana/dashboards:/var/lib/grafana/dashboards - ./conf/grafana/grafana.ini:/etc/grafana/grafana.ini:ro - ./logs:/var/log/lecoffre:ro environment: - GF_SECURITY_ADMIN_PASSWORD=Fuy8ZfxQI2xdSdoB8wsGxNjyU - GF_USERS_ALLOW_SIGN_UP=false - GF_SERVER_ROOT_URL=https://dev4.4nkweb.com/grafana/ - GF_PLUGINS_PREINSTALL_SYNC=grafana-clock-panel,grafana-simple-json-datasource networks: btcnet: aliases: - grafana depends_on: loki: condition: service_healthy promtail: condition: service_healthy healthcheck: test: ["CMD", "sh", "-c", "if curl -f http://localhost:3000/api/health >/dev/null 2>&1; then echo 'Grafana ready: Dashboard service responding'; exit 0; else echo 'Grafana starting: Dashboard service not yet ready'; exit 1; fi"] interval: 30s timeout: 10s retries: 50 start_period: 60s labels: - "com.centurylinklabs.watchtower.enable=true" restart: unless-stopped loki: image: grafana/loki:latest container_name: loki ports: - "0.0.0.0:3100:3100" volumes: - loki_data:/loki - ./conf/loki/loki-config.yaml:/etc/loki/loki-config.yaml:ro command: -config.file=/etc/loki/loki-config.yaml networks: btcnet: aliases: - loki healthcheck: test: ["CMD", "wget", "-q", "--spider", "http://localhost:3100/ready"] interval: 30s timeout: 15s retries: 50 start_period: 120s restart: unless-stopped promtail: image: promtail-custom:int-dev container_name: promtail volumes: - ./logs:/var/log/lecoffre:ro - ./conf/promtail/promtail.yml:/etc/promtail/config.yml:ro - /var/run/docker.sock:/var/run/docker.sock command: -config.file=/etc/promtail/config.yml networks: btcnet: aliases: - promtail depends_on: loki: condition: service_healthy healthcheck: test: ["CMD", "sh", "-c", "if [ -f /tmp/positions.yaml ]; then echo 'Promtail ready: Log collection service responding'; exit 0; else echo 'Promtail starting: Log collection service not yet ready'; exit 1; fi"] interval: 30s timeout: 10s retries: 50 start_period: 30s restart: unless-stopped # Service de statut des services status-api: build: context: ./web/status dockerfile: Dockerfile.python container_name: status-api ports: - "0.0.0.0:3006:3006" volumes: - ./web/status/api.py:/app/api.py:ro networks: btcnet: aliases: - status-api healthcheck: test: ["CMD", "sh", "-c", "if curl -f http://localhost:3006/api >/dev/null 2>&1; then echo 'Status API ready: Service monitoring API responding'; exit 0; else echo 'Status API starting: Service monitoring API not yet ready'; exit 1; fi"] interval: 30s timeout: 10s retries: 50 start_period: 30s labels: - "com.centurylinklabs.watchtower.enable=true" restart: unless-stopped volumes: bitcoin_data: name: 4nk_node_bitcoin_data blindbit_data: name: 4nk_node_blindbit_data sdk_data: name: 4nk_node_sdk_data sdk_signer_data: name: 4nk_node_sdk_signer_data sdk_storage_data: name: 4nk_node_sdk_storage_data grafana_data: name: 4nk_node_grafana_data loki_data: name: 4nk_node_loki_data networks: btcnet: name: 4nk_node_btcnet driver: bridge ipam: config: - subnet: 172.20.0.0/16