使用Docker部署Node应用至DigitalOcean时遭遇权限问题
Node应用Docker部署至DigitalOcean时的EACCES权限错误
错误信息
npm ERR! code EACCES npm ERR! syscall open npm ERR! path /app/package.json npm ERR! errno -13 npm ERR! Error: EACCES: permission denied, open '/app/package.json' npm ERR! [Error: EACCES: permission denied, open '/app/package.json'] { npm ERR! errno: -13, npm ERR! code: 'EACCES', npm ERR! syscall: 'open', npm ERR! path: '/app/package.json' npm ERR! } npm ERR! npm ERR! 操作被操作系统拒绝。 npm ERR! 很可能当前用户没有访问该文件的权限 npm ERR! npm ERR! 如果你认为这是权限问题,请仔细检查文件及其所在目录的权限,或尝试以root/管理员身份重新运行命令。
已创建具备sudo权限的node用户,但问题仍未解决。相关配置文件和命令如下:
Dockerfile内容
# 获取Node镜像 - 确保各环境一致性 FROM --platform=linux/amd64 node:16.17.0 # 先复制package相关文件,此处变更会使后续缓存失效 # 参考缓存优化文档 COPY package.json package-lock.json app/ # 设置工作目录 WORKDIR /app # 安装所有依赖(含开发依赖) # 放在COPY前,避免代码变更导致依赖层缓存失效 RUN npm ci --platform=linux --progress=false # 复制项目所有文件(排除.dockerignore中的内容)到/app COPY . . # 切换为非root用户运行 USER node # 确保文件归node用户所有,否则应用会退出 COPY --chown=node:node . /app # 暴露端口 EXPOSE 3002 3003 # 启动命令 CMD ["npm", "start"]
Docker Compose启动命令
docker-compose up -d --force-recreate --remove-orphans
docker-compose.yml内容
# 作为远程服务器生产环境文件模板 # 变更需同步到生产环境文件 version: '3' services: app: image: image/name container_name: container_name command: "npm start" environment: - NODE_ENV=production ports: - "127.0.0.1:3002:3002" working_dir: /app volumes: - .:/app
解决方案
核心问题分析
问题根源是本地目录挂载覆盖了容器内文件权限:docker-compose中配置了volumes: - .:/app,将主机当前目录直接挂载到容器的/app目录。这会覆盖容器内通过COPY --chown=node:node设置的文件权限,而主机目录的文件属于主机root或其他用户,容器内的node用户无访问权限。
修复步骤
调整Dockerfile的文件复制与权限设置顺序:
在切换到node用户前完成文件复制和所有权设置,避免重复操作。修改后的Dockerfile:FROM --platform=linux/amd64 node:16.17.0 # 创建/app目录并设置所有权 RUN mkdir -p /app && chown node:node /app # 设置工作目录 WORKDIR /app # 先复制依赖文件,利用缓存优化 COPY --chown=node:node package.json package-lock.json ./ # 切换为node用户执行依赖安装 USER node RUN npm ci --platform=linux --progress=false # 复制应用代码并确保所有权 COPY --chown=node:node . . # 暴露端口 EXPOSE 3002 3003 # 启动命令 CMD ["npm", "start"]修改生产环境docker-compose.yml:
生产环境无需挂载本地目录,直接使用镜像内的文件即可,删除volumes配置:version: '3' services: app: image: image/name container_name: container_name command: "npm start" environment: - NODE_ENV=production ports: - "127.0.0.1:3002:3002" working_dir: /app本地开发如需挂载目录,可单独维护dev版docker-compose,或挂载后手动设置容器内目录权限,但生产环境必须移除该挂载。
重新构建镜像并部署:
docker build -t image/name . docker-compose up -d --force-recreate --remove-orphans
额外说明
- 不要在Dockerfile中重复执行
COPY . .,会增加镜像层数并导致权限混乱。 - 生产环境使用镜像内文件而非主机挂载,可保证环境一致性,避免权限和文件版本问题。
内容的提问来源于stack exchange,提问作者Jason Long
相关产品推荐
相关产品推荐

