docker - image not updating after building - node.js

After I run docker-compose up -d --build, I run docker images, it shows:
REPOSITORY TAG IMAGE ID CREATED SIZE
test-tets-test-server_my-web latest 2a3f05e387a7 1 minutes ago 2.81GB
But When I run docker run -it 2a3f05e387a7 sh and look for the files, it seems that the files are not updating and still in old version.
Dockerfile
FROM node:lts-alpine
RUN npm install --global sequelize-cli nodemon
WORKDIR /server
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3030
CMD ["npm", "run", "dev"]
docker-compose.yml
version: '2.1'
services:
test-db:
image: mysql:5.7
...
test-web:
environment:
- NODE_ENV=local
- PORT=3030
build: .
command: >
./wait-for-db-redis.sh test-db npm run dev
volumes:
- ./:/server
ports:
- "3030:3030"
depends_on:
- test-db
package.json
...
"scripts": {
"test": "npm run lint && npm run mocha",
"lint": "eslint src/. test/. --config .eslintrc.json --fix",
"dev": "nodemon --legacy-watch src/",
"start": "node src/",
},
...

Since docker-compose up -d --build does not recreate, you may still see the old file, or they may be cache.
Run docker-compose up -d --build --force-recreate to force it recreate the image.

Related

Running Nodemon in Docker Container

I'm trying to run Nodemon package in a Docker Network with two services, NodeJs and MongoDB.
When I run the app with npm start, nodemon works: I can connect to localhost:3000 and I have the changes in real time. But as soon as I run npm run docker (docker-compose up --build), I can connect to localhost:3000 but I'm not able to see real-time changes on my application nor console.
docker-compose.yml
version: '3.7'
services:
app:
container_name: NodeJs
build: .
volumes:
- "./app:/usr/src/app/app"
ports:
- 3000:3000
mongo_db:
container_name: MongoDB
image: mongo
volumes:
- mongo_db:/data/db
ports:
- 27017:27017
volumes:
mongo_db:
dockerfile
FROM node:alpine
WORKDIR /app
COPY package.json /.
RUN npm install
COPY . /app
CMD ["npm", "run", "dev"]
package.json
{
"name": "projectvintedapi",
"version": "0.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node index.js",
"dev": "nodemon index.js",
"docker": "docker-compose up --build"
},
"license": "ISC",
"dependencies": {
"dotenv": "^16.0.0",
"express": "^4.17.3",
"mongodb": "^4.5.0",
"nodemon": "^2.0.15"
}
}
docker-compose.yml tells Docker to boot a container, the Node.js application. It also tells Docker to mount a host volume:
volumes:
- "./app:/usr/src/app/app"
As a result, Docker will mount the ./app directory on your laptop, which contains your code, into the container at /usr/src/app/app.
Once you’ve changed your code on your laptop/desktop, nodemon detects that change and restarts the process without rebuilding the container. To make this happen, you need to tell Docker to set the entrypoint to nodemon. Do that in the Dockerfile:
FROM node:alpine
WORKDIR /app
COPY . /app
RUN npm install -g nodemon
RUN npm install
#Give the path of your endpoint
ENTRYPOINT ["nodemon", "/usr/src/app/server.js"]
CMD ["npm", "run", "dev"]
With host volumes and nodemon, your code sync is almost instantaneous.
Fixed it: it was for bind mount
dockerfile
FROM node:16.13.2
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . ./
CMD ["npm", "run", "start"]
docker-compose.yml
version: '3.7'
services:
app:
container_name: NodeJs
build: .
command: npm run dev
volumes:
- .:/app
ports:
- 3000:3000
mongo_db:
container_name: MongoDB
image: mongo
volumes:
- mongo_db:/data/db
ports:
- 27017:27017
volumes:
mongo_db:

docker-compose setup node app - deep dive

I am getting a npm ERR! enoent ENOENT: no such file or directory, open '/usr/src/app/package.json' error currently with the below docker setup or a error TS2307: Cannot find module 'Actions' or its corresponding type declarations- i think its a case that the paths are not found in tsconfig.json during the build or i am not COPYing the correct directory/volume as part of the Dockerfile. Have spent multiple days working through different path configs / setups, any help getting this to build would be greatly appreciated.
Would love to see a node / TS / docker / mysql project example if there are any in the community to share - have found it difficult to find opensource projects to compare this to for hints.
...
"paths": {
"Actions/*": [
"Actions/*"
],
}
docker-compose
version: '3.8'
services:
app:
image: app:latest
container_name: balanced-money-backend
build:
context: .
dockerfile: Dockerfile
# TODO investigate uid and gid, how does it get in - from a startup script? Think it needs to be added like user: $UID:$GID if my cmd calls a setup to id on host machine. Needs more investigation.
depends_on:
db:
condition: service_healthy
env_file:
- .env
restart: always
volumes:
- .:/var/www/
command: npm start
ports:
- $NODE_LOCAL_PORT:$NODE_DOCKER_PORT
environment:
- DB_HOST=$MYSQL_HOST
- DB_USERNAME=$MYSQL_USER
- DB_PORT=$MYSQL_DOCKER_PORT
- DB_PASSWORD=$MYSQL_PASSWORD
- DB_DATABASE=$MYSQL_DATABASE
db:
image: mysql:5.7
restart: always
container_name: balanced-money-database
environment:
- MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD
- MYSQL_USER=$MYSQL_USER
- MYSQL_PASSWORD=$MYSQL_PASSWORD
- MYSQL_DATABASE=$MYSQL_DATABASE
ports:
- $MYSQL_LOCAL_PORT:$MYSQL_DOCKER_PORT
volumes:
- db:/var/lib/mysql
healthcheck: # mysql does not start immediatly, app needs to wait for mysql to start, having condition: service_healthy on app and a healthcheck makes sure db has started before app... i think.
test: mysqladmin ping -h 127.0.0.1 -u $$MYSQL_USER --password=$$MYSQL_PASSWORD
timeout: 20s
retries: 10
volumes:
db:
Dockerfile
############### Stage 1 - build the project
# use alpine version of node to keep the image size small as possible
FROM node:16-alpine AS build
# node docs recommend this
WORKDIR /usr/src/app
# docker caches per row as it builds, so copy those files which do not change often to the container first and following builds will not need copy as they are already cached by Docker.
COPY package*.json ./
COPY src tsconfig.json ./
RUN npm install
RUN npm run build
# TODO not sure about the stages - can i have a test / dev stage so test / dev is run in docker too.
############### Stage 2 - run the project
FROM build AS prod
EXPOSE 4000
# from stage 1, i.e. build take the code in the dist / package.json and copy to the container
COPY --from=build /usr/src/app/dist ./dist/
COPY --from=build /usr/src/app/package*.json ./
# npm ci will install exact versions from a package-lock file, and --production will only install dependencies, not dev dependencies.
RUN npm ci --production && npm cache clean --force
# make sure user is not root which could have security consequences.
USER node
CMD ["node", "dist/index.js"]
package.json scripts
"scripts": {
"build": "tsc",
"start": "node ./dist/index.js",
"node": "./dist/index.js",
"dev": "NODE_ENV=development DOTENV_CONFIG_PATH=.env.dev nodemon ts-node src/index.ts",
"format:prettier": "prettier --config .prettierrc 'src/**/*.ts' --write",
"lint": "eslint . --ext .ts",
"lint:fix": "eslint . --ext .ts --fix",
"test": "DOTENV_CONFIG_PATH=.env.test NODE_ENV=test jest --runInBand",
"test:coverage": "DOTENV_CONFIG_PATH=.env.test NODE_ENV=test jest --coverage",
},

Docker compose MongoDB with NodeJS using yarn

I'm trying to use docker compose to put in containers a node.js server and a mongodb database. I'm also trying to use yarn as my package-manager. My project is codded in typescript and my Mongodb is used as a service for my server.
For what I have at the moment, it works just fine, but I'm not sure if my implementation is even good. When I run docker-compose up, the containers and the images of node.js and mongodb are created, and the containers are running on the specified ports.
The problem is that when I kill the mongodb container, my nodejs server still has access to the database, like if my container mongodb container is still running. I would guess that it's because my mongodb server is also running on the same container as my node.js server.
This is my Dockerfile:
FROM node:lts-alpine
ADD package.json /app/package.json
ADD yarn.lock /app/yarn.lock
WORKDIR /app
# Installing packages
RUN yarn
ADD . /app
ENV NODE_ENV=production
# Building TypeScript files
RUN yarn build
CMD ["node", "./dist/app.js"]
These are the scripts in my package.json file:
"scripts": {
"lint": "eslint src/**/*.ts",
"format": "eslint src/**/*.ts --fix",
"start": "tsc && node --unhandled-rejections=strict ./dist/app.js",
"debug": "export DEBUG=* && npm run start",
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "ts-node src/app.ts",
"build": "rm -rf build && tsc -p ."
},
And this is my docker-compose.yml file:
version: "3"
services:
app:
container_name: app
restart: always
build:
context: .
dockerfile: Dockerfile
env_file: .env
volumes:
- ./src:/app/src
environment:
- COSMOSDB_HOST=${COSMOSDB_HOST}
- COSMOSDB_PORT=${COSMOSDB_PORT}
- COSMOSDB_DBNAME=${COSMOSDB_DBNAME}
- COSMOSDB_USER=${COSMOSDB_USER}
- COSMOSDB_PASSWORD=${COSMOSDB_PASSWORD}
ports:
- "4000:4000"
links:
- mongo
mongo:
container_name: mongo
image: mongo
ports:
- "27017:27017"
volumes:
- ./data:/data/db
I don't seem to understand what's wrong with my files...
Can you help me ? Also, would you have some recommendation to give me to optimize the build or anything else ? Thank you !

Nodemon -L not working using npm script from package.json on Docker

I am trying to set up a development environment on docker. I am running code that I made from this project.
I have seem several answers on stack-overflow but none of them solves my issue.
My package.json script is as below.
"ng": "ng",
"serve": "node server",
"start": "concurrently -c \"yellow.bold,green.bold\" -n \"SERVER,BUILD\" \"nodemon --legacy-watch ./server/index.js\" \"ng build --watch\"",
"build": "ng build --prod",
// more code...
My Dockerfile looks like this:
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install -g --force nodemon
RUN npm install
COPY . .
EXPOSE 4043
CMD ["npm", "start"]
My docker-compose.yml file looks as below:
services:
app:
container_name: express-ng-server
restart: always
image: express-ng-server-image
build: .
ports:
- '80:4043'
expose:
- 4043
When I do docker-compose up nodemon does react to code changes.
When I run npm start nodemon works as expected.
What am I doing wrong? How can I get nodemon to work in docker?
I am using the latest version of nodemon "nodemon": "^2.0.4",

How do I run a webpack build from a docker container?

The app I'm making is written in ES6 and other goodies is transpiled by webpack inside a Docker container. At the moment everything works from creating the inner directory, installing dependencies, and creating the compiled bundle file.
When running the container instead, it says that dist/bundle.js does not exist. Except if I create the bundle file in the host directory, it will work.
I've tried creating a volume for the dist directory at it works the first time, but after making changes and rebuilding it does not pick up the new changes.
What I'm trying to achieve is having the container build and run the compiled bundle. I'm not sure if the webpack part should be in the Dockerfile as a build step or at runtime since the CMD ["yarn", "start"] crashes but RUN ["yarn", "start"] works.
Any suggestions ands help is appreciated. Thanks in advance.
|_src
|_index.js
|_dist
|_bundle.js
|_Dockerfile
|_.dockerignore
|_docker-compose.yml
|_webpack.config.js
|_package.json
|_yarn.lock
docker-compose.yml
version: "3.3"
services:
server:
build: .
image: selina-server
volumes:
- ./:/usr/app/selina-server
- /usr/app/selina-server/node_modules
# - /usr/app/selina-server/dist
ports:
- 3000:3000
Dockerfile
FROM node:latest
LABEL version="1.0"
LABEL description="This is the Selina server Docker image."
LABEL maintainer="AJ alvaroo#selina.com"
WORKDIR "/tmp"
COPY ["package.json", "yarn.lock*", "./"]
RUN ["yarn"]
WORKDIR "/usr/app/selina-server"
RUN ["ln", "-s", "/tmp/node_modules"]
COPY [".", "./"]
RUN ["yarn", "run", "build"]
EXPOSE 3000
CMD ["yarn", "start"]
.dockerignore
.git
.gitignore
node_modules
npm-debug.log
dist
package.json
{
"scripts": {
"build": "webpack",
"start": "node dist/bundle.js"
}
}
I was able to get a docker service in the browser with webpack by adding the following lines to webpack.config.js:
module.exports = {
//...
devServer: {
host: '0.0.0.0',
port: 3000
},
};
Docker seems to want the internal container address to be 0.0.0.0 and not localhost, which is the default string for webpack. Changing webpack.config.js specification and copying that into the container when it is being built allowed the correct port to be recognized on `http://localhost:3000' on the host machine. It worked for my project; hope it works for yours.
I haven't included my src tree structure but its basically identical to yours,
I use the following docker setup to get it to run and its how we dev stuff every day.
In package.json we have
"scripts": {
"start": "npm run lint-ts && npm run lint-scss && webpack-dev-server --inline --progress --port 6868",
}
dockerfile
FROM node:8.11.3-alpine
WORKDIR /usr/app
COPY package.json .npmrc ./
RUN mkdir -p /home/node/.cache/yarn && \
chmod -R 0755 /home/node/.cache && \
chown -R node:node /home/node && \
apk --no-cache add \
g++ gcc libgcc libstdc++ make python
COPY . .
EXPOSE 6868
ENTRYPOINT [ "/bin/ash" ]
docker-compose.yml
version: "3"
volumes:
yarn:
services:
web:
user: "1000:1000"
build:
context: .
args:
- http_proxy
- https_proxy
- no_proxy
container_name: "some-app"
command: -c "npm config set proxy=$http_proxy && npm run start"
volumes:
- .:/usr/app/
ports:
- "6868:6868"
Please note this Dockerfile is not suitable for production it's for a dev environment as its running stuff as root.
With this docker file there its a gotcha.
Because alpine is on musl and we are on glib if we install node modules on the host the compiled natives won't work on the docker container, Once the container is up if you get an error we run this to fix it (its a bit of a sticking plaster right now)
docker-compose exec container_name_goes_here /bin/ash -c "npm rebuild node-sass --force"
ikky but it works.
Try changing your start script in the package.json to perform the build first (doing this, you won't need the RUN command to perform the build in your Dockerfile:
{
"scripts": {
"build": "webpack",
"start": "webpack && node dist/bundle.js"
}
}

Resources