FROM node:20-slim AS builder WORKDIR /app RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/* RUN git clone https://github.com/tashfeenahmed/freellmapi.git . RUN npm install RUN npm run build # --- 生产运行环境 --- FROM node:20-slim AS runner WORKDIR /app # 补全 Prisma 运行所需的 openssl 依赖,防止报错 RUN apt-get update && apt-get install -y openssl && rm -rf /var/lib/apt/lists/* COPY --from=builder /app ./ RUN mkdir -p /data/freellm # 1. 前端静态路由修复 RUN cp -r client/dist/* server/dist/public/ 2>/dev/null || cp -r client/dist/* server/public/ 2>/dev/null || true # 2. 注入基础配置 EXPOSE 7860 ENV PORT=7860 ENV DEV_MODE=true ENV DATABASE_URL="file:/data/database.sqlite" # 3. 【无损看门狗】:保持你原本的逻辑不变 RUN echo "import fs from 'fs';" > security.js && \ echo "const file = 'server/dist/index.js';" >> security.js && \ echo "if (fs.existsSync(file)) {" >> security.js && \ echo " let content = fs.readFileSync(file, 'utf8');" >> security.js && \ echo " const injectCode = \` \ import http from 'http'; \ const originalCreateServer = http.createServer; \ http.createServer = function(onion) { \ return originalCreateServer.call(this, (req, res) => { \ const user = process.env.SPACE_BASIC_AUTH_USERNAME || 'admin'; \ const pass = process.env.SPACE_BASIC_AUTH_PASSWORD || 'admin123'; \ if (req.url.startsWith('/v1')) return onion(req, res); \ const b64auth = (req.headers.authorization || '').split(' ')[1] || ''; \ const [login, password] = Buffer.from(b64auth, 'base64').toString().split(':'); \ if (login === user && password === pass) return onion(req, res); \ res.statusCode = 401; \ res.setHeader('WWW-Authenticate', 'Basic realm=\"Secure\"'); \ res.end('Unauthorized'); \ }); \ }; \n\`;" >> security.js && \ echo " fs.writeFileSync(file, injectCode + content, 'utf8');" >> security.js && \ echo "}" >> security.js # 💡 核心修复点: # 1. 使用 --schema=./server/prisma/schema.prisma 精确定位文件 # 2. 强制指定环境变量,确保数据库表结构安全同步到 /data/database.sqlite # 移除所有在外部手动调用的 prisma 指令,直接交给项目原本的 dev 命令去跑,它内部自己会处理数据库初始化! CMD ["npm", "run", "dev"]