From d6bcd11fb40b2a1a99d89193a5c80bc516ab8200 Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Thu, 22 Oct 2026 19:50:00 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=83=A8=E7=BD=B2=EF=BC=9A?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=8D=B7=E5=B1=9E=E4=B8=BB=E6=98=AF=20root?= =?UTF-8?q?=EF=BC=8C=E5=B9=B3=E5=8F=B0=E7=94=A8=E6=88=B7=E5=86=99=E4=B8=8D?= =?UTF-8?q?=E8=BF=9B=E6=95=B0=E6=8D=AE=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Docker 新建数据卷时属主是 root,而平台用普通用户(APP_UID)运行,SQLite 打不开数据库, 新容器反复退出。compose 加一个启动前只运行一次的 init-data(root 把 /data 交给平台用户), Dockerfile 里也预先建好属于平台用户的 /data。 Co-Authored-By: Claude Opus 5.5 --- Dockerfile | 2 ++ compose.yaml | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/Dockerfile b/Dockerfile index cdbab84..951e1ae 100644 --- a/Dockerfile +++ b/Dockerfile @@ -40,6 +40,8 @@ ENV APP_ROOT=/app \ TZ=Asia/Shanghai \ PORT=3000 \ DOTNET_CLI_TELEMETRY_OPTOUT=1 +# 数据目录(数据卷挂在这里)属于运行平台的用户,新建的数据卷会继承这个属主 +RUN mkdir -p /data && chown "$APP_UID" /data # 镜像自带的非 root 用户 USER $APP_UID EXPOSE 3000 diff --git a/compose.yaml b/compose.yaml index 993ad0b..b12b6e7 100644 --- a/compose.yaml +++ b/compose.yaml @@ -1,10 +1,25 @@ # 部署:先在 .env 里写好 TEACHER_PASSWORD(参考 .env.example),再 docker compose up -d # HTTPS 由 Nginx Proxy Manager 负责,它在 npm_proxy 网络里转发到 iot-sim:80;步骤见 deploy/README.md services: + # 启动前把数据卷交给平台用户(Docker 新建数据卷时属主是 root,平台用普通用户运行,写不进去) + init-data: + image: iot-sim:latest + # 和 app 同一个镜像(构建有缓存,不会重复构建);写上 build,新服务器上就不会去 Docker Hub 拉这个镜像 + build: . + user: root + command: ["sh", "-c", "chown -R \"$$APP_UID\" /data"] + volumes: + - data:/data + restart: "no" + networks: [default] + app: image: iot-sim:latest build: . restart: unless-stopped + depends_on: + init-data: + condition: service_completed_successfully environment: # 老师账号(只有一个);学生账号由老师在网页上导入名单 TEACHER_USERNAME: ${TEACHER_USERNAME:-admin}