# HuggingFace Spaces 终极修复版 - 解决 echo 多行问题 FROM python:3.11-slim # 避免交互式提示 ENV DEBIAN_FRONTEND=noninteractive ENV TZ=Asia/Shanghai ENV PYTHONUNBUFFERED=1 # 设置工作目录 WORKDIR /app # 安装基础依赖 RUN apt-get update && apt-get install -y \ curl \ wget \ git \ ca-certificates \ gnupg \ lsb-release \ build-essential \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* # Node.js 22 安装 - 解决符号链接问题 RUN NODE_VERSION=22.11.0 \ && curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz" \ -o node.tar.xz \ && tar -xJf node.tar.xz -C /usr/local --strip-components=1 \ && rm node.tar.xz \ && printf "Node.js %s 安装完成\n系统自带 node: %s\n安装的 node: %s\n" \ "${NODE_VERSION}" "$(which node 2>/dev/null || echo "未找到")" \ && echo 'export PATH="/usr/local/bin:$PATH"' >> /etc/bash.bashrc \ && echo 'export PATH="/usr/local/bin:$PATH"' >> /root/.bashrc \ && ENV PATH="/usr/local/bin:$PATH" # 升级 pip 到最新版本 RUN pip install --no-cache-dir --upgrade pip setuptools wheel # 创建启动脚本 - 使用 printf 解决多行问题 RUN printf "#!/bin/bash\n\ set -e\n\ \n\ echo \"正在下载 airs_protocol 代码...\"\n\ \n\ # 克隆 airs_protocol 仓库到主目录\n\ if [ -d \"airs_protocol\" ]; then\n\ echo \"清理旧代码...\"\n\ rm -rf \"airs_protocol\"\n\ fi\n\ \n\ git clone -b master https://gitee.com/tanbushi/airs-protocol.git temp_airs\n\ \n\ # 只复制 airs_protocol 子目录的内容到主目录\n\ if [ -d \"temp_airs/airs_protocol\" ]; then\n\ mkdir -p airs_protocol\n\ cp -r temp_airs/airs_protocol/* airs_protocol/\n\ cp -r temp_airs/airs_protocol/.[^.]* airs_protocol/ 2>/dev/null || true\n\ fi\n\ \n\ # 清理临时文件\n\ rm -rf temp_airs\n\ \n\ echo \"airs_protocol 代码下载完成\"\n\ ls -la airs_protocol/\n\ \n\ # 安装当前项目依赖\n\ if [ -f \"package.json\" ]; then\n\ echo \"安装 Node.js 依赖...\"\n\ /usr/local/bin/npm install\n\ fi\n\ \n\ if [ -f \"requirements.txt\" ]; then\n\ echo \"安装 Python 依赖...\"\n\ pip install --no-cache-dir -r requirements.txt\n\ fi\n\ \n\ # 安装 airs_protocol 依赖\n\ if [ -f \"airs_protocol/requirements.txt\" ]; then\n\ echo \"安装 airs_protocol Python 依赖...\"\n\ pip install --no-cache-dir -r airs_protocol/requirements.txt\n\ fi\n\ \n\ if [ -f \"airs_protocol/package.json\" ]; then\n\ echo \"安装 airs_protocol Node.js 依赖...\"\n\ /usr/local/bin/npm install\n\ fi\n\ \n\ echo \"环境准备完成,启动应用...\"\n\ \n\ # HuggingFace Spaces 启动逻辑\n\ if [ \\$# -gt 0 ]; then\n\ exec \"\\$@\"\n\ else\n\ # 优先级启动顺序\n\ if [ -f \"package.json\" ]; then\n\ if grep -q \"start\" package.json; then\n\ echo \"使用 npm start 启动...\"\n\ exec npm start\n\ fi\n\ fi\n\ \n\ if [ -f \"app.py\" ]; then\n\ echo \"使用 python app.py 启动...\"\n\ exec python app.py\n\ fi\n\ \n\ if [ -f \"main.py\" ]; then\n\ echo \"使用 python main.py 启动...\"\n\ exec python main.py\n\ fi\n\ \n\ if [ -f \"server.py\" ]; then\n\ echo \"使用 python server.py 启动...\"\n\ exec python server.py\n\ fi\n\ \n\ # 默认保持运行,避免容器重启\n\ echo \"未找到标准启动文件,保持容器运行...\"\n\ sleep infinity\n\ fi\n" > /app/entrypoint.sh \ && chmod +x /app/entrypoint.sh # 创建非 root 用户 RUN useradd -m -u 1000 user \ && chown -R user:user /app # 复制项目文件 COPY --chown=user . . # 暴露 HuggingFace Spaces 默认端口 EXPOSE 7860 # 切换到非 root 用户 USER user # 设置环境变量 - 加载 Node.js 路径 ENV HOME=/home/user \ PATH=/usr/local/bin:\$PATH \ NODE_PATH=/usr/local/bin # HuggingFace Spaces 会使用此 entrypoint ENTRYPOINT ["/app/entrypoint.sh"]