Ritwik
Ritwik

Reputation: 1725

Docker Compose: How to configure a Multi-Stage Docker image split into multiple Dockerfiles?

I have 3 Dockerfiles

./Dockerfile

FROM rust:1.43.1
WORKDIR /usr/src/hiro
COPY . .
RUN cargo build

./Dockerfile.master

FROM me/base
RUN chmod +x ./target/debug/hiro
CMD [ "./target/debug/hiro", "--master", "-p", "${PORT}" ]

./Dockerfile.worker

FROM me/base
RUN chmod +x ./target/debug/hiro
CMD [ "./target/debug/hiro", "--worker", "-p", "${PORT}" ]

Build (without Docker Compose)

docker build -t me/base -f Dockerfile .

and then,

docker build -t me/master -f Dockerfile.master .
docker build -t me/worker -f Dockerfile.worker .

I'm creating both master and worker, from the same base image that does the hard work of compiling source code. Somewhat like what explained in this Stackoverflow question: Docker Multi-Stage: How to split up into multiple Dockerfiles

Question

How can I configure my docker-compose.yml to build both images from the same base image?

Upvotes: 0

Views: 1943

Answers (1)

David Maze
David Maze

Reputation: 159732

If the only thing that's different between the two images is the CMD, that's easy to override in the docker-compose.yml.

version: '3.8'
services:
  master:
    build: . # uses the base Dockerfile
    command: ./target/debug/hiro --master --port 12345
  worker:
    build: .
    command: ./target/debug/hiro --worker --port 12345

The other thing that's easy to customize this way is per-invocation environment variables. Note, though, that this won't go through and rebuild the image with different variables; it will only launch the final CMD with a different environment.

Your question shows plain docker build commands; with plain docker run anything after the image name is similarly interpreted as the command to run.

docker run ... me/base \
  ./target/debug/hiro --worker --port 12345

(If you're looking for other examples of this, this is especially common in Python Django/Celery applications. The "main" application is a Django-based Web server, but it shares most of its source tree with a Celery task runner, and you launch the Celery worker with the same image but a different command.)

Upvotes: 1

Related Questions