services: mysql: image: mysql:8.0 container_name: tmflow-mysql restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:?manca DB_ROOT_PASSWORD} MYSQL_DATABASE: ${DB_NAME:-tiemeasureflow} MYSQL_USER: ${DB_USER:-tmflow} MYSQL_PASSWORD: ${DB_PASSWORD:?manca DB_PASSWORD} volumes: - mysql_data:/var/lib/mysql command: > --authentication-policy=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 10s timeout: 5s retries: 5 networks: - tmflow-net server: build: context: . dockerfile: Dockerfile container_name: tmflow-server restart: unless-stopped env_file: - .env environment: DB_HOST: mysql UPLOAD_DIR: uploads VISION_WORKER_URL: http://vision:8100 SERVER_SECRET_KEY: ${SERVER_SECRET_KEY:?manca SERVER_SECRET_KEY} WEB_CONCURRENCY: ${WEB_CONCURRENCY:-4} TRUSTED_PROXY_COUNT: ${TRUSTED_PROXY_COUNT:-1} volumes: - upload_data:/app/uploads depends_on: mysql: condition: service_healthy healthcheck: test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/api/health', timeout=5)"] interval: 30s timeout: 10s retries: 3 start_period: 20s labels: - "traefik.enable=true" - "traefik.http.routers.tmflow-api.rule=Host(`tieflow.tielogic.xyz`) && (PathPrefix(`/api/`) || PathPrefix(`/uploads/`))" - "traefik.http.routers.tmflow-api.entrypoints=web,websecure" - "traefik.http.routers.tmflow-api.tls=true" - "traefik.http.routers.tmflow-api.tls.certresolver=mytlschallenge" - "traefik.http.routers.tmflow-api.priority=100" - "traefik.http.services.tmflow-api.loadbalancer.server.port=8000" networks: - tmflow-net - traefik-net vision: build: context: . dockerfile: Dockerfile.vision args: VISION_ENGINE_VERSION: ${VISION_ENGINE_VERSION:-} container_name: tmflow-vision restart: unless-stopped healthcheck: test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8100/health', timeout=5)"] interval: 30s timeout: 10s retries: 3 start_period: 20s networks: - tmflow-net client: build: context: . dockerfile: Dockerfile.frontend container_name: tmflow-client restart: unless-stopped env_file: - .env environment: API_SERVER_URL: http://server:8000 CLIENT_SECRET_KEY: ${CLIENT_SECRET_KEY:?manca CLIENT_SECRET_KEY} depends_on: server: condition: service_healthy healthcheck: test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:5000/auth/login', timeout=5)"] interval: 30s timeout: 10s retries: 3 start_period: 20s labels: - "traefik.enable=true" - "traefik.http.routers.tmflow-web.rule=Host(`tieflow.tielogic.xyz`)" - "traefik.http.routers.tmflow-web.entrypoints=web,websecure" - "traefik.http.routers.tmflow-web.tls=true" - "traefik.http.routers.tmflow-web.tls.certresolver=mytlschallenge" - "traefik.http.routers.tmflow-web.priority=10" - "traefik.http.services.tmflow-web.loadbalancer.server.port=5000" - "traefik.http.middlewares.tmflow-headers.headers.SSLRedirect=true" - "traefik.http.middlewares.tmflow-headers.headers.STSSeconds=315360000" - "traefik.http.middlewares.tmflow-headers.headers.browserXSSFilter=true" - "traefik.http.middlewares.tmflow-headers.headers.contentTypeNosniff=true" - "traefik.http.middlewares.tmflow-headers.headers.forceSTSHeader=true" - "traefik.http.middlewares.tmflow-headers.headers.STSIncludeSubdomains=true" - "traefik.http.middlewares.tmflow-headers.headers.STSPreload=true" - "traefik.http.routers.tmflow-web.middlewares=tmflow-headers" networks: - tmflow-net - traefik-net volumes: mysql_data: driver: local upload_data: driver: local networks: tmflow-net: driver: bridge traefik-net: external: true name: traefik