Kaynağa Gözat

fix(deploy): 容器以 node 用户运行,修复 output/jobs 卷权限

docker-compose 原以 root(0:0) 运行,导致 ./output 写出 root 属主文件,
污染宿主机访问(本地 CLI 渲染 EACCES)。改为以镜像 node 用户
(uid 1000 == 宿主机 lkattey,且与 k8s 运行时一致)运行:bind mount
文件保持宿主机属主而非 root。jobs 存储由 root 属主的命名卷改为预建为
1000 属主的 bind mount(.data/pipeline-jobs),避免非 root 容器写不了。
user 默认 node:node,可用 HOST_UID/HOST_GID 覆盖以适配非 1000 宿主机;
.data/ 加入 .gitignore。

Co-Authored-By: Claude <noreply@anthropic.com>
lkatzey 4 gün önce
ebeveyn
işleme
28f40b5073
2 değiştirilmiş dosya ile 14 ekleme ve 8 silme
  1. 3 0
      .gitignore
  2. 11 8
      docker-compose.yml

+ 3 - 0
.gitignore

@@ -19,5 +19,8 @@ next-env.d.ts
 output/
 tmp/
 
+# Docker bind-mounted runtime data (jobs store, pre-created as uid 1000)
+.data/
+
 # Claude Code
 .claude/settings.local.json

+ 11 - 8
docker-compose.yml

@@ -1,10 +1,13 @@
 services:
   pipeline:
     build: .
-    # The image runs as the non-root `node` user for Kubernetes. For local dev
-    # we override back to root so the ./output bind mount keeps working
-    # regardless of the host user's uid; Kubernetes sets fsGroup instead.
-    user: "0:0"
+    # Run as the image's non-root `node` user by default (uid 1000 == host
+    # `lkattey` here, and the same user Kubernetes runs the image as, so local
+    # compose mirrors prod's filesystem ownership). Bind-mounted files (./output,
+    # ./.data) therefore stay host-accessible instead of root-owned. On a host
+    # whose uid isn't 1000, set HOST_UID/HOST_GID (in .env or the shell) to your
+    # numeric uid:gid so the bind mounts match your user.
+    user: "${HOST_UID:-node}:${HOST_GID:-node}"
     ports:
       - "${PORT:-13000}:3000"
     # Pass EVERY variable from .env (API keys, OSS, Feishu, SCHEDULES,
@@ -23,7 +26,10 @@ services:
       - TIMEZONE=${TIMEZONE:-Asia/Shanghai}
     volumes:
       - ./output:/app/output
-      - pipeline-jobs:/tmp/pipeline-jobs
+      # Bind mount (pre-created as uid 1000 on the host) instead of a named
+      # volume: named volumes are root-owned, which the non-root container
+      # (uid 1000) below couldn't write to. .data is gitignored.
+      - ./.data/pipeline-jobs:/tmp/pipeline-jobs
     # Use public DNS resolvers directly. The container inherits the host's
     # resolver, which can silently fail to resolve some public domains (e.g.
     # open.feishu.cn behind a VPN/proxy) and break the Feishu webhook. Override
@@ -32,6 +38,3 @@ services:
       - ${DNS_SERVER_1:-223.5.5.5}
       - ${DNS_SERVER_2:-114.114.114.114}
     restart: unless-stopped
-
-volumes:
-  pipeline-jobs: