services: backend: build: context: . dockerfile: backend/Dockerfile args: PYTHON_BASE_IMAGE: ${PYTHON_BASE_IMAGE:-python:3.12-slim} PIP_INDEX_URL: ${PIP_INDEX_URL:-https://pypi.org/simple} PIP_TRUSTED_HOST: ${PIP_TRUSTED_HOST:-} image: dashboard-nanobot/backend:${BACKEND_IMAGE_TAG:-latest} container_name: dashboard-nanobot-backend restart: unless-stopped environment: APP_HOST: 0.0.0.0 APP_PORT: 8000 APP_RELOAD: "false" DATABASE_ECHO: "false" DATA_ROOT: ${HOST_DATA_ROOT} BOTS_WORKSPACE_ROOT: ${HOST_BOTS_WORKSPACE_ROOT} DATABASE_URL: ${DATABASE_URL:-} volumes: - /var/run/docker.sock:/var/run/docker.sock - ${HOST_DATA_ROOT}:${HOST_DATA_ROOT} - ${HOST_BOTS_WORKSPACE_ROOT}:${HOST_BOTS_WORKSPACE_ROOT} expose: - "8000" healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/api/health', timeout=3).read()"] interval: 15s timeout: 5s retries: 5 start_period: 20s logging: driver: json-file options: max-size: "20m" max-file: "3" networks: - nanobot_net nginx: build: context: ./frontend dockerfile: Dockerfile args: NODE_BASE_IMAGE: ${NODE_BASE_IMAGE:-node:20-alpine} NGINX_BASE_IMAGE: ${NGINX_BASE_IMAGE:-nginx:alpine} NPM_REGISTRY: ${NPM_REGISTRY:-https://registry.npmjs.org/} VITE_API_BASE: /api VITE_WS_BASE: /ws/monitor image: dashboard-nanobot/nginx:${FRONTEND_IMAGE_TAG:-latest} container_name: dashboard-nanobot-nginx restart: unless-stopped depends_on: backend: condition: service_healthy ports: - "${NGINX_PORT}:80" healthcheck: test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1/"] interval: 15s timeout: 5s retries: 5 start_period: 10s logging: driver: json-file options: max-size: "20m" max-file: "3" networks: - nanobot_net networks: nanobot_net: driver: bridge