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
As the error message states, you can run the following command to permanently get rid of the error.
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.Add this command before the
npm install
command.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 asroot
since there is noUSER
directive. Additionally, thenpm install
inside the build is possibly creating the cache directory, but without thepackage.json
has nothing to install.The Solution(s)
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 setcache=/some_dir
, or on the command linenpm install --cache=/some_dir
to change this. I’d suggest you create somewhere sensible in the root fs, something like/npm
, thencache=/npm/.npm
.In your Dockerfile, it would look like this:
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:
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.
Most clean would be to create that user upfront and configure npms path prefix.