wait-for-it icon indicating copy to clipboard operation
wait-for-it copied to clipboard

Usage with Docker

Open agustisanchez opened this issue 7 years ago • 16 comments

In order to use it with Docker and docker-compose, place it alongside Dockerfile, build it into the image with exec permissions and reference it in docker-compose.yml.

- Dockerfile
- wait-for-it.sh
#Dockerfile
...
COPY wait-for-it.sh /wait-for-it.sh
RUN chmod +x /wait-for-it.sh
...
#docker-compose.yml
...
  my-service:
    build:
      context: "."
      container_name: my_container
      command: ["/wait-for-it.sh", "mysql:3306", "--", [entrypoint function]]
...

agustisanchez avatar Mar 05 '18 19:03 agustisanchez

Thanks @agustisanchez - I like it. Depending on your setup, you might also copy wait-for-it.sh in as a mounted volume, such as this:

version: '3'

services:
  hello-world:
    image: ubuntu
    volumes:
      - ./wait-for-it.sh:/usr/local/bin/wait-for-it.sh
    command:
      - wait-for-it.sh
      - github.com:80
      - --
      - echo
      - "hello world"

douglas-gibbons avatar Nov 04 '18 00:11 douglas-gibbons

Depending on the base image used there will be no netcat available in the container. The description pure bash conflicts in this case with the fact that netcat is no shell builtin. No offense intended.

Cheers

portolkyz avatar Jan 09 '19 13:01 portolkyz

Can you tell me what my Entrypoint is? Given are the following snippets.

#Dockerfile

FROM java:8
VOLUME /tmp
EXPOSE 8080
COPY wait-for-mysql.sh /wait-for-mysql.sh
RUN chmod +x /wait-for-mysql.sh
ADD target/App.jar App.jar.
ENTRYPOINT ["java","-jar","App.jar"]

Im not shure with my ENTRYPOINT. I do the follwoing. #docker-compose.yml

...
  mysql-docker-container:
  ..
  .
  my-service:
    build:
      context: "."
      container_name: my_container
      command: ["./wait-for-mysql.sh", "mysql-docker-container:3306", "--", "java", "App.jar"]
....

Is the Entrypoint correct?

Tux1234 avatar Feb 12 '19 19:02 Tux1234

I think that your command should look like this: command: ["./wait-for-mysql.sh", "mysql-docker-container:3306", "--", "sh", "-c", "java", "App.jar"]

Calimerico avatar Apr 20 '19 17:04 Calimerico

to find out what is default entrypoint - do next steps:

  1. comment entrypoint config line in docker-compose.yml
  2. start service (docker-compose up -d)
  3. inspect service (docker inspect my_container) and find info about entrypoint. also it's possible to view entrypoint via docker ps, but string is truncated.
  4. modify your entrypoint: "wait-for-it mysql-docker-container:3306 -- default-entrypoint", replace "default-entrypoint" to your actual command

alexgivi avatar May 20 '19 10:05 alexgivi

In order to use it with Docker and docker-compose, place it alongside Dockerfile, build it into the image with exec permissions and reference it in docker-compose.yml.

- Dockerfile
- wait-for-it.sh
#Dockerfile
...
COPY wait-for-it.sh /wait-for-it.sh
RUN chmod +x /wait-for-it.sh
...
#docker-compose.yml
...
  my-service:
    build:
      context: "."
      container_name: my_container
      command: ["/wait-for-it.sh", "mysql:3306", "--", [entrypoint function]]
...

@agustisanchez what is the "entrypoint function" in docker-compose.yml

yaoyuanyy avatar May 22 '19 03:05 yaoyuanyy

@agustisanchez if i want to run a java project, what is the "entrypoint function"

yaoyuanyy avatar May 22 '19 03:05 yaoyuanyy

https://docs.docker.com/compose/compose-file/#command https://docs.docker.com/compose/compose-file/#entrypoint there is some difference between command and entrypoint. personally I prefer to use entrypoint config and don't use command.

alexgivi avatar May 26 '19 11:05 alexgivi

Multistage builds can be leveraged to install wait-for-it with apt-get:

FROM debian:buster-slim as wait-for-it
RUN apt-get update && apt-get install -y "wait-for-it"

FROM debian:buster-slim
COPY --from=wait-for-it /usr/bin/wait-for-it /usr/bin/wait-for-it

If there was an official docker image for wait-for-it (i.e. wait-for-it/wait-for-it) we could potentially do:

FROM debian:buster-slim
COPY --from=wait-for-it/wait-for-it /usr/bin/wait-for-it /usr/bin/wait-for-it

jakzal avatar May 31 '19 10:05 jakzal

@douglas-gibbons Is it possible to use it with google distroless java images?

kunal-bhatia avatar Jun 12 '19 18:06 kunal-bhatia

For a dependency that you don't need to build (i.e. also create Dockerfile and specify context), you can make it work with the volumes config only:

  1. chmod 755 wait-for-it.sh
# docker-compose.yml
…
volumes:
  - "./wait-for-it.sh:/wait-for-it.sh:ro"
…

Good to know:

  • Bind mounts keep the host's permissions[source], so step 1) is obligatory.
  • The read-only (ro) segment is optional.

mdkalish avatar Dec 30 '19 14:12 mdkalish

wait-for-it.sh is not trapping SIGTERM so, to be able to gracefully stop a service that is stuck waiting, the stop signal needs to be overridden in docker-compose.yml:

version: '3'

services:
  wait-for-app:
    image: ubuntu
    volumes:
      - ./wait-for-it.sh:/usr/local/bin/wait-for-it.sh
    command: wait-for-it.sh app:8080 -- echo ok
    stop_signal: SIGINT

ncjones avatar Feb 05 '20 03:02 ncjones

I want to share my case. I investigated.

I using openjdk:8-jdk-alpine image docker. My environment:

  • OS: window 10 Pro
  • Docker engine: 19.03.2

My Dockerfile

FROM openjdk:8-jdk-alpine

RUN apk add --no-cache bash

COPY ./wait-for-it.sh /wait-for-it.sh

RUN chmod +x wait-for-it.sh

RUN ls -la

and used it in docker-compose.yml file command: bash ./wait-for-it.sh my-service:8080 --strict -- java -jar app.jar But it was failed!!! @@

This issue is EOL(end of line). My wait_for_it.sh file has CRLF (windows). I changed it into LF (for Unix and MacOs). It worked!

97lynk avatar May 12 '20 15:05 97lynk

I want to share my case. I investigated.

I using openjdk:8-jdk-alpine image docker. My environment:

  • OS: window 10 Pro
  • Docker engine: 19.03.2

My Dockerfile

FROM openjdk:8-jdk-alpine

RUN apk add --no-cache bash

COPY ./wait-for-it.sh /wait-for-it.sh

RUN chmod +x wait-for-it.sh

RUN ls -la

and used it in docker-compose.yml file command: bash ./wait-for-it.sh my-service:8080 --strict -- java -jar app.jar But it was failed!!! @@

This issue is EOL(end of line). My wait_for_it.sh file has CRLF (windows). I changed it into LF (for Unix and MacOs). It worked!

Thanks, this really helped, I had spent hours figuring out why it's not working for me despite putting all the commands correctly. Changing from CRLF to LF worked like a charm.

SandeepYadav-Hashedin avatar Sep 14 '20 02:09 SandeepYadav-Hashedin

is there a way to retain the CMD in the Dockerfile so other users can easily opt-out of using docker-compose?

Choongkyu avatar Mar 06 '21 23:03 Choongkyu

I struggled with this problem for a long time and finally come up with a solution with reference from above. In case someone would come here for solutions, here is my working codes.

In your Dockerfile, you would add this for the wait-for-it.sh. The $APP_HOME is an ENV variable that you might define after FROM command for your specific project.

COPY wait-for-it.sh $APP_HOME/app

WORKDIR $APP_HOME/app

RUN chmod +x wait-for-it.sh

ENTRYPOINT ["/bin/bash", "-c"]

In your docker-compose.yml, you might add the following:

app:
  restart: on-failure
  command: ["./wait-for-it.sh db:3306 --strict --timeout=300 -- alembic upgrade head && python main.py"]

Note all the rest configurations were not mentioned here, but they could be found from other references as above.

johntheprime avatar Apr 09 '21 03:04 johntheprime