Docker wait for web app to start (dependency) - node.js

Short question. I have the following Dockerfile:
FROM node:6.9.2
RUN apt-get update
RUN useradd --user-group --create-home --shell /bin/false app
ENV HOME=/home/app
RUN mkdir -p $HOME
RUN chown -R app:app $HOME
USER app
WORKDIR $HOME/
VOLUME ["/home/app/uploads"]
EXPOSE 5001
CMD [ "npm", "run", "test-integration" ]
and the corresponding docker-compose:
version: '2.0'
services:
komed-test-integration:
image: borntraegermarc/komed-test-integration
container_name: komed-test-integration
build: .
depends_on:
- komed-app
- komed-mongo
volumes:
- .:/home/app
environment:
- HOST_URL=komed-app
- HOST_PORT=5001
- MONGO_HOST=komed-mongo
- MONGO_DATABASE=komed-health
I have the dependency to komed-app in my compose file and that works fine. But how do I wait for these integration tests to start until the web server (komed-app) is actually running? Tried with CMD [ "./wait-for-it.sh", "komed-app-test:5001", "--", "npm", "run", "test-integration" ] but didn't work. Always get the error exited with code 127.
Any ideas?

The best practice is described in Controlling startup order in Compose.
You can either use depends-on or (better) vishnubob/wait-for-it (which you did).
127 is mentioned in this issue, when the timeout fails.
Docker node 6.9.2 depends on jessie, not Alpine, so it should not be affected by issue 6: so try and debug the script, by adding -x to the first line
#!/usr/bin/env bash -x
You will see which exit $RESULT produced that 127 error code.
The OP Marc Borni confirms in the comments the origin of the issue: windows file encoding for a unix script.
Sometimes, using dos2unix directly in a Dockerfile can help.

Related

Docker container can't find file

Github repo here.
I have a runshortcuts.sh bash script I set up to deploy different parts of my app for dev or prod. I can run it from the project's root directory with ./runshortcuts.sh $args. I mapped the root of my project directory to /usr/src/app and verified with ls that the project root directories look the same on my machine and in the container.
For whatever reason I can't execute runshortcuts.sh from within the docker container and get "OCI runtime exec failed: exec failed: unable to start container process: exec ./runshortcuts.sh: no such file or directory: unknown". Its permissions are -rwxrwxr-x according to ls -l. Wrapping it in a sh also fails as sh can't find the file. I am clueless as to why this is, any ideas?
I'm using the node 14-alpine base image. My Docker setup is quite minimal:
Dockerfile:
FROM node:14-alpine
WORKDIR /usr/src/app
VOLUME /usr/src/app
docker-compose.yaml:
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "3000:3000"
- "5000:5000"
volumes:
- .:/usr/src/app
tty: true
When I docker-compose up -d and docker ps -a I see:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bdaac49268d0 fiction-forge_app "docker-entrypoint.s…" About a minute ago Up 5 seconds 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp, 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp fiction-forge_app_1
The problem comes from your script you are using a #!/bin/bash and that bash is not available in the default packages of alpine.
Using #!/bin/sh should fix the problem.

NestJS start command returning Killed with no error in conatiner

I am trying to get NestJS up and running in my container. Currently, I have this set up as my docker-compose.yml
services:
redis-cluster:
image: internal-repo.com/devops/redis-cluster:5.0.5
ports:
- 7000:7000
- 7001:7001
- 7002:7002
- 7003:7003
- 7004:7004
- 7005:7005
- 7006:7006
- 7007:7007
- 7008:7008
environment:
IP: 0.0.0.0
MASTERS: 3
SLAVES_PER_MASTER: 2
app-orders:
image: app-orders
build:
context: ..
dockerfile: $PWD/Dockerfile
working_dir: /workspace
depends_on:
- 'redis-cluster'
environment:
NODE_ENV: development
volumes:
- ..:/workspace
ports:
- 50099:9229
- 3000:3000
command: /bin/sh -c "while sleep 1000; do :; done"
I have this for my Dockerfile
FROM internal-repo.com/devops/node/ubuntu-1804:12.16.2 as build-env
ENV NODE_VERSION 12.16.2
WORKDIR /workspace
RUN apt-get update && apt install python -y
# Ensure the image timezone mirrorsCorp HQ
ENV TZ=America/Los_Angeles
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
COPY .devcontainer/library-scripts/docker-debian.sh /tmp/library-scripts/
COPY package.json package.json
RUN npm i -g nodemon
RUN npm i -g #nestjs/cli
RUN npm install
# App specific environment
ENV PACKAGE_JSON_PATH ../package.json
I have set my docker to run the sleep command so I can start this container and run an interactive shell with it. If i tried to put the npm command as the run, it would just crash after a few minutes.
In an interactive shell, I have tried running npm start:dev which uses rimraf to remove the dist folder and then run nest start --watch. The problem is, it will run for a little bit, generate the new dist folder and then promptly die. It only says in the npm log Error 147. If i try to run the nest start --watch manually, it sits for a little bit saying 'Starting compilation in Watch Mode' and just says "Killed". I don't know why it is failing or what to fix.
The odd thing is, if I don't try and run it in the container, it will run fine on my mac (assuming i have the redis cluster up and running already in a container)

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

How do I expose ports in Docker on Windows 10?

I have a properly installed copy of Docker CE on my Windows 10 Pro machine.
I am trying to run a simple node app using docker-compose and be able to dynamically update the code while running in docker. I followed this website to build it out, and my code can be found here.
When I navigate to localhost:8080 while running the code locally, I get my web page. When I run it through Docker, I get "This page isn't working" from my web browser (same url). I have made sure to stop running locally before running in Docker so that the ports aren't crossed.
My Dockerfile:
FROM node:6.10.2
RUN useradd --user-group --create-home --shell /bin/false app
ENV HOME=/home/app
COPY package.json npm-shrinkwrap.json $HOME/diet-program/
RUN chown -R app:app $HOME/*
USER app
WORKDIR $HOME/diet-program
RUN npm install
EXPOSE 8080
CMD ["npm", "run", "dev"]
My docker-compose.yml:
version: '2'
services:
diet-program:
build: .
ports:
- "8080:8080"
volumes:
- .:/home/app/diet-program
- /home/app/diet-program/node_modules
The dev command is mapped to: webpack-dev-server --content-base src --inline --hot
For expose ports try to change line
ports:
- 8080:8080
into
ports:
- "8080:8080"
in docker-compose.yml file
More details about expose ports here: https://docs.docker.com/compose/compose-file/#ports
For check if you call a correct IP check with command docker inspect <container_name> in "NetworkSettings" and look at IPAddress.

Docker compose not finding my index.js

I'm following this guide and use my low docker knowledge to get a dev environment up and running. I've hit a wall I cannot solve. This is my docker-compose.yml:
version: '2'
services:
redis:
image: redis:3.2
mongo:
image: mongo:3.2
app:
build: .
ports:
- '3000:3000'
command: './node_modules/.bin/nodemon ./index.js'
environment:
NODE_ENV: development
volumes:
- .:/home/app/cardcreator
- /home/app/cardcreator/node_modules
depends_on:
- redis
- mongo
links:
- redis
- mongo
and this is my Dockerfile:
FROM node:6.3.1
RUN useradd --user-group --create-home --shell /bin/false app
ENV HOME=/home/app
COPY package.json npm-shrinkwrap.json $HOME/cardcreator/
RUN chown -R app:app $HOME/*
USER app
WORKDIR $HOME/cardcreator
RUN npm install
USER root
COPY . $HOME/cardcreator/
RUN chown -R app:app $HOME/*
USER app
CMD ["node", "index.js"]
When I try to start the app via docker-compose up, I get the error
app_1 | Usage: nodemon [nodemon options] [script.js] [args]
app_1 | See "nodemon --help" for more.
I then removed the command line of my docker-compose.yml, only leaving node index.js to start. I get an error saying index.js cannot be found.
The file is in my project folder, it is there and it has content. I can't figure out why this setup doesn't work, I did similar setups for tails and it worked fine.
Can anyone tell me what I'm doing wrong here?
Whatever you are mounting in your compose file here:
- .:/home/app/cardcreator
Is going to mount on top of whatever you built in $HOME/cardcreator/ in your Dockerfile.
So basically you seem to have conflicting volumes -- it's an order of operations issue -- the build is going to happen first and the volume mount happens later when the container runs, so your container will no longer have access to the files built in the Dockerfile.
You could try to use
docker exec -it app_1 bash
to go into the container, trying to execute the
node index.js
command manually and see what's going on. Not 100% sure if the 'node' docker images have bash installed though..

Resources