diff --git a/Dockerfile b/Dockerfile index 079e0c5..2f66198 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,45 +1,93 @@ -# 使用Python 3.11作为基础镜像 -FROM python:3.11-slim-bookworm +# syntax=docker/dockerfile:1 -# 设置标签信息 -LABEL maintainer="zhinianboke" -LABEL version="2.2.0" -LABEL description="闲鱼自动回复系统 - 企业级多用户版本,支持自动发货和免拼发货" -LABEL repository="https://github.com/zhinianboke/xianyu-auto-reply" -LABEL license="仅供学习使用,禁止商业用途" -LABEL author="zhinianboke" -LABEL build-date="" -LABEL vcs-ref="" +# Base stage with shared environment configuration +FROM python:3.11-slim-bookworm AS base + +ENV PYTHONUNBUFFERED=1 \ + PYTHONDONTWRITEBYTECODE=1 \ + TZ=Asia/Shanghai \ + DOCKER_ENV=true \ + PLAYWRIGHT_BROWSERS_PATH=/ms-playwright -# 设置工作目录 WORKDIR /app -# 设置环境变量 -ENV PYTHONUNBUFFERED=1 -ENV PYTHONDONTWRITEBYTECODE=1 -ENV TZ=Asia/Shanghai -ENV DOCKER_ENV=true -ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright -# Nuitka编译优化 -ENV CC=gcc -ENV CXX=g++ -ENV NUITKA_CACHE_DIR=/tmp/nuitka-cache +# Builder stage: install build tooling, Python deps and optional binary modules +FROM base AS builder + +ENV CC=gcc \ + CXX=g++ \ + NUITKA_CACHE_DIR=/tmp/nuitka-cache -# 安装系统依赖(包括Playwright浏览器依赖) RUN apt-get update && \ apt-get install -y --no-install-recommends \ - # 基础工具 - nodejs \ - npm \ - tzdata \ - curl \ - ca-certificates \ - # 编译工具(Nuitka需要) build-essential \ gcc \ g++ \ ccache \ patchelf \ + curl \ + ca-certificates \ + && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +RUN python -m venv /opt/venv && \ + /opt/venv/bin/pip install --no-cache-dir --upgrade pip +ENV VIRTUAL_ENV=/opt/venv +ENV PATH="$VIRTUAL_ENV/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin" + +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +COPY . . + +RUN if [ -f "utils/xianyu_slider_stealth.py" ]; then \ + echo "===================================="; \ + echo "检测到 xianyu_slider_stealth.py"; \ + echo "开始编译为二进制模块..."; \ + echo "===================================="; \ + pip install --no-cache-dir nuitka ordered-set zstandard && \ + python build_binary_module.py; \ + BUILD_RESULT=$?; \ + if [ $BUILD_RESULT -eq 0 ]; then \ + echo "===================================="; \ + echo "✓ 二进制模块编译成功"; \ + echo "===================================="; \ + ls -lh utils/xianyu_slider_stealth.* 2>/dev/null || true; \ + else \ + echo "===================================="; \ + echo "✗ 二进制模块编译失败 (错误码: $BUILD_RESULT)"; \ + echo "将继续使用 Python 源代码版本"; \ + echo "===================================="; \ + fi; \ + pip uninstall -y nuitka ordered-set zstandard >/dev/null 2>&1 || true; \ + rm -rf /tmp/nuitka-cache utils/xianyu_slider_stealth.build utils/xianyu_slider_stealth.dist; \ + else \ + echo "===================================="; \ + echo "未检测到 xianyu_slider_stealth.py"; \ + echo "跳过二进制编译"; \ + echo "===================================="; \ + fi + +# Runtime stage: only keep what is needed to run the app +FROM base AS runtime + +LABEL maintainer="zhinianboke" \ + version="2.2.0" \ + description="闲鱼自动回复系统 - 企业级多用户版本,支持自动发货和免拼发货" \ + repository="https://github.com/zhinianboke/xianyu-auto-reply" \ + license="仅供学习使用,禁止商业用途" \ + author="zhinianboke" \ + build-date="" \ + vcs-ref="" + +ENV NODE_PATH=/usr/lib/node_modules + +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + nodejs \ + npm \ + tzdata \ + curl \ + ca-certificates \ # 图像处理依赖 libjpeg-dev \ libpng-dev \ @@ -77,78 +125,30 @@ RUN apt-get update && \ # OpenCV运行时依赖 libgl1 \ libglib2.0-0 \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* \ - && rm -rf /tmp/* \ - && rm -rf /var/tmp/* + && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* -# 设置时区 RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone -# 验证Node.js安装并设置环境变量 RUN node --version && npm --version -ENV NODE_PATH=/usr/lib/node_modules -# 复制requirements.txt并安装Python依赖 -COPY requirements.txt . -RUN pip install --no-cache-dir --upgrade pip && \ - pip install --no-cache-dir -r requirements.txt +COPY --from=builder /opt/venv /opt/venv +COPY --from=builder /app /app +ENV VIRTUAL_ENV=/opt/venv +ENV PATH="$VIRTUAL_ENV/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin" -# 复制项目文件 -COPY . . - -# 条件执行:如果 xianyu_slider_stealth.py 存在,则编译为二进制模块 -RUN if [ -f "utils/xianyu_slider_stealth.py" ]; then \ - echo "===================================="; \ - echo "检测到 xianyu_slider_stealth.py"; \ - echo "开始编译为二进制模块..."; \ - echo "===================================="; \ - pip install --no-cache-dir nuitka ordered-set zstandard && \ - python build_binary_module.py; \ - BUILD_RESULT=$?; \ - if [ $BUILD_RESULT -eq 0 ]; then \ - echo "===================================="; \ - echo "✓ 二进制模块编译成功"; \ - echo "===================================="; \ - ls -lh utils/xianyu_slider_stealth.* 2>/dev/null || true; \ - else \ - echo "===================================="; \ - echo "✗ 二进制模块编译失败 (错误码: $BUILD_RESULT)"; \ - echo "将继续使用 Python 源代码版本"; \ - echo "===================================="; \ - fi; \ - rm -rf /tmp/nuitka-cache utils/xianyu_slider_stealth.build utils/xianyu_slider_stealth.dist; \ - else \ - echo "===================================="; \ - echo "未检测到 xianyu_slider_stealth.py"; \ - echo "跳过二进制编译"; \ - echo "===================================="; \ - fi - -# 安装Playwright浏览器(必须在复制项目文件之后) RUN playwright install chromium && \ playwright install-deps chromium -# 创建必要的目录并设置权限 RUN mkdir -p /app/logs /app/data /app/backups /app/static/uploads/images && \ chmod 777 /app/logs /app/data /app/backups /app/static/uploads /app/static/uploads/images -# 配置系统限制,防止core文件生成 RUN echo "ulimit -c 0" >> /etc/profile -# 注意: 为了简化权限问题,使用root用户运行 -# 在生产环境中,建议配置适当的用户映射 - -# 暴露端口 EXPOSE 8080 -# 健康检查 HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD curl -f http://localhost:8080/health || exit 1 -# 复制启动脚本 -COPY entrypoint.sh /app/entrypoint.sh RUN chmod +x /app/entrypoint.sh -# 启动命令 -CMD ["/app/entrypoint.sh"] \ No newline at end of file +CMD ["/app/entrypoint.sh"] diff --git a/Dockerfile-cn b/Dockerfile-cn index 25dad86..58e1d89 100644 --- a/Dockerfile-cn +++ b/Dockerfile-cn @@ -1,33 +1,97 @@ -# 使用Python 3.11作为基础镜像 -FROM python:3.11-slim-bookworm +# syntax=docker/dockerfile:1 -# 设置标签信息 -LABEL maintainer="zhinianboke" -LABEL version="2.1.0" -LABEL description="闲鱼自动回复系统 - 企业级多用户版本,支持自动发货和免拼发货" -LABEL repository="https://github.com/zhinianboke/xianyu-auto-reply" -LABEL license="仅供学习使用,禁止商业用途" -LABEL author="zhinianboke" -LABEL build-date="" -LABEL vcs-ref="" +# Base stage with shared env config and mirror switch +FROM python:3.11-slim-bookworm AS base + +ENV PYTHONUNBUFFERED=1 \ + PYTHONDONTWRITEBYTECODE=1 \ + TZ=Asia/Shanghai \ + DOCKER_ENV=true \ + PLAYWRIGHT_BROWSERS_PATH=/ms-playwright -# 设置工作目录 WORKDIR /app -# 设置环境变量 -ENV PYTHONUNBUFFERED=1 -ENV PYTHONDONTWRITEBYTECODE=1 -ENV TZ=Asia/Shanghai -ENV DOCKER_ENV=true -ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright +# 更换中科大源(兼容不同基础镜像) +RUN if [ -f /etc/apt/sources.list.d/debian.sources ]; then \ + sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list.d/debian.sources; \ + fi && \ + if [ -f /etc/apt/sources.list ]; then \ + sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list; \ + fi -#更换中科大源 -RUN sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list.d/debian.sources +# Builder stage +FROM base AS builder + +ENV CC=gcc \ + CXX=g++ \ + NUITKA_CACHE_DIR=/tmp/nuitka-cache \ + PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple + +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + build-essential \ + gcc \ + g++ \ + ccache \ + patchelf \ + curl \ + ca-certificates \ + && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +RUN python -m venv /opt/venv && \ + /opt/venv/bin/pip install --no-cache-dir --upgrade pip +ENV VIRTUAL_ENV=/opt/venv +ENV PATH="$VIRTUAL_ENV/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin" + +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +COPY . . + +RUN if [ -f "utils/xianyu_slider_stealth.py" ]; then \ + echo "===================================="; \ + echo "检测到 xianyu_slider_stealth.py"; \ + echo "开始编译为二进制模块..."; \ + echo "===================================="; \ + pip install --no-cache-dir nuitka ordered-set zstandard && \ + python build_binary_module.py; \ + BUILD_RESULT=$?; \ + if [ $BUILD_RESULT -eq 0 ]; then \ + echo "===================================="; \ + echo "✓ 二进制模块编译成功"; \ + echo "===================================="; \ + ls -lh utils/xianyu_slider_stealth.* 2>/dev/null || true; \ + else \ + echo "===================================="; \ + echo "✗ 二进制模块编译失败 (错误码: $BUILD_RESULT)"; \ + echo "将继续使用 Python 源代码版本"; \ + echo "===================================="; \ + fi; \ + pip uninstall -y nuitka ordered-set zstandard >/dev/null 2>&1 || true; \ + rm -rf /tmp/nuitka-cache utils/xianyu_slider_stealth.build utils/xianyu_slider_stealth.dist; \ + else \ + echo "===================================="; \ + echo "未检测到 xianyu_slider_stealth.py"; \ + echo "跳过二进制编译"; \ + echo "===================================="; \ + fi + +# Runtime stage +FROM base AS runtime + +LABEL maintainer="zhinianboke" \ + version="2.1.0" \ + description="闲鱼自动回复系统 - 企业级多用户版本,支持自动发货和免拼发货" \ + repository="https://github.com/zhinianboke/xianyu-auto-reply" \ + license="仅供学习使用,禁止商业用途" \ + author="zhinianboke" \ + build-date="" \ + vcs-ref="" + +ENV NODE_PATH=/usr/lib/node_modules -# 安装系统依赖(包括Playwright浏览器依赖) RUN apt-get update && \ apt-get install -y --no-install-recommends \ - # 基础工具 nodejs \ npm \ tzdata \ @@ -70,50 +134,30 @@ RUN apt-get update && \ # OpenCV运行时依赖 libgl1 \ libglib2.0-0 \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* \ - && rm -rf /tmp/* \ - && rm -rf /var/tmp/* + && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* -# 设置时区 RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone -# 验证Node.js安装并设置环境变量 RUN node --version && npm --version -ENV NODE_PATH=/usr/lib/node_modules -# 复制requirements.txt并安装Python依赖 -COPY requirements.txt . -RUN pip install --no-cache-dir --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple&& \ - pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple +COPY --from=builder /opt/venv /opt/venv +COPY --from=builder /app /app +ENV VIRTUAL_ENV=/opt/venv +ENV PATH="$VIRTUAL_ENV/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin" -# 复制项目文件 -COPY . . - -# 安装Playwright浏览器(必须在复制项目文件之后) RUN playwright install chromium && \ playwright install-deps chromium -# 创建必要的目录并设置权限 RUN mkdir -p /app/logs /app/data /app/backups /app/static/uploads/images && \ chmod 777 /app/logs /app/data /app/backups /app/static/uploads /app/static/uploads/images -# 配置系统限制,防止core文件生成 RUN echo "ulimit -c 0" >> /etc/profile -# 注意: 为了简化权限问题,使用root用户运行 -# 在生产环境中,建议配置适当的用户映射 - -# 暴露端口 EXPOSE 8080 -# 健康检查 HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD curl -f http://localhost:8080/health || exit 1 -# 复制启动脚本 -COPY entrypoint.sh /app/entrypoint.sh RUN chmod +x /app/entrypoint.sh -# 启动命令 CMD ["/app/entrypoint.sh"]