services: postgres: image: timescale/timescaledb:latest-pg16 container_name: datanumbers-postgres restart: unless-stopped ports: - "${POSTGRES_PORT:-5432}:5432" environment: POSTGRES_USER: ${POSTGRES_USER:-numbers} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-numbers} POSTGRES_DB: ${POSTGRES_DB:-data_numbers_iot} volumes: - postgres-data:/var/lib/postgresql/data - ./infra/postgres/init:/docker-entrypoint-initdb.d:ro healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-numbers} -d ${POSTGRES_DB:-data_numbers_iot}"] interval: 5s timeout: 5s retries: 10 networks: - data-numbers-network redis: image: redis:7-alpine container_name: datanumbers-redis restart: unless-stopped ports: - "${REDIS_PORT:-6380}:6379" environment: TZ: ${TZ:-America/Sao_Paulo} healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 5s retries: 10 networks: - data-numbers-network nats: image: nats:2.10-alpine container_name: datanumbers-nats restart: unless-stopped command: ["-js", "-sd", "/data", "-m", "8222"] ports: - "${NATS_CLIENT_PORT:-4222}:4222" - "${NATS_MONITOR_PORT:-8222}:8222" volumes: - nats-data:/data healthcheck: test: ["CMD", "wget", "-q", "-O", "-", "http://localhost:8222/healthz"] interval: 5s timeout: 5s retries: 10 networks: - data-numbers-network nats-ui: image: klinux/nats-ui:latest platform: linux/amd64 container_name: datanumbers-nats-ui restart: unless-stopped depends_on: nats: condition: service_healthy ports: - "${NATS_UI_PORT:-3131}:8080" environment: NATS_URL: nats://nats:4222 BASE_URL: "http://localhost:${NATS_UI_PORT:-3131}" PORT: 8080 ADMIN_USER: ${NATS_UI_ADMIN_USER:-admin} ADMIN_PASS: ${NATS_UI_ADMIN_PASS:-admin123} JWT_SECRET: ${NATS_UI_JWT_SECRET:-change-me-local} healthcheck: test: ["CMD", "wget", "-q", "-O", "-", "http://localhost:8080/healthz"] interval: 10s timeout: 5s retries: 10 networks: - data-numbers-network emqx: image: emqx:5.3.0 container_name: datanumbers-emqx restart: unless-stopped environment: EMQX_NODE_NAME: emqx@node1.emqx.io EMQX_CLUSTER__DISCOVERY_STRATEGY: static EMQX_CLUSTER__STATIC__SEEDS: "[emqx@node1.emqx.io]" EMQX_ALLOW_ANONYMOUS: "true" EMQX_AUTHORIZATION__NO_MATCH: "allow" EMQX_AUTHORIZATION__CACHE__ENABLE: "false" healthcheck: test: ["CMD", "/opt/emqx/bin/emqx", "ctl", "status"] interval: 5s timeout: 25s retries: 10 ports: - "${EMQX_MQTT_PORT:-1883}:1883" - "${EMQX_WS_PORT:-8083}:8083" - "${EMQX_WSS_PORT:-8084}:8084" - "${EMQX_MQTTS_PORT:-8883}:8883" - "${EMQX_DASHBOARD_PORT:-18083}:18083" volumes: - emqx-data:/opt/emqx/data networks: data-numbers-network: aliases: - node1.emqx.io auth-api: container_name: datanumbers-auth-api build: context: . dockerfile: Dockerfile restart: unless-stopped depends_on: postgres: condition: service_healthy redis: condition: service_healthy ports: - "${AUTH_API_PORT:-3000}:3000" volumes: - certs-data:/auth/certs environment: DB_DNS: "host=postgres user=${POSTGRES_USER:-numbers} password=${POSTGRES_PASSWORD:-numbers} dbname=${POSTGRES_DB:-data_numbers_iot} port=5432 sslmode=disable TimeZone=${TZ:-America/Sao_Paulo}" HOST_REDIS: redis PORT_REDIS: 6379 PASSWORD_REDIS: ${REDIS_PASSWORD:-} JWT_PRIVATE_KEY_PATH: /auth/certs/private_key.pem JWT_PUBLIC_KEY_PATH: /auth/certs/public_key.pem CORS_ALLOWED_ORIGINS: ${CORS_ALLOWED_ORIGINS:-http://localhost:3030,http://localhost:8080} healthcheck: # /auth/verify-token sem header devolve 401 — usamos isso como sinal de # que o processo está vivo e respondendo HTTP. test: ["CMD-SHELL", "wget -qO- --server-response http://localhost:3000/auth/verify-token 2>&1 | grep -q 'HTTP/1.1 401'"] interval: 5s timeout: 5s retries: 10 networks: - data-numbers-network gateway-emqx: container_name: datanumbers-gateway-emqx build: context: ./gateway-emqx dockerfile: Dockerfile restart: unless-stopped depends_on: postgres: condition: service_healthy nats: condition: service_healthy emqx: condition: service_healthy auth-api: condition: service_healthy ports: - "${GATEWAY_HTTP_PORT:-3002}:3002" - "${GATEWAY_GRPC_PORT:-5051}:5051" volumes: - certs-data:/app/certs:ro environment: DNS_DATABASE: "postgres://${POSTGRES_USER:-numbers}:${POSTGRES_PASSWORD:-numbers}@postgres:5432/${POSTGRES_DB:-data_numbers_iot}?sslmode=disable" HOST_EMQX: emqx PORT_EMQX: 1883 ROUTER_PORT: 3002 NATS_URL: nats://nats:4222 WS_ALLOWED_ORIGINS: ${WS_ALLOWED_ORIGINS:-http://localhost:3030,http://localhost:8080} JWT_PUBLIC_KEY_PATH: /app/certs/public_key.pem networks: - data-numbers-network device-manager: container_name: datanumbers-device-manager build: context: ./device-manager dockerfile: Dockerfile restart: unless-stopped depends_on: postgres: condition: service_healthy nats: condition: service_healthy auth-api: condition: service_healthy ports: - "${DEVICE_MANAGER_PORT:-3001}:3001" volumes: - certs-data:/app/certs:ro environment: DATABASE_URL: "postgres://${POSTGRES_USER:-numbers}:${POSTGRES_PASSWORD:-numbers}@postgres:5432/${POSTGRES_DB:-data_numbers_iot}?sslmode=disable" NATS_URL: nats://nats:4222 HTTP_PORT: 3001 JWT_PUBLIC_KEY_PATH: /app/certs/public_key.pem networks: - data-numbers-network data-management: container_name: datanumbers-data-management build: context: ./data-management dockerfile: Dockerfile restart: unless-stopped depends_on: postgres: condition: service_healthy nats: condition: service_healthy auth-api: condition: service_healthy ports: - "${DATA_MANAGEMENT_PORT:-3003}:3003" volumes: - certs-data:/app/certs:ro environment: DATABASE_URL: "postgres://${POSTGRES_USER:-numbers}:${POSTGRES_PASSWORD:-numbers}@postgres:5432/${POSTGRES_DB:-data_numbers_iot}?sslmode=disable" NATS_URL: nats://nats:4222 NATS_TELEMETRY_SUBJECT: iot.telemetry.received HTTP_PORT: 3003 JWT_PUBLIC_KEY_PATH: /app/certs/public_key.pem networks: - data-numbers-network rule-engine: container_name: datanumbers-rule-engine build: context: ./rule-engine dockerfile: Dockerfile restart: unless-stopped depends_on: postgres: condition: service_healthy nats: condition: service_healthy auth-api: condition: service_healthy ports: - "${RULE_ENGINE_PORT:-3004}:3004" volumes: - certs-data:/app/certs:ro environment: DATABASE_URL: "postgres://${POSTGRES_USER:-numbers}:${POSTGRES_PASSWORD:-numbers}@postgres:5432/${POSTGRES_DB:-data_numbers_iot}?sslmode=disable" NATS_URL: nats://nats:4222 HTTP_PORT: 3004 JWT_PUBLIC_KEY_PATH: /app/certs/public_key.pem networks: - data-numbers-network calendar-tool: container_name: datanumbers-calendar-tool build: context: ./tools/calendar-tool dockerfile: Dockerfile restart: unless-stopped depends_on: postgres: condition: service_healthy nats: condition: service_healthy auth-api: condition: service_healthy ports: - "${CALENDAR_TOOL_PORT:-3005}:8080" volumes: - certs-data:/app/certs:ro environment: DATABASE_URL: "postgres://${POSTGRES_USER:-numbers}:${POSTGRES_PASSWORD:-numbers}@postgres:5432/${POSTGRES_DB:-data_numbers_iot}?sslmode=disable" NATS_URL: nats://nats:4222 PORT: 8080 JWT_PUBLIC_KEY_PATH: /app/certs/public_key.pem GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID:-} GOOGLE_CLIENT_SECRET: ${GOOGLE_CLIENT_SECRET:-} GOOGLE_REDIRECT_URL: ${GOOGLE_REDIRECT_URL:-http://localhost:8080/api/calendar/auth/google/callback} FRONTEND_URL: ${FRONTEND_URL:-http://localhost:3030} networks: - data-numbers-network nginx: image: nginx:alpine container_name: datanumbers-api-gateway restart: unless-stopped ports: - "${API_GATEWAY_PORT:-8080}:80" volumes: - ./infra/nginx/nginx.conf:/etc/nginx/nginx.conf:ro depends_on: - auth-api - device-manager - gateway-emqx - data-management - rule-engine - calendar-tool networks: - data-numbers-network web: container_name: datanumbers-web build: context: ./datanumbers-iot-web dockerfile: Dockerfile restart: unless-stopped ports: - "${WEB_PORT:-3030}:80" networks: - data-numbers-network volumes: postgres-data: nats-data: emqx-data: certs-data: networks: data-numbers-network: driver: bridge