Here's what I mean. How can I write a docker-compose.yaml file so that when one of the services is "built", it first runs another service?
I'll try to be even more specific. I'm trying to build a Java application using the database library JOOQ, which wants to connect to a database at build time in order to generate Java classes that correspond to database tables. I would like some combination of Dockerfile(s) and docker-compose.yaml file, such that the following happens in roughly the following order.
Here's the docker-compose.yaml file I'm working with
version: '3.7'
services:
postgres:
image: postgres:10.5-alpine
restart: always
ports:
- "6432:5432"
environment:
POSTGRES_DB: flashtools
POSTGRES_USER: flashtools
POSTGRES_PASSWORD: flashtools
volumes:
- ./src/main/scripts/01_init.sql:/docker-entrypoint-
initdb.d/01_init.sql
web:
build: .
network_mode: host
depends_on:
- postgres
ports:
- "8080:8080"
I'll flesh this out with more details, but hopefully what I'm asking is pretty straightforward.
I had the same issue and solved it in a hacky way...
In my case the web service is Haskell, which builds with the stack build
command, then executes with the stack exec APP_NAME
. There's also a shorthand like stack build --exec APP_NAME
.
Also there is an option to build only the dependencies with stack build --only-dependencies
, so the Docker build cache them.
So I changed my Dockerfile like this:
COPY ./package.yaml /app/package.yaml # Copying the package file
RUN stack build --only-dependencies # Build dependencies only
COPY . /app # Copying the rest of the files
EXPOSE 3000
CMD ["stack", "build", "--exec", "APP_NAME"] # Build the application itself
so the final build runs only when the service is started.
I don't know Java enough, but I guess there must be a similar option there too.
Also some hacking on the depends_on part is also needed: https://docs.docker.com/compose/startup-order/
since 2021-04-06 in version 1.29.0
(release note link)
Using the service_completed_successfully
condition (which is a "Long Form" depends_on
option):
Long syntax:
The long form syntax enables the configuration of additional fields that can't be expressed in the short form.
- condition: condition under which dependency is considered satisfied
service_completed_successfully
: specifies that a dependency is expected to run to successful completion before starting a dependent service.(source - emphasis added)
Long Syntax Example:
depends_on:
service_name:
condition: service_completed_successfully
docker-compose.yml
file:You'll need to make the following changes:
3.8
service_completed_successfully
condition to your depends_on
version: "3.8"
services:
postgres:
image: postgres:10.5-alpine
restart: always
ports:
- "6432:5432"
environment:
POSTGRES_DB: flashtools
POSTGRES_USER: flashtools
POSTGRES_PASSWORD: flashtools
volumes:
- ./src/main/scripts/01_init.sql:/docker-entrypoint-initdb.d/01_init.sql
web:
build: .
network_mode: host
depends_on:
postgres:
condition: service_completed_successfully
ports:
- "8080:8080"
Dockerfile
:(multi-stage build info)
Multi-stage builds are typically used to slim down your final Docker image, but it can also be used to run scripts and create "artifacts" needed before finishing your build.
It's hard to suggest this without seeing your exact Dockerfile
, but I thought it was worth mentioning that you may need to also use this.
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