# 使用官方Python 3.9 Alpine作为基础镜像(轻量级) FROM python:3.9-alpine # 设置工作目录 WORKDIR /app # 安装系统依赖 # 添加 yaml-dev 提供编译PyYAML所需的libyaml # 添加 unzip 用于解压 Yacd RUN apk add --no-cache \ curl \ ca-certificates \ tzdata \ tar \ gzip \ python3-dev \ musl-dev \ libffi-dev \ yaml-dev \ unzip \ # 不再需要 py3-yaml # py3-yaml \ # 添加调试工具 file \ libc-utils \ strace # 设置时区为亚洲/上海 ENV TZ=Asia/Shanghai # 创建必要的目录并设置权限(构建阶段就设置好权限) RUN mkdir -p ./clash_core ./subconverter ./data && \ chmod -R 777 ./data && \ chmod -R 777 ./clash_core && \ chmod -R 777 ./subconverter # 下载并安装Clash Meta,保留原始文件名 RUN echo "Downloading Clash Meta..." && \ curl -L -f -o /tmp/clash-meta.gz "https://github.com/MetaCubeX/Clash.Meta/releases/download/v1.16.0/clash.meta-linux-amd64-v1.16.0.gz" && \ echo "Extracting Clash Meta..." && \ gunzip -c /tmp/clash-meta.gz > ./clash_core/clash.meta-linux-amd64 && \ echo "Setting Clash Meta permissions..." && \ chmod +x ./clash_core/clash.meta-linux-amd64 && \ # 确保Linux可执行属性已设置 ls -la ./clash_core/clash.meta-linux-amd64 && \ # 显示文件类型 file ./clash_core/clash.meta-linux-amd64 && \ echo "Verifying Clash Meta exists..." && \ test -f ./clash_core/clash.meta-linux-amd64 && \ echo "Cleaning up Clash Meta download..." && \ rm /tmp/clash-meta.gz # 下载并完整解压subconverter RUN echo "Downloading subconverter..." && \ curl -L -f -o /tmp/subconverter.tar.gz "https://github.com/tindy2013/subconverter/releases/download/v0.7.2/subconverter_linux64.tar.gz" && \ echo "Extracting subconverter archive..." && \ tar -xzf /tmp/subconverter.tar.gz -C ./subconverter --strip-components=1 && \ echo "Setting subconverter permissions..." && \ chmod +x ./subconverter/subconverter && \ # 确保Linux可执行属性已设置 ls -la ./subconverter/subconverter && \ # 显示文件类型 file ./subconverter/subconverter && \ echo "Verifying subconverter exists..." && \ test -f ./subconverter/subconverter && \ echo "Cleaning up subconverter download..." && \ rm /tmp/subconverter.tar.gz # 复制Python依赖列表 COPY requirements.txt ./ # 升级 pip RUN pip install --upgrade pip # 安装Cython(用于编译PyYAML) RUN echo "Installing Cython for PyYAML build..." && \ pip install --no-cache-dir Cython # 安装Python依赖(包括PyYAML,现在应该能成功编译了) RUN echo "Installing Python dependencies..." && \ pip install --no-cache-dir -r requirements.txt # 可选:删除构建依赖以减小镜像体积 RUN apk del python3-dev musl-dev libffi-dev yaml-dev # 下载并准备 Yacd UI 文件 (从 Yacd-meta 的 gh-pages 分支) RUN echo "Downloading Yacd-meta UI (gh-pages branch)..." && \ YACD_DIR=/app/app/static/yacd && \ mkdir -p ${YACD_DIR} && \ # 下载 gh-pages 分支的 zip 压缩包 curl -L -f -o /tmp/yacd-gh-pages.zip "https://github.com/MetaCubeX/Yacd-meta/archive/refs/heads/gh-pages.zip" && \ echo "Extracting Yacd-meta UI (gh-pages)..." && \ # 解压到临时目录 unzip -q /tmp/yacd-gh-pages.zip -d /tmp && \ # 将解压后的 gh-pages 目录下的 *所有内容* 移动到目标位置 # 注意:解压后的文件夹名通常是 {repo_name}-{branch_name},即 Yacd-meta-gh-pages mv /tmp/Yacd-meta-gh-pages/* ${YACD_DIR}/ && \ echo "Cleaning up Yacd-meta download..." && \ rm /tmp/yacd-gh-pages.zip && \ rm -rf /tmp/Yacd-meta-gh-pages # 设置环境变量 ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ FLASK_APP=app.main \ FLASK_ENV=production \ FLASK_PORT=7860 \ CLASH_PROXY_PORT=7890 \ CLASH_API_PORT=9090 \ PORT=7860 # 复制应用代码和静态文件 COPY app/ ./app/ # 复制启动脚本并赋予执行权限 COPY entrypoint.sh ./ RUN chmod +x ./entrypoint.sh # 给脚本和二进制文件执行权限 (重复的chmod可能不需要,但在构建阶段设置更安全) RUN chmod +x ./clash_core/clash.meta-linux-amd64 || true RUN chmod +x ./subconverter/subconverter || true # 暴露端口 EXPOSE $FLASK_PORT $CLASH_PROXY_PORT $CLASH_API_PORT # 使用entrypoint脚本启动应用 ENTRYPOINT ["/app/entrypoint.sh"]