Docker / docker-compose workflow: angular changes not being reflected - node.js

When I make changes to my app source code and rebuild my docker images, the changes are not being reflected in the updated containers. I have:
Checked that the changes are being pulled to the remote machine correctly
Cleared the browser cache and double checked with different browsers
Checked that the development build files are not being pulled onto the remote machine by mistake
Banged my head against a number of nearby walls
Every time I pull new code from the repo or make a local change, I do the following in order to do a fresh rebuild:
sudo docker ps -a
sudo docker rm <container-id>
sudo docker image prune -a
sudo docker-compose build --no-cache
sudo docker-compose up -d
But despite all that, the changes do not make it through - I simply dont know how it isn't working as the output during build appears to be taking the local files. Where can it be getting the old files from, cos I've checked and double checked that the local source has changed?
Docker-compose:
version: '3'
services:
angular:
build: angular
depends_on:
- nodejs
ports:
- "80:80"
- "443:443"
volumes:
- certbot-etc:/etc/letsencrypt
- certbot-var:/var/lib/letsencrypt
- web-root:/usr/share/nginx/html
- ./dhparam:/etc/ssl/certs
- ./nginx-conf/prod:/etc/nginx/conf.d
networks:
- app-net
nodejs:
build: nodejs
ports:
- "8080:8080"
volumes:
certbot-etc:
certbot-var:
web-root:
Angular dockerfile:
FROM node:14.2.0-alpine AS build
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
# install and cache app dependencies
COPY package.json /app/
RUN apk update && apk add --no-cache bash git
RUN npm install
COPY . /app
RUN ng build --outputPath=./dist --configuration=production
### prod ###
FROM nginx:1.17.10-alpine
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80 443
CMD ["nginx", "-g", "daemon off;"]

I found it. I followed tutorial to get https to work, and thats where the named volumes came in. Its a two step process, and it needed all those named volumes for the first step, but the web-root volume is what was screwing things up; deleting that solved my problem. At least I understand docker volumes better now...

Related

Node.js docker container not updating to changes in volume

I am trying to host a development environment on my Windows machine which hosts a frontend and backend container. So far I have only been working on the backend. All files are on the C Drive which is shared via Docker Desktop.
I have the following docker-compose file and Dockerfile, the latter is inside a directory called backend within the root directory.
Dockerfile:
FROM node:12.15.0-alpine
WORKDIR /usr/app
COPY package*.json ./
RUN npm install
EXPOSE 5000
CMD [ "npm", "start" ]
docker-compose.yml:
version: "3"
services:
backend:
container_name: backend
build:
context: ./backend
dockerfile: Dockerfile
volumes:
- ./backend:/usr/app
environment:
- APP_PORT=80
ports:
- '5000:5000'
client:
container_name: client
build:
context: ./client
dockerfile: Dockerfile
volumes:
- ./client:/app
ports:
- '80:8080'
For some reason, when I make changes in my local files they are not reflecting inside the container. I am testing this by slightly modifying the outputs of one of my files, but I am having to rebuild the container each time to see the changes take effect.
I have worked with Docker in PHP applications before, and have basically done the same thing. So I am unsure why this is not working with by Node.js app. I am wondering if I am just missing something glaringly obvious as to why this is not working.
Any help would be appreciated.
The difference between node and PHP here is that php automatically picks up file system changes between requests, but a node server doesn't.
I think you'll see that the file changes get picked up if you restart node by bouncing the container with docker-compose down then up (no need to rebuild things!).
If you want node to pick up file system changes without needing to bounce the server you can use some of the node tooling. nodemon is one: https://www.npmjs.com/package/nodemon. Follow the installation instructions for local installation and update your start script to use nodemon instead of node.
Plus I really do think you have a mistake in your dockerfile and you need to copy the source code into your working directory. I'm assuming you got your initial recipe from here: https://dev.to/alex_barashkov/using-docker-for-nodejs-in-development-and-production-3cgp. This is the docker file is below. You missed a step!
FROM node:10-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
CMD [ "npm", "start" ]

Docker with nodemon does not reload my api when code changes

I've been working with docker some weeks ago and I was able to hold this issue, stop docker containers and start them over again to see the changes that I had made in my code but now is really anoying because every single change I do have to kill docker and then "docker-compose up".
However my friend is using the same container on his apple machine but when he makes changes to any server side code he does not have to restart his app.
I can see the changes when I go into the container but those changes are not reflected on live(browser).
My Dockerfile
FROM node:8.11.3
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
# Copy application files
COPY tools ./tools/
COPY migrations ./migrations/
COPY seeds ./seeds/
# Attempts to copy "build" folder even if it doesn't exist
COPY .env build* ./build/
RUN npm install -g nodemon
RUN git clone https://github.com/vishnubob/wait-for-it.git
EXPOSE 8080
CMD ["nodemon", "-L", "server"]
My docker-compose.yml
api:
build: ./
hostname: api
container_name: api
ports:
- "${APP_PORT}:3000"
volumes:
- ./:/usr/src/app
env_file:
- ".env"
command: node tools/run.js
Any sugestion?

docker container crashes with exited with code 139

I have this docker file build/and run an node application
# ---- Base Node ----
FROM node:10 AS base
# Create app directory
WORKDIR /app
# ---- Dependencies ----
FROM base AS dependencies
COPY package.json ./
# install app dependencies including 'devDependencies'
RUN npm install
# ---- Copy Files/Build ----
FROM dependencies AS build
WORKDIR /app
COPY . /app
# Build the app
RUN npm run build
WORKDIR /app/dist
# install npm models in dist
RUN npm install --only=production
# --- Release with Alpine ----
FROM node:10-alpine AS release
# Create app directory
WORKDIR /app
# optional
ENV NODE_ENV=development
ENV MONGO_HOST=mongodb://localhost/chronas-api
ENV MONGO_PORT=27017
ENV PORT=80
# copy app from build
COPY --from=build /app/dist/ ./
CMD ["node", "index.js"]
and using this docker-compose file
version: '3'
services:
database:
image: mongo
container_name: mongo
ports:
- "27017:27017"
app:
build: .
container_name: chronas_api
ports:
- "80:80"
- "5858:5858"
links:
- database
environment:
- JWT_SECRET='placeholder'
- MONGO_HOST=mongodb://database/chronas-api
- APPINSIGHTS_INSTRUMENTATIONKEY='placeholder'
- TWITTER_CONSUMER_KEY=placeholder
- TWITTER_CONSUMER_SECRET=placeholder
- TWITTER_CALLBACK_URL=placeholder
- PORT=80
depends_on:
- database
stdin_open: true
tty: true
always when I try to write to the mongodb the node container crashes with this error:
exited with code 139
can anyone help? When I run the application only with docker it works fine
The issue may be caused by the fact that node:10-alpine is a tag where the underlying image may change with updates, so when you are building the same app without using compose it won't pull the most recent image, docker-compose will do a pull from the docker hub instead.
Images based on alpine may have some dependency issues that are quite hard to debug from one version to another, you can find some possibilities for this particular issue here
I was using the tag node:8-alpine in my application and I found out that the current latest node:8.15.1-alpine is causing the Exited with code 139 issue that was not present in the previous image node:8.15.0-alpine. Downgrading may be the easiest solution to solve this kind of issue, check if you are using bcrypt too.
Another option is to use a debian based image that will be less likely to have this kind of issues (just consider it's slighly bigger in size).

Docker port forwarding for nodejs app

I'm having problems configuring docker for my nodejs app.
I have previously set up containers for both php and rails with port forwarding working flawlessly, but for this instance i can't seem to get it to work.
Running: docker ps, i get the following:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a60f9c82d600 29c7d94a8c58 "/bin/sh -c 'npm s..." 5 seconds ago Up 3 seconds 3000/tcp romantic_albattani
As you can see I'm not getting the usual: 0.0.0.0:3000->3000/tcp that I am expecting.
docker-compose ps gives:
Name Command State Ports
------------------------------
My docker-compose.yml:
web:
build: .
volumes:
- .:/app
volumes_from:
- box
ports:
- "3000:3000"
box:
image: busybox
volumes:
- /node_modules
My Docker file:
FROM node:8.7.0
# The base node image sets a very verbose log level.
ENV NPM_CONFIG_LOGLEVEL warn
WORKDIR /tmp
COPY package.json /tmp/
RUN npm install
WORKDIR /app
ADD . /app
RUN cp -a /tmp/node_modules /app/
#ENV PORT=3000
EXPOSE 3000
CMD npm start
I'm running the command: docker-compose up --build
Any help at this point is appreciated.
I don't know if a docker inspect would be useful, but if so, tell me and i will also post it.
Edit: Changed my Dockerfile to follow the answer.
Your docker-compose.yml file has bad formatting, since you are not getting any errors i will assume you pasted it here wrong, here is the version with the fixed indenting:
web:
build: .
volumes:
- .:/app
volumes_from:
- box
ports:
- "3000:3000"
box:
image: busybox
volumes:
- /node_modules
Your Dockerfile has a bug, you are missing the ENTRYPOINT and/or CMD stanzas, instead you are using the RUN stanza with the wrong intent, here is a working Dockerfile with the fix applied:
FROM node:8.7.0
# The base node image sets a very verbose log level.
ENV NPM_CONFIG_LOGLEVEL warn
WORKDIR /tmp
COPY package.json /tmp/
RUN npm install
WORKDIR /app
ADD . /app
RUN cp -a /tmp/node_modules /app/
#ENV PORT=3000
EXPOSE 3000
CMD npm start
Your Dockerfile halted the execution of docker-compose at the docker image building stage because of the RUN npm start which is a process that starts and listens until stopped (because you want it to start your node app and listen for connections) causing docker-compose to never finish the docker image creating step, let alone the other steps like creating the needed containers and finish the entire docker-compose runtime process.
In short:
When you use RUN it is meant to run a command do some work and return sometime to continue the building process, it should return and exit code of 0 and the process will move on to the next Dockerfile stanza, or return another exit code and the building process will fail with an error.
When you use CMD you tell the docker image what is the starting command of all the containers started from this image (it can also be overridden at run time with docker run). It is tightly related to the ENTRYPOINT stanza, but for basic usage you are safe with the default.
Further reading: ENTRYPOINT, CMD and RUN

Docker with node bcrypt — invalid ELF header

I've tried every solution from this post and this post
I'm not finding a solution to get rid of the following error when running docker-compose up:
module.js:598
return process.dlopen(module, path._makeLong(filename));
^
Error: /code/node_modules/bcrypt/lib/binding/bcrypt_lib.node: invalid ELF header
Here's my latest attempt docker-compose.yml
version: "2"
services:
app:
build: ./client
ports:
- "3000:3000"
links:
- auth
volumes:
- ./client:/code
auth:
build: ./auth-service
ports:
- "3002:3002"
links:
- db
volumes:
- ./auth-service:/code
db:
...
And my auth service Dockerfile:
FROM node:7.7.1
EXPOSE 3002
WORKDIR /code
COPY package.json /code
RUN npm install
COPY . /code
CMD npm start
After trying each of the solution from the above two links, I rebuild the containers and it always results in the same error.
Also worth noting, the service runs fine locally, when I don't use docker.
How do I get docker to work with bcrypt?
Update
I was able to get it working by doing the following:
finding the id of the container: docker ps
accessing the container: docker exec -t -i containerId /bin/bash
installing bcrypt: npm install bcrypt
This isn't ideal for portability
I spent a few hours trying to solve this and in the end I came up with the following solution.
My compose file looks like this.....
version: "3"
services:
server:
build:
context: ./server
volumes:
- ./server:/usr/src/app
- /usr/src/app/node_modules/
ports:
- 3050:3050
depends_on:
- db
command: ["nodemon", "./bin/www"]
The second volume mount there is the important one as this gets around the local node_module issue.
Just for reference my dockerfile is like this:
FROM node
RUN npm install -g nodemon
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json /usr/src/app
RUN npm install
EXPOSE 3050
CMD ["nodemon", "./bin/www"]
was struggling with this one few times, the ".dockerignore" solution wont work if you use volumes sadly, since its only related to the "Copy" command and only when you build the container.
the only solution i found which i think makes the most sense, is to volume only what you need, what does it mean - divide your source code and the "configurations" files (such as package.json):
- src
-- morecode
-- morecode2
-- server.js
- index.js
- package.json
- jslint.json
- tsconfig.json
- .env
- .dockerignore
- ... etc
and put the volume only on the "src" folder, that way your builds will also be much faster plus your node modules will be built and installed on the correct operation system, d'ont forget to add .dockerignore to node_modules to prevent builds form taking unnecessary longer time
do note that doing so will require re-build of the application every time your adding new package, but if you use npm best practice and you divide the npm installation in your docker file to be cached, it will be faster
The reason this error occurs is that the node module bcrypt is first compiled on your original machine (specific for your OS) and when an image is built on docker it cannot run since the OS is no longer the same. solution create a .dockerignore file in your root folder and add node_modules to this file.

Resources