diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..506cb6f --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,96 @@ +services: + mysql: + image: mysql:8.0 + container_name: tmflow-mysql + restart: unless-stopped + environment: + MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-root_password_change_me} + MYSQL_DATABASE: ${DB_NAME:-tiemeasureflow} + MYSQL_USER: ${DB_USER:-tmflow} + MYSQL_PASSWORD: ${DB_PASSWORD:-change_me_in_production} + 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: ./server + dockerfile: Dockerfile + container_name: tmflow-server + restart: unless-stopped + env_file: + - .env + environment: + DB_HOST: mysql + UPLOAD_DIR: uploads + volumes: + - upload_data:/app/uploads + depends_on: + mysql: + condition: service_healthy + 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 + + client: + build: + context: ./client + dockerfile: Dockerfile + container_name: tmflow-client + restart: unless-stopped + env_file: + - .env + environment: + API_SERVER_URL: http://server:8000 + depends_on: + - server + 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: root_default