skip to Main Content

I have created a php fpm containers which is associated to the host user, in this way I doesn’t have any issues with the file generated within the docker container (eg: when using php artisan make:controller).

So I have this 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

and this is the 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

When I access within the container docker-exec -it laravel_app sh, and then I run npm install I get:

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

This problem is related to the USER directive which I have specified on the container, is there a way to fix that?

3

Answers


  1. As the error message states, you can run the following command to permanently get rid of the error.

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

    Note: As this command is running in sudo privileges, you may have to provide an administrative password.


    You can also add this command in your Dockerfile to avoid manually running it.

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

    Add this command before the npm install command.

    Login or Signup to reply.
  2. The Problem

    When you’re running the Docker container as uid 1000, that user doesn’t exist in the container, so default paths, such as for the npm cache that would normally be in the HOME directory of the running user don’t have anywhere to live, so defaults to /. During the build, you are acting as root since there is no USER directive. Additionally, the npm install inside the build is possibly creating the cache directory, but without the package.json has nothing to install.

    The Solution(s)

    1. Create the user in your Dockerfile.
    2. Change where npm is writing the cache.
    3. Pre-create the directory

    Create a User

    If you create the user, that assumes that it will always be the same user, but since you’re setting the user in the Docker Compose this possibly isn’t the best solution (what if you use a different user?). If you can reason which user you will be, then this might be the best option, using a USER directive in the Dockerfile.

    Change the npm cache location

    You can use a .npmrc file, and set cache=/some_dir, or on the command line npm install --cache=/some_dir to change this. I’d suggest you create somewhere sensible in the root fs, something like /npm, then cache=/npm/.npm.

    In your Dockerfile, it would look like this:

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

    Pre-create the directory

    The simplest option is probably to just pre-create the cache directory with open permissions. The Dockerfile excerpt would be something like this:

    ...
    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
    ...
    

    If you want to persist this across containers, you could create a volume or bind mount a local folder into the container in the docker compose file.

    Login or Signup to reply.
  3. Most clean would be to create that user upfront and configure npms path prefix.

    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
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search