Mehdi
Mehdi

Reputation: 308

docker compose config for multiple instances of one image with different arguments

I have a cli application that can run two services based on the input argument.

1- app serve // to run a web server
2- app work  // to run a long-running background worker

they share the same code. what do I need when for deployment?

 A: two separate containers or
 B: two processes in the same container 

And what would be the docker-compose config ?

Upvotes: 3

Views: 4597

Answers (2)

sauerburger
sauerburger

Reputation: 5138

If you want to have one process per container, I would suggest to have a generic image (and Dockerfile) which can run as worker or as server.

The Dockerfile file should set the entrypoint to the app, e.g. ENTRYPOINT ["/path_to_my_app/myapp"] but not the CMD. When the user invokes the command from the command line, he can start the worker with docker run IMAGENAME work or the server with docker run IMAGENAME serve.

To define both services in a compose file, you need to override the command field for each service.

version: '3'
services:
  web:
      build: ./docker    # common Dockerfile
      image: IMAGENAME
      ports:
          - "8090:8090"
      command: ["serve"]

  worker:
      build: ./docker    # common Dockerfile
      image: IMAGENAME   # reuse image
      ports:
          - "8091:8091"
      command: ["work"]

The benefit of this solution over a solution with two separate images, is a gain in maintainability. Since there is only one Dockerfile and one image, both services should be always compatible.

Upvotes: 5

Mehdi
Mehdi

Reputation: 308

after some googling, I found that as @sauerburger said in comments, better to have one process per container.

But to have multiple containers each for running my main app with a specific argument (ie. one for main app and one for worker) I need to have multiple Dockerfiles. the in my docker-compose i can referenc them separately.

but how to have different dockerfiles for a project?

the prefered solution is to have a docker directory in which each part has its own folder. for my application it will be like this:

- docker
    - web
        -Dockerfile
    - worker
        -Dockerfile

then in each Dockerfile I have a common entrypoint and a distinct cmd:

-in web Dockerfile :
    - ENTRYPOINT ["/path_to_my_app/myapp"]
    - CMD ["web"]

-in worker Dockerfile :
    - ENTRYPOINT ["/path_to_my_app/myapp"]
    - CMD ["worker"]

after doing this my docker-compose file will reference them like this:

version: '3'
services:
      web:
          # will build ./docker/web/Dockerfile
          build: ./docker/web
          ports:
              - "8090:8090"

      worker:
          # will build ./docker/worker/Dockerfile
          build: ./docker/worker
          ports:
              - "8091:8091"

Upvotes: 1

Related Questions