Do I have to first have to clone the wait-for-it repo and edit the parts of the wait-for-it.sh file?
https://github.com/vishnubob/wait-for-it/blob/master/wait-for-it.sh
I'm trying to make my main file fire after 5 seconds after my customer service connects and run its server. (Or whenever customer service connects server properly).
I am aware that in the Dockerfile, we would need to add these commands to it (copying file into workdir, and run the shell script as an executable.)
...
COPY wait-for-it.sh .
RUN chmod +x /wait-for-it.sh
...
Here's my current Docker-Compose file
version: '3'
services:
books:
build: './books'
container_name: "horus-books"
ports:
- "30043:30043"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
customers:
depends_on:
- books
build: './customers'
container_name: "horus-customers"
ports:
- "6000:6000"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
main:
depends_on:
- customers
build: './main'
container_name: "horus-main"
ports:
- "4555:4555"
command: ["./wait-for-it.sh", "customers:6000", "--", "node", "main.js"]
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
Main Service Dockerfile
FROM node:12.14.0
WORKDIR /usr/src/app
COPY package*.json ./
COPY . /usr/src/app
COPY wait-for-it.sh .
RUN chmod +x /wait-for-it.sh
RUN npm install
EXPOSE 4555
CMD ["node", "main.js"]
The 'docker wait' is a command that is used to wait or block until one or more containers stop, and then it outputs their exit codes which means you cannot use your terminal if you are running the command on the terminal.
There's a good reason for this: The problem of waiting for a database (for example) to be ready is really just a subset of a much larger problem of distributed systems. In production, your database could become unavailable or move hosts at any time. Your application needs to be resilient to these types of failures.
depends_on is a Docker Compose keyword to set the order in which services must start and stop. For example, suppose we want our web application, which we'll build as a web-app image, to start after our Postgres container.
Generally you wouldn't put it in your docker-compose.yml
file at all. The script needs to be built into the image, and its standard startup sequence needs to know to run it.
There's a fairly common pattern of using an entrypoint script to do some initial setup, and then use exec "$@"
to run the container's command as the main process. This lets you, for example, use the wait-for-it.sh
script to wait for the backend to be up, then run whatever the main command happens to be. For example, a docker-entrypoint.sh
script might look like:
#!/bin/sh
# Abort on any error (including if wait-for-it fails).
set -e
# Wait for the backend to be up, if we know where it is.
if [ -n "$CUSTOMERS_HOST" ]; then
/usr/src/app/wait-for-it.sh "$CUSTOMERS_HOST:${CUSTOMERS_PORT:-6000}"
fi
# Run the main container command.
exec "$@"
You need to make sure this script is executable, and make it the image's ENTRYPOINT
, but otherwise you can leave the Dockerfile pretty much unchanged.
FROM node:12.14.0
WORKDIR /usr/src/app
COPY package*.json ./
# Do this _before_ copying the entire application in
# to avoid repeating it on rebuild
RUN npm install
# Includes wait-for-it.sh and docker-entrypoint.sh
COPY . ./
RUN chmod +x ./wait-for-it.sh ./docker-entrypoint.sh
EXPOSE 4555
# Add this line
# It _must_ use the JSON-array syntax
ENTRYPOINT ["./docker-entrypoint.sh"]
CMD ["node", "main.js"]
In your docker-compose.yml
you need to add the configuration to say where the backend is, but you do not need to override command:
.
main:
depends_on:
- customers
build: './main'
ports:
- "4555:4555"
environment:
- CUSTOMERS_HOST=customers
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With