Reputation: 475
I'm using Docker for Mac and Docker Compose for development of a Node.js application and I'm experiencing an error with the package.json file being locked. The specific error after running npm install --save <package>
within a running container is:
npm WARN saveError EBUSY: resource busy or locked, rename
'/Example/package.json.1647356251' -> '/Example/package.json'
The simplified package structure is:
▾ docker/
Dockerfile
docker-compose.yaml
package.json
The Dockerfile contains:
FROM node:9.5
ENV SOURCE_CODE /Example
COPY package.json $SOURCE_CODE/package.json
RUN npm --prefix $SOURCE_CODE install $SOURCE_CODE
WORKDIR $SOURCE_CODE
The docker-compose.yaml file contains:
version: "3"
services:
node:
build:
context: ./
dockerfile: ./docker/Dockerfile
volumes:
- ./node_modules/:/Example/node_modules/
- ./package.json:/Example/package.json
The package.json file contains:
{
"name": "example",
"version": "1.0.0",
"description": "example",
"license": "UNLICENSED"
}
Running docker-compose run --entrypoint bash node
to start bash, then running npm install --save redux
inside the container yields the warning about the package.json file being locked, however files are able to be written in the node_modules directory on the host. How can I avoid locks on package.json file using this structure?
Upvotes: 8
Views: 5617
Reputation: 3827
This is a quite an odd config problem, but I eventually cracked the nut. The idea is to:
Volume mount the host's package-lock.json
to package-lock-host.json
Run npm install
in the container to generate new contents
Overwrite the host's contents with the container's newly generated contents
docker-compose run \
--rm \
--name 'package_lock_json' \
-v "$(pwd)/package-lock.json":'/package-lock-host.json' \
--entrypoint /bin/sh \
'YOUR_CONTAINER_NAME' \
-c "npm install --package-lock-only && (cat /package-lock.json > /package-lock-host.json)"
Upvotes: 0
Reputation: 1873
Like Green Tree suggested, playing with links works. The idea:
In you Dockerfile, do something like this:
# Create a home dir, give access to 'node' user
ENV HOME [whatever your home is...]
RUN mkdir -p $HOME && \
chown node:node $HOME
# Switch to user node
USER node
# We'll place our files in npm-package
# Create that folder, place empty place holders in there,
# and create a link to them
RUN mkdir $HOME/npm-package && \
touch $HOME/npm-package/package.json && \
touch $HOME/npm-package/package-lock.json && \
ln -s $HOME/npm-package/package.json $HOME/package.json && \
ln -s $HOME/npm-package/package-lock.json $HOME/package-lock.json
The temp files are there for two reasons:
Then in docker-compose.yml:
services:
your-service-name:
volumes:
- npm-package/:/opt/app/npm-package/
Works for me (under Linux)
Upvotes: 0
Reputation: 3586
I encountered the same issue and I solved this by mounting the folder where package.json is located instead of package.json itself.
version: "3"
services:
node:
build:
context: ./
dockerfile: ./docker/Dockerfile
volumes:
- .:/Example
Mounting package.json directly as a volume seems to lock the file.
Upvotes: 2