From 38e8ace5ae8d6941817febf99adadc2e18706a22 Mon Sep 17 00:00:00 2001 From: Jeason <1710884619@qq.com> Date: Tue, 17 Mar 2026 10:29:22 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96docker=E5=AE=B9=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/.dockerignore | 8 ++ backend/Dockerfile | 114 ++++++---------------- docker-compose.yml | 211 ++++++++++++----------------------------- frontend/.dockerignore | 5 + frontend/Dockerfile | 29 ++++++ frontend/app.py | 3 +- 6 files changed, 138 insertions(+), 232 deletions(-) create mode 100644 backend/.dockerignore create mode 100644 frontend/.dockerignore create mode 100644 frontend/Dockerfile diff --git a/backend/.dockerignore b/backend/.dockerignore new file mode 100644 index 0000000..5cea748 --- /dev/null +++ b/backend/.dockerignore @@ -0,0 +1,8 @@ +venv/ +__pycache__/ +*.pyc +.pytest_cache/ +.env +.env.local +*.db +tests/ diff --git a/backend/Dockerfile b/backend/Dockerfile index d65a150..448bd2d 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,103 +1,51 @@ -# Base stage for all Python services +# ============================================================ +# Weibo-HotSign Backend Multi-Stage Dockerfile +# 构建目标: auth-service, api-service +# ============================================================ + +# ---- 基础层 ---- FROM python:3.11-slim AS base -# Set working directory WORKDIR /app -# Install common system dependencies for MySQL -RUN apt-get update && apt-get install -y \ - gcc \ - default-libmysqlclient-dev \ +RUN apt-get update && apt-get install -y --no-install-recommends \ + gcc default-libmysqlclient-dev curl \ && rm -rf /var/lib/apt/lists/* -# Copy and install unified requirements COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt -# Create non-root user for security +# 复制共享模块 +COPY shared/ ./shared/ + RUN groupadd -r appuser && useradd -r -g appuser appuser -# --- API Gateway Service Stage --- -FROM base AS api_gateway +# ---- Auth Service ---- +FROM base AS auth-service -# Copy shared module -COPY shared/ ./shared/ +COPY auth_service/ ./auth_service/ -# Copy application code -COPY api_service/app/ ./app/ - -# Switch to non-root user +ENV PYTHONPATH=/app USER appuser +EXPOSE 8001 -# Expose port +HEALTHCHECK --interval=30s --timeout=10s --retries=3 \ + CMD curl -f http://localhost:8001/health || exit 1 + +CMD ["uvicorn", "auth_service.app.main:app", "--host", "0.0.0.0", "--port", "8001"] + + +# ---- API Service ---- +FROM base AS api-service + +COPY api_service/ ./api_service/ + +ENV PYTHONPATH=/app +USER appuser EXPOSE 8000 -# Health check -HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \ +HEALTHCHECK --interval=30s --timeout=10s --retries=3 \ CMD curl -f http://localhost:8000/health || exit 1 -# Start application -CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] - - -# --- Auth Service Stage --- -FROM base AS auth_service - -# Copy shared module -COPY shared/ ./shared/ - -# Copy application code -COPY auth_service/app/ ./app/ - -# Switch to non-root user -USER appuser - -# Expose port -EXPOSE 8000 - -# Health check -HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \ - CMD curl -f http://localhost:8000/health || exit 1 - -# Start application -CMD ["python", "-m", "app.main"] - - -# --- Task Scheduler Service Stage --- -FROM base AS task_scheduler - -# Copy shared module -COPY shared/ ./shared/ - -# Copy application code -COPY task_scheduler/app/ ./app/ - -# Switch to non-root user -USER appuser - -# Start Celery Beat scheduler -CMD ["celery", "-A", "app.celery_app", "beat", "--loglevel=info"] - - -# --- Sign-in Executor Service Stage --- -FROM base AS signin_executor - -# Copy shared module -COPY shared/ ./shared/ - -# Copy application code -COPY signin_executor/app/ ./app/ - -# Switch to non-root user -USER appuser - -# Expose port -EXPOSE 8000 - -# Health check -HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \ - CMD curl -f http://localhost:8000/health || exit 1 - -# Start application -CMD ["python", "-m", "app.main"] +CMD ["uvicorn", "api_service.app.main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/docker-compose.yml b/docker-compose.yml index 1cd75a9..9e826a1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,170 +1,85 @@ version: '3.8' +# ============================================================ +# Weibo-HotSign Docker Compose +# 使用方式: +# 1. 填写下方 x-db-env 中的 MySQL/Redis 密码 +# 2. docker-compose up -d --build +# 3. 访问 http://localhost:5000 +# ============================================================ + +# 共享环境变量(避免重复) +x-db-env: &db-env + DATABASE_URL: "mysql+aiomysql://weibo:123456@host.docker.internal:3306/weibo_hotsign?charset=utf8mb4" + REDIS_URL: "redis://:123456@host.docker.internal:6379/0" + USE_REDIS: "true" + JWT_SECRET_KEY: "change-me-to-a-random-string-in-production" + JWT_ALGORITHM: "HS256" + JWT_EXPIRATION_HOURS: "24" + COOKIE_ENCRYPTION_KEY: "change-me-to-a-32byte-key-prod!" + WX_APPID: "" + WX_SECRET: "" + ENVIRONMENT: "production" + services: - # Redis缓存服务 - redis: - image: redis:7-alpine - container_name: weibo-redis + # 认证服务 (端口 8001) + auth-service: + build: + context: ./backend + dockerfile: Dockerfile + target: auth-service + container_name: weibo-auth + restart: unless-stopped ports: - - "6379:6379" - volumes: - - redis_data:/data + - "8001:8001" + environment: + <<: *db-env + extra_hosts: + - "host.docker.internal:host-gateway" networks: - - weibo-network + - weibo-net - # Nginx反向代理 - nginx: - image: nginx:alpine - container_name: weibo-nginx + # API 服务 (端口 8000) + api-service: + build: + context: ./backend + dockerfile: Dockerfile + target: api-service + container_name: weibo-api + restart: unless-stopped ports: - - "80:80" - - "443:443" - volumes: - - ./nginx/nginx.conf:/etc/nginx/nginx.conf - - ./nginx/ssl:/etc/nginx/ssl + - "8000:8000" + environment: + <<: *db-env + extra_hosts: + - "host.docker.internal:host-gateway" depends_on: - - api-gateway - - frontend + - auth-service networks: - - weibo-network + - weibo-net - # 前端React应用 + # Flask 前端 (端口 5000) frontend: build: context: ./frontend dockerfile: Dockerfile container_name: weibo-frontend + restart: unless-stopped ports: - - "3000:3000" + - "5000:5000" environment: - - REACT_APP_API_BASE_URL=http://localhost/api/v1 + FLASK_ENV: "production" + FLASK_DEBUG: "False" + SECRET_KEY: "change-me-flask-secret-key" + API_BASE_URL: "http://api-service:8000" + AUTH_BASE_URL: "http://auth-service:8001" + SESSION_TYPE: "filesystem" depends_on: - - api-gateway + - api-service + - auth-service networks: - - weibo-network - - # API网关和主API服务 - api-gateway: - build: - context: ./backend - dockerfile: Dockerfile - target: api_gateway - container_name: weibo-api-gateway - ports: - - "8000:8000" - environment: - - DATABASE_URL=mysql+aiomysql://weibo:123456789@XX.XX.XX.XX/weibo - - REDIS_URL=redis://redis:6379 - - JWT_SECRET_KEY=your-super-secret-jwt-key-here - - ENVIRONMENT=development - depends_on: - - redis - networks: - - weibo-network - - # 认证服务 - auth-service: - build: - context: ./backend - dockerfile: Dockerfile - target: auth_service - container_name: weibo-auth-service - ports: - - "8001:8000" - environment: - - DATABASE_URL=mysql+aiomysql://weibo:123456789@XX.XX.XX.XX/weibo - - JWT_SECRET_KEY=your-super-secret-jwt-key-here - networks: - - weibo-network - - # 任务调度服务 - task-scheduler: - build: - context: ./backend - dockerfile: Dockerfile - target: task_scheduler - container_name: weibo-task-scheduler - environment: - - DATABASE_URL=mysql+aiomysql://weibo:123456789@XX.XX.XX.XX/weibo - - REDIS_URL=redis://redis:6379 - depends_on: - - redis - networks: - - weibo-network - - # 签到执行Worker - signin-executor: - build: - context: ./backend - dockerfile: Dockerfile - target: signin_executor - container_name: weibo-signin-executor - environment: - - DATABASE_URL=mysql+aiomysql://weibo:123456789@XX.XX.XX.XX/weibo - - REDIS_URL=redis://redis:6379 - - PROXY_POOL_URL=http://proxy-pool:8080 - - BROWSER_AUTOMATION_URL=http://browser-automation:3001 - depends_on: - - redis - networks: - - weibo-network - - # 通知中心服务 - notification-hub: - build: - context: ./backend/notification_hub - dockerfile: Dockerfile - container_name: weibo-notification-hub - ports: - - "8002:8000" - environment: - - REDIS_URL=redis://redis:6379 - depends_on: - - redis - networks: - - weibo-network - - # 浏览器自动化服务 - browser-automation: - build: - context: ./backend/browser_automation_service - dockerfile: Dockerfile - container_name: weibo-browser-automation - ports: - - "3001:3000" - environment: - - PLAYWRIGHT_BROWSERS_PATH=/app/browsers - volumes: - - browser_data:/app/browsers - networks: - - weibo-network - - # 代理池管理器 - proxy-pool: - build: - context: ./elk-stack/proxy_pool - dockerfile: Dockerfile - container_name: weibo-proxy-pool - ports: - - "8080:8080" - networks: - - weibo-network - - # 浏览器指纹生成器 - fingerprint-generator: - build: - context: ./browser_fingerprint_generator - dockerfile: Dockerfile - container_name: weibo-fingerprint-generator - ports: - - "8081:8080" - networks: - - weibo-network - -volumes: - redis_data: - browser_data: + - weibo-net networks: - weibo-network: + weibo-net: driver: bridge diff --git a/frontend/.dockerignore b/frontend/.dockerignore new file mode 100644 index 0000000..bc9db2f --- /dev/null +++ b/frontend/.dockerignore @@ -0,0 +1,5 @@ +venv/ +__pycache__/ +*.pyc +flask_session/ +.env diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 0000000..1648394 --- /dev/null +++ b/frontend/Dockerfile @@ -0,0 +1,29 @@ +# ============================================================ +# Weibo-HotSign Frontend Dockerfile (Flask) +# ============================================================ + +FROM python:3.11-slim + +WORKDIR /app + +RUN apt-get update && apt-get install -y --no-install-recommends curl \ + && rm -rf /var/lib/apt/lists/* + +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +COPY . . + +# 创建 flask_session 目录 +RUN mkdir -p flask_session + +RUN groupadd -r appuser && useradd -r -g appuser appuser \ + && chown -R appuser:appuser /app +USER appuser + +EXPOSE 5000 + +HEALTHCHECK --interval=30s --timeout=10s --retries=3 \ + CMD curl -f http://localhost:5000/ || exit 1 + +CMD ["python", "app.py"] diff --git a/frontend/app.py b/frontend/app.py index 5918e0b..0c85473 100644 --- a/frontend/app.py +++ b/frontend/app.py @@ -911,5 +911,6 @@ def server_error(error): return render_template('500.html'), 500 if __name__ == '__main__': + debug_mode = os.getenv('FLASK_DEBUG', 'True').lower() in ('true', '1', 'yes') # use_reloader=False 避免 Windows 终端 QuickEdit 模式导致进程挂起 - app.run(debug=True, port=5000, use_reloader=False) + app.run(host='0.0.0.0', debug=debug_mode, port=5000, use_reloader=False)