docker image is not rebuilt automatically on file change - docker

I am running docker containers with WSL2. When I make changes to my files in the /client directory the changes are not reflected and I have to do docker compose stop client, docker compose build client and docker compose start client. If I cat a file after changing domething one can see the change.
Here is my Dockerfile:
FROM node:16.17.0-alpine
RUN mkdir -p /client/node_modules
RUN chown -R node:node /client/node_modules
RUN chown -R node:node /root
WORKDIR /client
# Copy Files
COPY . .
# Install Dependencies
COPY package.json ./
RUN npm install --force
USER root
I alse have a /server directory with the following Dockerfile and the automatic image rebuild happens on file change there just fine:
FROM node:16.17.0-alpine
RUN mkdir -p /server/node_modules
RUN chown -R node:node /server/node_modules
WORKDIR /server
COPY . .
# Install Dependencies
COPY package.json ./
RUN npm install --force --verbose
USER root
Any help is appreciated.

Solved by adding the following to my docker-compose.yml:
environment:
WATCHPACK_POLLING: "true"

Docker does not take care of the hot-reload.
You should look into the hot-reload documentation of the tools you are building with.

Related

Docker volume change owner to non-root

I want to create an uploads volume and set its owner to the node user. But upon running the container I find that the volume's owner is root. This is my Docker file:
FROM node:12.21
RUN apt-get update && apt-get -y install curl vim bash nano
WORKDIR /home/node/app
COPY package.json .
COPY yarn.lock .
RUN mkdir ./uploads
RUN chown -R node:node .
USER node
RUN yarn install
COPY --chown=node:node . .
VOLUME /home/node/app/uploads
I use docker-compose build then docker-compose up to build and run; my docker-compose.yml also contains a volume instruction:
services:
...
server:
...
volumes:
- ./uploads:/home/node/app/uploads
My tests show that this instruction in docker-compose.yml is what's causing the problem -- without it the uploads directory owner is correctly set to node -- but I don't understand why. Is the instruction in docker-compose.yml redundant in this case? How about if I wanted to map the volume to a local directory (for which I believe this instruction would be necessary)?
Bind volume will retain the origin ownership on the host. You can either change mode the directory on the host to 77x, or you can try this way.
Update: Base on your feedback, you can add the chmod in your docker startup script.

Module Not found after attaching volume in docker

This is my dockerfile
FROM node:15
# sets the folder structure to /app directory
WORKDIR /app
# copy package.json to /app folder
COPY package.json .
RUN npm install
# Copy all files from current directory to current directory in docker(app)
COPY . ./
EXPOSE 3000
CMD ["node","index.js"]
I am using this command in my powershell to run the image in a container
docker run -v ${pwd}:/app -p 3000:3000 -d --name node-app node-app-image
${pwd}
returns the current directory.
But as soon as I hit enter, somehow node_modules isn't being installed in the container and I get "express not found" error in the log.
[![Docker log][1]][1]
I can't verify if node_modules isn't being installed because I can't get the container up to run the exec --it command.
I was following a freecodecamp tutorial and it seems to work in his pc and I've tried this command in command prompt too by replacing ${pwd} by %cd%.
This used to work fine before I added the volume flag in the command.
[1]: https://i.stack.imgur.com/4Fifu.png
Your problem was you build your image somewhere and then try to map another folder to it.
|_MyFolder/
|_ all-required-files
|_ all-required-folders
|_ Dockerfile
docker build -t node-app-image .
docker run -p 3000:3000 -d --name node-app node-app-image
Simplified Dockerfile
FROM node:15
# sets the folder structure to /app directory
WORKDIR /app
# Copy all files from current directory to current directory in docker(app)
COPY . ./
RUN npm install
EXPOSE 3000
CMD ["node","index.js"]

How to avoid node_modules folder being deleted

I'm trying to create a Docker container to act as a test environment for my application. I am using the following Dockerfile:
FROM node:14.4.0-alpine
WORKDIR /test
COPY package*.json ./
RUN npm install .
CMD [ "npm", "test" ]
As you can see, it's pretty simple. I only want to install all dependencies but NOT copy the code, because I will run that container with the following command:
docker run -v `pwd`:/test -t <image-name>
But the problem is that node_modules directory is deleted when I mount the volume with -v. Any workaround to fix this?
When you bind mount test directory with $PWD, you container test directory will be overridden/mounted with $PWD. So you will not get your node_modules in test directory anymore.
To fix this issue you can use two options.
You can run npm install in separate directory like /node and mount your code in test directory and export node_path env like export NODE_PATH=/node/node_modules
then Dockerfile will be like:
FROM node:14.4.0-alpine
WORKDIR /node
COPY package*.json ./
RUN npm install .
WORKDIR /test
CMD [ "npm", "test" ]
Or you can write a entrypoint.sh script that will copy the node_modules folder to the test directory at the container runtime.
FROM node:14.4.0-alpine
WORKDIR /node
COPY package*.json ./
RUN npm install .
WORKDIR /test
COPY Entrypoint.sh ./
ENTRYPOINT ["Entrypoint.sh"]
and Entrypoint.sh is something like
#!/bin/bash
cp -r /node/node_modules /test/.
npm test
Approach 1
A workaround is you can do
CMD npm install && npm run dev
Approach 2
Have docker install node_modules on docker-compose build and run the app on docker-compose up.
Folder Structure
docker-compose.yml
version: '3.5'
services:
api:
container_name: /$CONTAINER_FOLDER
build: ./$LOCAL_FOLDER
hostname: api
volumes:
# map local to remote folder, exclude node_modules
- ./$LOCAL_FOLDER:/$CONTAINER_FOLDER
- /$CONTAINER_FOLDER/node_modules
expose:
- 88
Dockerfile
FROM node:14.4.0-alpine
WORKDIR /test
COPY ./package.json .
RUN npm install
# run command
CMD npm run dev

Unable to locate file in docker container

I'm new to docker and creating a simple test app to test my docker container, but docker unable to locate the server.py file.
The directory structure of my project is:
<project>
|
|-- Dockerfile
|-- app
|
|-- requirements.txt
|-- server.py
Below is the Dockerfile content:
FROM ubuntu:latest
MAINTAINER name <mail#domain.com>
COPY . /app # do I need this ?
COPY ./app/requirements.txt /tmp/requirements.txt
RUN apt-get -y update && \
apt-get install -y python-pip python-dev build-essential
RUN pip install -r /tmp/requirements.txt
WORKDIR /app
RUN chmod +x server.py # ERROR: No such file or directory
EXPOSE 5000
ENTRYPOINT ["python"]
CMD ["server.py"] # ERROR: No such file or directory
I'm using boot2docker on windows.
What am I missing here?
You're copying your local /app/ folder to the /app/ folder in the running Docker container (as mentioned in the comments) creating /app/app/server.py in the Docker container.
How to resolve
A simple fix will be to change
COPY . /app
to
COPY ./app/server.py /app/server.py
Explanation
The command COPY works as follows:
COPY <LOCAL_FROM> <DOCKER_TO>
You're selecting everything in the folder where the Dockerfile resides, by using . in your first COPY, thereby selecting the local /app folder to be added to the Docker's folder. The destination you're allocating for it in the Docker container is also /app and thus the path in the running container becomes /app/app/.. explaining why you can't find the file.
Have a look at the Docker docs.

Babelrc file in Docker builds

I'm running into the errors:
ERROR in ../~/babel-polyfill/lib/index.js
Couldn't find preset "es2015-loose" relative to directory "/app"
amongst a few other preset not found errors upon building a ReactJS project. It runs on webpackdevserver in dev.
COPY in Docker doesn't copy over dot files by default. Should I be copying .babelrc over to avoid this breaking? How to do this if so. If not, what am I missing/wrong ordering in this build?
Dockerfile
FROM alpine:3.5
RUN apk update && apk add nodejs
RUN npm i -g webpack \
babel-cli \
node-gyp
ADD package.json /tmp/package.json
RUN cd /tmp && npm install
RUN mkdir -p /app && cp -a /tmp/node_modules /app/
WORKDIR /app
COPY . /app
docker-compose
version: '2.1'
services:
webpack:
build:
context: .
dockerfile: Docker.doc
volumes:
- .:/app
- /app/node_modules
COPY in Docker doesn't copy over dot files by default.
This is not true. COPY in the Dockerfile copies dot files by default. I came across this question as I had faced this issue earlier. For anyone else who may encounter this issue, troubleshoot with the following:
Check your host/local directory if the dotfiles exists. If you are copying the files over from your OS's GUI, there's a chance that the dotfiles will not be ported over simply because they are hidden.
Check if you have a .dockerignore file that may be ignoring these dotfiles. More info from .dockerignore docs

Resources