How to fix "Directory not empty" on move during docker build? - node.js

I have a working Dockerfile for a node application:
FROM node:8.8
ENV TERM=xterm-color NPM_CONFIG_LOGLEVEL=warn PATH="$PATH:/usr/src/app/node_modules/.bin/"
VOLUME ["/logs"]
WORKDIR /tmp/node
ADD package.json yarn.lock .npmrc ./
RUN yarn install --frozen-lockfile --ignore-platform --ignore-engines --quiet
WORKDIR /usr/src/app
ADD . /usr/src/app
RUN mv /tmp/node/* ./ && tsc && webpack
CMD ["node", "/usr/src/app/server"]
I wanted to re-created the caching behavior for the node_modules during build, hence I have updated the Dockerfile for another project to look very similar.
FROM node:9-alpine
WORKDIR /tmp/node
ADD package.json yarn.lock ./
RUN yarn install --frozen-lockfile --ignore-platform --ignore-engines --quiet
WORKDIR /app
ADD . /app/
RUN mv /tmp/node/* ./
EXPOSE 1337
CMD ["yarn", "start"]
Yet for that Dockerfile I get an unexpected error during:
$ docker build .
...
Step 7/9 : RUN mv /tmp/node/* ./
---> Running in 51543827cd89
mv: can't rename '/tmp/node/node_modules': Directory not empty
The command '/bin/sh -c mv /tmp/node/* ./' returned a non-zero code: 1
Why doesn't the mv command work here?

When you run docker build ., the current directory gets passed as its context. It's most likely the case that you have either run the yarn install command on your host already which is why you alrady have a
/app/node_modules
This is why it cannot be moved, as it already exists.
To avoid passing the folder along within the context, you can add:
node_modules/
in your .dockerignore file.

Related

Docker build is not using cache all the time for react/node project

I have a docker file for deploying my react project. Here is the dockerfile:
FROM node:14.2.0
COPY package.json /tmp/package.json
RUN cd /tmp && npm install --silent
RUN mkdir -p /home/node/app/ && cp -a /tmp/node_modules /home/node/app/
WORKDIR /home/node/app/
USER root
COPY . ./
I believe if there is no change in package.json it will use cache for npm install(2nd step) and copying node_modules (3rd step).
But even if there is no change in package.json it does not.
How do I cache the steps then ?

RUN yarn doesn't create node_modules inside docker image

I have a dockerfile that should build an image of a node. In the build phase, it builds right, however, in the production phase, the node_modules folder does not appear inside the image.
I'm not mapping any volumes, just trying to build the image. Could anyone help me with this? I don't understand why this is happening.
FROM node:16.14-alpine3.15 as builder
ENV NODE_ENV=development
WORKDIR /home/node/app
COPY package*.json .
COPY tsconfig.json .
RUN yarn install
COPY . .
RUN yarn build
FROM node:16.14-alpine3.15 as production
ENV NODE_ENV=production
RUN mkdir -p /usr/src/app
VOLUME /usr/src/app
WORKDIR /usr/src/app
RUN mkdir logs
COPY package*.json .
COPY yarn.lock .
RUN yarn install --production
RUN ls -la
RUN ls -la node_modules
COPY --from=builder /home/node/app/dist /usr/src/app/dist
EXPOSE 3333
CMD ["yarn", "start"]

how do a dockerfile for React JS, Next js , npm project

I'm making an app with React JS, Next Js, npm and also I would have to change the .npmrc for it to run.
I don't know how I could make a DockerFile for these technologies and at the same time this dockerfile has to change the .npmrc
my docker file
FROM node:lts as dependencies
WORKDIR /emercore-arg-manager
COPY package.json yarn.lock ./
RUN echo "#lala-lalal:registry=https://npm.pkg.github.com/" >> ~/.npmrc
RUN echo "//npm.pkg.github.com/:_authToken=asdasdasdasdasdsad" >> ~/.npmrc
RUN echo "//registry.npmjs.org/:_authToken=assdasdasdasdsaasd" >> ~/.npmrc
RUN yarn install --frozen-lockfile
FROM node:lts as builder
WORKDIR /emercore-arg-manager
COPY . .
COPY --from=dependencies /emercore-arg-manager/node_modules ./node_modules
RUN yarn build
FROM node:lts as runner
WORKDIR /emercore-arg-manager
ENV NODE_ENV production
# If you are using a custom next.config.js file, uncomment this line.
# COPY --from=builder /my-project/next.config.js ./
COPY --from=builder /emercore-arg-manager/public ./public
COPY --from=builder /emercore-arg-manager/.next ./.next
COPY --from=builder /emercore-arg-manager/node_modules ./node_modules
COPY --from=builder /emercore-arg-manager/package.json ./package.json
EXPOSE 3000
CMD ["yarn", "start:dev"]
It does not work for me, and I think it is a lot of content for a dockerfile with these technologies, could someone help me to put together a shorter one and make it work?
The command that i use in my deskpot is yarn install and yarn start:dev (and its working)

Docker: node_modules symlink not working for typescript

I am working on containerization of Express app in TS. But not able to link node_modules installed outside the container. Volume is also mounted for development.But still getting error in editor(vscode) Cannot find module 'typeorm' or its corresponding type declarations., similar for all dependencies.
volumes:
- .:/usr/src/app
Dockerfile:
FROM node:16.8.0-alpine3.13 as builder
WORKDIR /usr/src/app
COPY package.json .
COPY transformPackage.js .
RUN ["node", "transformPackage"]
FROM node:16.8.0-alpine3.13
WORKDIR /usr/src/app
COPY --from=builder /usr/src/app/package-docker.json package.json
RUN apk update && apk upgrade
RUN npm install --quiet && mv node_modules ../ && ln -sf ../node_modules node_modules
COPY . .
EXPOSE 3080
ENV NODE_PATH=./dist
RUN npm run build
CMD ["npm", "start"]
I've one workaround where I can install dependencies locally, and then use those, but need another solution where we should install dependencies only in the container and not the outside.
Thanks in advance.
Your first code section implies you use docker-compose. Probably the build (of the Dockerfile) is also done there.
The point is that the volume mappings in the docker-compose are not available during build-phase in that same Docker-service.

Running gulp in Docker compose - does not create files

I have issues where gulp is not making any files. It says finished, but no file is being created.
If I log in to my docker instance using:
docker exec -t -i myservice-service /bin/bash
and if I run the gulp command, then it creates it properly
Then all the files defined in the gulpfile.js are created. In other words, public/dist/ is populated with the main.js and other css files.
This is my Dockerfile.
FROM node:9
RUN mkdir -p /usr/src/app
RUN mkdir -p /usr/src/logs
WORKDIR /usr/src/app
# GULP Installation
RUN npm install -g gulp
RUN npm install gulp
COPY package*.json /usr/src/app/
COPY .npmrc /usr/src/app/
RUN cd /usr/src/app/ && npm install && npm install -g nodemon
COPY . /usr/src/app
RUN chown -R node:node /usr/src/app && chown -R node:node /usr/src/logs
USER node
EXPOSE 3000
RUN gulp
CMD ["npm", "run-script", "start" ]
And this is my composer file (development):
version: "3"
services:
myservice-service:
build: .
image: myservice-service
container_name: myservice-service
volumes:
- .:/usr/src/app
- /usr/src/app/node_modules
environment:
- NODE_ENV=dev
ports:
- 3000:3000
command: nodemon --delay 2 ./bin/www
I run it as:
docker-compose -f docker-compose.development.yml up --build
When I run it like that, it does not create any files. I get the same output on the screen, when I run the command manually.
I have spent hours trying to make it work, I tried with setting permissions and what not, but it just does not work.
My expectation was to have public/dist/ populated with files.
Any help is appreciated.
UPDATE. It works, but I have doubts:
I manage to make it work by using command inside the composerfile itself.
So in my case:
command: bash -c "gulp && nodemon --delay 2 ./bin/www"
In my reasoning, gulp should be done inside the Dockerfile itself, not on the composer files. But then again, it is out of my scope of knowledge.
The Dockerfile is run at build time and will COPY all the files in your local directory into the container, then run gulp and create any files.
You then mount the local folder over the docker containers file system, pretty much overwriting what was done in the docker file with the original files, as gulp ran on the files in the container, it did not effect the original files so you are undoing the changes.
The solutions are either to do as as you have mentioned in your question (add it to the command in docker-compose.yml or run it via docker-compose exec) or write a custom entrypoint script that will run gulp and then the command, something like:
bin/entrypoint.sh
#!/bin/sh
gulp
exec "$#"
Dockerfile
FROM node:9
COPY bin/entrypoint.sh /entrypoint.sh
RUN chmod 755 /entrypoint.sh
RUN mkdir -p /usr/src/app
RUN mkdir -p /usr/src/logs
WORKDIR /usr/src/app
# GULP Installation
RUN npm install -g gulp
RUN npm install gulp
COPY package*.json /usr/src/app/
COPY .npmrc /usr/src/app/
RUN cd /usr/src/app/ && npm install && npm install -g nodemon
COPY . /usr/src/app
RUN chown -R node:node /usr/src/app && chown -R node:node /usr/src/logs
USER node
EXPOSE 3000
ENTRYPOINT ["/entrypoint.sh"]
CMD ["npm", "run-script", "start" ]
This will make your build a little less predictable though as it will run gulp each time the container starts (e.g. after every deployment) if you use the same Dockerfile in dev and production.

Resources