-1

Need to understand how to use multiple images in a single service in docker-compose file.

Consider the following docker-compose file,

version: '3.4'

services:
  postgres:
        image: timescale/timescaledb:latest-pg14
        restart: always
        environment: 
          - POSTGRES_USER=xxxx
          - POSTGRES_PASSWORD=xxxx
        logging:
          options:
            max-size: 10m
            max-file: "3"
        ports:
          - '5432:5432'
        volumes:
          - ./postgres-data:/var/lib/postgresql/data
          - ./sql/historydb.sql:/docker-entrypoint-initdb.d/historydb.sql    

  app:
        image: xxxxxxxxxxxxxx:xx.xx.xx.xx
        network_mode: host 
        volumes:
          - ./sample:/var/sample

As you can see from the above example, we have two services (postgres and app).

Now we want to merge these two services into one (say, mergedapp). So that we have a service like following,

version: '3.4'

services:
  mergedapp:
        image: timescale/timescaledb:latest-pg14
        image: xxxxxxxxxxxxxx:xx.xx.xx.xx
        restart: always
        network_mode: host 
        environment: 
          - POSTGRES_USER=xxxx
          - POSTGRES_PASSWORD=xxxx
        logging:
          options:
            max-size: 10m
            max-file: "3"
        ports:
          - '5432:5432'
        volumes:
          - ./postgres-data:/var/lib/postgresql/data
          - ./sql/historydb.sql:/docker-entrypoint-initdb.d/historydb.sql  
          - ./sample:/var/sample

I know the above docker-compose content is not valid. Hence, I need some docker-compose file content that will satisfy my requirement.

Please help.

Tried the following but it does not work,

version: '3.4'

services:
  mergedapp:
        image: timescale/timescaledb:latest-pg14
        image: xxxxxxxxxxxxxx:xx.xx.xx.xx
        restart: always
        network_mode: host 
        environment: 
          - POSTGRES_USER=xxxx
          - POSTGRES_PASSWORD=xxxx
        logging:
          options:
            max-size: 10m
            max-file: "3"
        ports:
          - '5432:5432'
        volumes:
          - ./postgres-data:/var/lib/postgresql/data
          - ./sql/historydb.sql:/docker-entrypoint-initdb.d/historydb.sql  
          - ./sample:/var/sample
Chris Doyle
  • 10,703
  • 2
  • 23
  • 42
  • You don't; the first Compose file you show is a best practice. Consider that a Docker container only runs a single process, so what single process would you run that's both your application and the external databases combined together? Mechanically, with different Linux distributions (or none) and different versions potentially in images, it's difficult to safely take the files from one image and put them into another. – David Maze Apr 03 '23 at 09:55

1 Answers1

0

Dangerous, but exactly answering your question:

Create a new Dockerfile, name it as my-merged-app-dockerfile.yml, and in that dockerfile use multi layering.


FROM timescale/timescaledb:latest-pg14

FROM xxxxxxxxxxxxxx:xx.xx.xx.xx

#Copy everything from the first layer (red alert!)
COPY --from=0 / /

And then use that dockerfile for your compose:


services:
  mergedapp:
        build:
          context: THE_DIRECTORY_OF_THE_DOCKERFILE
          dockerfile: my-merged-app-dockerfile.yml
        restart: always
        network_mode: host 

But you need to know exactly what you are doing because we are copying everything from the first layer to second layer. If that is what you mean by "merge".

If the bases of your two base images are of the same kind (For example ubuntu:22.04) and your two images don't have overlapping libraries that will terminate each other due to different versions, then your new image might survive after merging. But otherwise, undefined behavior might occur.

Therefore, I would rather change my design instead of merging (especially if one image is postgresql)

yerlilbilgin
  • 3,041
  • 2
  • 26
  • 21