Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make docker-compose build image once and repeatedly use it to run containers?

I am trying to run multiple containers built from the same image. My problem is when I define my docker-compose.yml this way

version: '3'
services:
    crossbar-target:
        container_name: "app-crossbar-target"
        build:
            context: ../../crossbar

    crossbar-source-domain1:
        container_name: "app-crossbar-source-domain1"
        build:
            context: ../../crossbar

    crossbar-source-domain2:
        container_name: "app-crossbar-source-domain2"
        build:
            context: ../../crossbar

I will get three containers as I want them, but I get three images as well.

In case I have hundreds of containers, I don't like the idea having hundreds of images as well. That makes my local image repository completely unusable and unreadable.

Thinking and searching for solution I tried define crossbar image by itself and then reuse it:

version: '3'
services:
    app-crossbar:
        build:
        context: ../../crossbar

    crossbar-target:
        container_name: "app-crossbar-target"
        image: project_name/app-crossbar

    crossbar-source-domain1:
        container_name: "app-crossbar-source-domain1"
        image: project_name/app-crossbar

    crossbar-source-domain2:
        container_name: "app-crossbar-source-domain2"
        image: project_name/app-crossbar

Now, I have only one image for all containers, but get an app-crossbar container as well. That doesn't suit my needs as well.

Is there any way to make docker-compose manage my images efficiently and make only those images I need and then use them to run containers in any amount needed? Or do I have to manage my images separately in some other routines? I like calling:

docker-compose build

to rebuild all needed images and I like the idea that all my docker logic is held in one place.

like image 460
Wax Cage Avatar asked Jul 26 '17 12:07

Wax Cage


People also ask

Does docker compose run build images?

From your project directory, start up your application by running docker compose up . Compose pulls a Redis image, builds an image for your code, and starts the services you defined.

Does docker compose run multiple containers?

With Docker compose, you can configure and start multiple containers with a single yaml file.

How do I force recreate docker compose?

If you want to force Compose to stop and recreate all containers, use the --force-recreate flag. If the process encounters an error, the exit code for this command is 1 . If the process is interrupted using SIGINT (ctrl + C) or SIGTERM , the containers are stopped, and the exit code is 0 .

Do I have to build docker every time?

In ConclusionYou don't need to rebuild your Docker image in development for each tiny code change. If you mount your code into your dev container, you don't have to build a new image on every code change and iterate faster. It's a great feeling when you make changes and see the results right away!


1 Answers

Build the crossbar image first and properly tag it. Then you can spawn multiple services using that image. The latest tag here is only an example. I would use a unique version number.

version: '3'
services:
    app-crossbar:
        image: crossbar:latest

    crossbar-target:
        image: crossbar:latest

    crossbar-source-domain1:
        image: crossbar:latest

    crossbar-source-domain2:
        image: crossbar:latest

A huge advantage of pre-building images (and possibly storing them in an docker image repo) is that you can revert to older versions when needed. In addition you can run tests with the pre-build images if needed.

It's pretty standard to have a CI setup where for example Jenkins builds a new image of your crossbar project (when you push a branch), properly tags it an pushes the image to your private (or public) image repo.

I'd say even if you could build the image with compose, that is still not the right way to do it for prod. It might be acceptable if you extend your image to add a layer with config files. By pre-building images your pipeline is also compatible with swarm and other clustered environments.

If this is overkill for your needs you just build locally (and TAG the images properly). The tagging part is important so you don't have to battle with docker cache and you can still find older versions if a revert is needed.

(In a dev environment you can be a more careless and just map in directories and file from the host to the containers. No one wants to re-build for every single change)

like image 120
Grimmy Avatar answered Nov 14 '22 23:11

Grimmy