Spaces:
Running
Running
Update Dockerfile
Browse files- Dockerfile +21 -6
Dockerfile
CHANGED
|
@@ -12,7 +12,7 @@ WORKDIR /app
|
|
| 12 |
COPY --from=builder /app ./
|
| 13 |
RUN mkdir -p /data/freellm
|
| 14 |
|
| 15 |
-
# 1. 前端路由修复
|
| 16 |
RUN cp -r client/dist/* server/dist/public/ 2>/dev/null || cp -r client/dist/* server/public/ 2>/dev/null || true
|
| 17 |
|
| 18 |
# 2. 注入基础配置
|
|
@@ -21,15 +21,30 @@ ENV PORT=7860
|
|
| 21 |
ENV NODE_ENV=production
|
| 22 |
ENV DATABASE_URL="file:/data/database.sqlite"
|
| 23 |
|
| 24 |
-
# 3. 【
|
| 25 |
-
|
|
|
|
| 26 |
echo "const file = 'server/dist/index.js';" >> security.js && \
|
| 27 |
echo "if (fs.existsSync(file)) {" >> security.js && \
|
| 28 |
echo " let content = fs.readFileSync(file, 'utf8');" >> security.js && \
|
| 29 |
-
echo " const injectCode = \`
|
| 30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
echo " fs.writeFileSync(file, injectCode + content, 'utf8');" >> security.js && \
|
| 32 |
echo "}" >> security.js
|
| 33 |
|
| 34 |
-
# 4.
|
| 35 |
CMD ["sh", "-c", "rm -rf /app/server/data && ln -s /data/freellm /app/server/data && node security.js && export ENCRYPTION_KEY=$(node -e \"console.log(require('crypto').randomBytes(32).toString('hex'))\") && node server/dist/index.js"]
|
|
|
|
| 12 |
COPY --from=builder /app ./
|
| 13 |
RUN mkdir -p /data/freellm
|
| 14 |
|
| 15 |
+
# 1. 前端静态路由修复
|
| 16 |
RUN cp -r client/dist/* server/dist/public/ 2>/dev/null || cp -r client/dist/* server/public/ 2>/dev/null || true
|
| 17 |
|
| 18 |
# 2. 注入基础配置
|
|
|
|
| 21 |
ENV NODE_ENV=production
|
| 22 |
ENV DATABASE_URL="file:/data/database.sqlite"
|
| 23 |
|
| 24 |
+
# 3. 【无损看门狗】:直接把拦截逻辑写进一个独立的中间件,然后利用 Node.js 极低层的 http 模块拦截器
|
| 25 |
+
# 无论项目底层怎么写、变量叫什么名字,只要请求进来,首先必过此关,绝不引发任何语法冲突!
|
| 26 |
+
RUN echo "import fs from 'fs';" > security.js && \
|
| 27 |
echo "const file = 'server/dist/index.js';" >> security.js && \
|
| 28 |
echo "if (fs.existsSync(file)) {" >> security.js && \
|
| 29 |
echo " let content = fs.readFileSync(file, 'utf8');" >> security.js && \
|
| 30 |
+
echo " const injectCode = \` \
|
| 31 |
+
import http from 'http'; \
|
| 32 |
+
const originalCreateServer = http.createServer; \
|
| 33 |
+
http.createServer = function(onion) { \
|
| 34 |
+
return originalCreateServer.call(this, (req, res) => { \
|
| 35 |
+
const user = process.env.SPACE_BASIC_AUTH_USERNAME || 'admin'; \
|
| 36 |
+
const pass = process.env.SPACE_BASIC_AUTH_PASSWORD || 'admin123'; \
|
| 37 |
+
if (req.url.startsWith('/v1')) return onion(req, res); \
|
| 38 |
+
const b64auth = (req.headers.authorization || '').split(' ')[1] || ''; \
|
| 39 |
+
const [login, password] = Buffer.from(b64auth, 'base64').toString().split(':'); \
|
| 40 |
+
if (login === user && password === pass) return onion(req, res); \
|
| 41 |
+
res.statusCode = 401; \
|
| 42 |
+
res.setHeader('WWW-Authenticate', 'Basic realm=\"Secure\"'); \
|
| 43 |
+
res.end('Unauthorized'); \
|
| 44 |
+
}); \
|
| 45 |
+
}; \n\`;" >> security.js && \
|
| 46 |
echo " fs.writeFileSync(file, injectCode + content, 'utf8');" >> security.js && \
|
| 47 |
echo "}" >> security.js
|
| 48 |
|
| 49 |
+
# 4. 完美运行命令
|
| 50 |
CMD ["sh", "-c", "rm -rf /app/server/data && ln -s /data/freellm /app/server/data && node security.js && export ENCRYPTION_KEY=$(node -e \"console.log(require('crypto').randomBytes(32).toString('hex'))\") && node server/dist/index.js"]
|