Dockerfile 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. # 第一阶段:构建前端应用
  2. FROM docker.1ms.run/node:22-alpine3.21 AS frontend-builder
  3. # 设置工作目录
  4. WORKDIR /app/frontend
  5. # 设置npm镜像源为阿里源
  6. RUN npm config set registry https://registry.npmmirror.com
  7. # 创建.npmrc文件确保使用正确的镜像源
  8. RUN echo "registry=https://registry.npmmirror.com" > .npmrc
  9. # 先复制package.json和package-lock.json
  10. COPY frontend/package.json frontend/package-lock.json* ./
  11. # 安装依赖时使用更好的缓存策略和更少的日志输出
  12. RUN npm ci --legacy-peer-deps --no-fund --no-audit --quiet
  13. # 复制所有前端文件(这行之后的代码变更会重新触发构建)
  14. COPY frontend/ .
  15. # 显示文件结构
  16. RUN echo "=== 文件结构检查 ===" && ls -la && ls -la public/
  17. # 构建前端应用
  18. RUN echo "=== 开始构建前端应用 ===" && npm run build
  19. # 检查构建产物
  20. RUN echo "=== 构建产物检查 ===" && ls -la dist/ && \
  21. if [ -z "$(ls -A dist)" ]; then \
  22. echo "错误: dist目录为空" && exit 1; \
  23. else \
  24. echo "构建成功,dist目录不为空"; \
  25. fi
  26. # 第二阶段:构建Python后端
  27. FROM docker.1ms.run/python:3.9-slim
  28. # 设置工作目录
  29. WORKDIR /app/backend
  30. # 设置pip镜像源为阿里源
  31. RUN pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/
  32. # 强制使用阿里源,完全清除所有其他源的引用
  33. # 删除所有可能的源文件,使用更彻底的方式
  34. RUN rm -f /etc/apt/sources.list /etc/apt/sources.list.d/*.list && \
  35. mkdir -p /etc/apt/sources.list.d && \
  36. rm -f /etc/apt/sources.list.d/*.list
  37. # 只创建包含阿里源的源文件,使用安全的写法确保文件存在
  38. RUN echo 'deb http://mirrors.aliyun.com/debian/ trixie main contrib non-free' > /etc/apt/sources.list && \
  39. echo 'deb-src http://mirrors.aliyun.com/debian/ trixie main contrib non-free' >> /etc/apt/sources.list && \
  40. echo 'deb http://mirrors.aliyun.com/debian/ trixie-updates main contrib non-free' >> /etc/apt/sources.list && \
  41. echo 'deb-src http://mirrors.aliyun.com/debian/ trixie-updates main contrib non-free' >> /etc/apt/sources.list && \
  42. echo 'deb http://mirrors.aliyun.com/debian-security/ trixie-security main contrib non-free' >> /etc/apt/sources.list && \
  43. echo 'deb-src http://mirrors.aliyun.com/debian-security/ trixie-security main contrib non-free' >> /etc/apt/sources.list
  44. # 验证源文件内容
  45. RUN echo "=== 验证源文件内容 ===" && cat /etc/apt/sources.list
  46. # 确保没有其他源文件存在
  47. RUN echo "=== 检查是否存在其他源文件 ===" && ls -la /etc/apt/ /etc/apt/sources.list.d/ 2>/dev/null || echo "No sources.list.d directory"
  48. # 使用Python内置的http客户端进行健康检查,避免额外依赖
  49. # 清理并重建apt缓存,仅使用清华源,添加更多参数确保不使用其他源
  50. RUN echo "=== 清理并重建apt缓存 ===" && \
  51. rm -rf /var/lib/apt/lists/* && \
  52. apt-get clean && \
  53. # 设置严格的apt配置,确保只使用指定的源
  54. apt-config dump && \
  55. # 执行update并严格只使用清华源
  56. apt-get update -o Acquire::ForceIPv4=true -o Acquire::AllowInsecureRepositories=true -o Dir::Etc::sourcelist="/etc/apt/sources.list" -o Dir::Etc::sourceparts="" -o APT::Get::List-Cleanup="0" && \
  57. # 安装必要的依赖
  58. apt-get install -y --no-install-recommends \
  59. gcc \
  60. python3-dev \
  61. libffi-dev \
  62. && rm -rf /var/lib/apt/lists/*
  63. # 复制Python依赖文件
  64. COPY backend/requirements.txt .
  65. # 安装Python依赖
  66. RUN pip install --no-cache-dir -r requirements.txt
  67. # 创建静态文件目录
  68. RUN mkdir -p /app/backend/static
  69. # 复制前端构建产物到后端静态文件夹
  70. COPY --from=frontend-builder /app/frontend/dist /app/backend/static
  71. # 使用更灵活的方式修改index.html中的脚本引用路径,不再硬编码文件名
  72. RUN echo "=== 修改index.html脚本引用 ===" && \
  73. # 查找实际的main.js文件
  74. MAIN_JS_FILE=$(find /app/backend/static/assets -name "main-*.js" | head -1) && \
  75. MAIN_JS_BASENAME=$(basename "$MAIN_JS_FILE") && \
  76. echo "找到main.js文件: $MAIN_JS_BASENAME" && \
  77. # 替换index.html中的引用路径
  78. sed -i "s|/src/main.js|/assets/$MAIN_JS_BASENAME|g" /app/backend/static/index.html
  79. # 检查静态文件目录和修改后的index.html
  80. RUN echo "=== 静态文件目录检查 ===" && ls -la /app/backend/static/ && ls -la /app/backend/static/assets/ && echo "=== index.html内容 ===" && cat /app/backend/static/index.html
  81. # 复制后端源代码
  82. COPY backend/ .
  83. # 设置环境变量
  84. ENV FLASK_APP=app.py
  85. ENV FLASK_ENV=production
  86. ENV TZ=Asia/Shanghai
  87. # 添加健康检查(使用Python内置的http.client模块)
  88. HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
  89. CMD python -c "import http.client; conn = http.client.HTTPConnection('localhost', 5001); conn.request('GET', '/api/health'); res = conn.getresponse(); exit(0 if res.status < 400 else 1)"
  90. # 使用非root用户运行应用以提高安全性
  91. RUN groupadd -r appuser && useradd -r -g appuser appuser
  92. RUN chown -R appuser:appuser /app/backend
  93. USER appuser
  94. # 暴露应用端口
  95. EXPOSE 5001
  96. # 简化启动命令 - 确保端口统一为5001
  97. CMD ["python", "-m", "flask", "run", "--host=0.0.0.0", "--port=5001"]