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