使用特定 docker 用户时无法执行 npm 更新

Cannot execute npm update when using a specific docker user

我创建了一个与主机用户相关联的 php fpm 容器,这样我就不会对 docker 容器中生成的文件有任何问题(例如:当使用 php artisan make:controller).

所以我有这个 docker-compose.yml:

    version: '3.9'
    
    services:
    
      laravel-fpm:
        user: 1000
        container_name: laravel_app
        restart: always
        build:
          context: .
          dockerfile: ./docker/php-fpm/Dockerfile
        volumes:
          - ./src:/var/www/html

这是 Dockerfile:

    FROM php:8.0.2-fpm-alpine
    WORKDIR /var/www/html
    
    RUN docker-php-ext-install pdo_mysql
    RUN docker-php-ext-install mysqli
    RUN apk add icu-dev
    
    # Installa nodejs per l'utilizzo delle dipendenze npm
    RUN apk add --update npm
    RUN npm install gulp-cli -g
    RUN npm install
    
    CMD ["php-fpm"]
    
    EXPOSE 9000

当我在容器 docker-exec -it laravel_app sh 内访问时,然后我 运行 npm install 我得到:

Your cache folder contains root-owned files, due to a bug in npm ERR! previous versions of npm which has since been addressed. npm ERR! npm ERR! To permanently fix this problem, please run: npm ERR! sudo chown -R 1000:0 "/.npm" npm ERR! code EACCES npm ERR! syscall mkdir npm ERR! path /.npm npm ERR! errno -13

这个问题与我在容器上指定的 USER 指令有关,有没有办法解决这个问题?

如错误消息所述,您可以运行以下命令永久消除错误。

$ sudo chown -R 1000:0 "/.npm"

注意:由于此命令 运行 具有 sudo 权限,您可能需要提供管理密码。


您也可以在您的 Dockerfile 中添加此命令以避免手动 运行ning 它。

RUN sudo chown -R 1000:0 "/.npm"

npm install 命令之前添加此命令。

问题

当您运行 Docker 容器作为 uid 1000 时,该用户不存在于容器中,因此默认路径,例如 npm 缓存通常位于运行 用户的 HOME 目录无处可住,因此默认为 /。在构建期间,您充当 root 因为没有 USER 指令。此外,构建中的 npm install 可能正在创建缓存目录,但没有 package.json 则没有任何可安装的内容。

解决方案

  1. 在您的 Docker 文件中创建用户。
  2. 更改 npm 写入缓存的位置。
  3. Pre-create目录

创建用户

如果您创建用户,则假定它始终是同一用户,但由于您在 Docker 中设置用户,因此这可能不是最佳解决方案(如果您使用不同的用户?)。如果你能推断出你将成为哪个用户,那么这可能是最好的选择,在 Docker 文件中使用 USER 指令。

更改 npm 缓存位置

您可以使用 .npmrc 文件,并设置 cache=/some_dir,或在命令行 npm install --cache=/some_dir 上进行更改。我建议你在根 fs 中创建一个合理的地方,比如 /npm,然后是 cache=/npm/.npm.

在您的 Docker 文件中,它看起来像这样:

# Set the NPM cache location
RUN mkdir /npm && chmod a+rwx /npm

Pre-create目录

最简单的选择可能是 pre-create 具有打开权限的缓存目录。 Docker文件摘录应该是这样的:

...
RUN apk add --update npm
RUN npm install gulp-cli -g
# You don't need this if you haven't got the
#  application code in the build.
# RUN npm install
RUN mkdir /.npm && chmod a+rwx /.npm
...

如果您想跨容器持久保存它,您可以创建一个卷或将本地文件夹绑定挂载到 docker 组合文件中的容器中。

最干净的方法是预先创建该用户并配置 npms 路径前缀。

FROM php:8.0.2-fpm-alpine

# use the root user for the installation
USER root

# install and configure npm
RUN apk add --update --no-cache npm
RUN npm config -g set prefix /home/dev/.local/npm

# create the local user
ARG UID="1000" GID="1000"
RUN addgroup -g $GID "dev" && \
    adduser -D -G "dev" -s /bin/sh -u $UID "dev"

# switch to the local user
USER dev

# add npms bin path to PATH
ENV PATH="$PATH:/home/dev/.local/npm/bin"

# install package as user
RUN npm install gulp-cli -g