Как запустить несколько postgresql CУБД, на разных контейнерах в одном хосте, через docker-compose

Я хочу запускать несколько баз postgresql на разных контейнерах одновременно.

У меня есть вот такой файл для docker-compose.

- 1-й контейнер


version: '3.5'
services:
  postgres:
    container_name: booking_air_example
    image: postgres:11.7
    environment:
      POSTGRES_USER: ${POSTGRES_USER:-postgres}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-root}
      PGDATA: /data/postgres
    volumes:
      - postgres:/data/postgres
      - //docker/init.sql:/docker-entrypoint-initdb.d/init.sql
    ports:
      - "5433:5432"
    networks:
      - postgres
    restart: unless-stopped

  pgadmin:
    container_name: pgadmin_container
    image: dpage/pgadmin4
    environment:
      PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL:[email protected]}
      PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD:-admin}
    volumes:
      - pgadmin:/root/.pgadmin
    ports:
      - "${PGADMIN_PORT:-5050}:80"
    networks:
      - postgres
    depends_on:
      - postgres
    restart: unless-stopped

networks:
  postgres:
    driver: bridge

volumes:
  postgres:
  pgadmin:

- 2-й контейнер

version: '3.5'
services:
  postgres:
    container_name: booking_air_2
    image: postgres:11.7
    environment:
      POSTGRES_USER: ${POSTGRES_USER:-postgres}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-root}
      PGDATA: /data/postgres
    volumes:
      - postgres:/data/postgres
      - //docker/init.sql:/docker-entrypoint-initdb.d/init.sql
    ports:
      - "5432:5432"
    networks:
      - postgres
    restart: unless-stopped

  pgadmin:
    container_name: pgadmin_container
    image: dpage/pgadmin4
    environment:
      PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL:[email protected]}
      PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD:-admin}
    volumes:
      - pgadmin:/root/.pgadmin
    ports:
      - "${PGADMIN_PORT:-5050}:80"
    networks:
      - postgres
    depends_on:
      - postgres
    restart: unless-stopped

networks:
  postgres:
    driver: bridge

volumes:
  postgres:
  pgadmin:

Я указал 2 разных имени контейнера, также у них входной порт со стороны хостовой системы - разный.

pgadmin - хотел бы, чтобы он работал с несколькими контейнерами.

Хотелось бы. чтобы контейнеры использовали одну заданную сеть (postgres).

Но когда я запуская 1-файл создается контейнер.

Когда запускаю 2 раз, он перезаписывает первый контейнер.

Как я понимаю, должны различаться имена объявляемых сервисов, но почему, разве недостаточно объявить другое имя контейнера ? Также нужно другой volume ?

Прошу укажите на ошибку и просьба пояснить что я делаю не так.


Ответы (4 шт):

Автор решения: zalex

С точки зрения docker-compose вы, меняя название контейнера, говорите ему - поменяй в сервисе с именем postgres имя контейнера, но вы не говорите сделай новый сервис с новыми параметрами.

Теперь к проблеме, как бы на вашем месте поступил бы я. Я бы очевидно описал бы все в одном файле.

Как именно - я бы вынес ваши разнящиеся данные в переменные окружения, сделал бы .env-1 .env-2 файлы и подключал бы их через ключ (естественно в docker-compose файле не забыть сделать соответствующие изменения)

--env-file PATH             Specify an alternate environment file

И теперь самое важно и самое простое - как запустить один и тот же описанный сервис с разные данными ?

  -p, --project-name NAME     Specify an alternate project name

т.е. при запуске вы указываете разные имена через данный ключ и по сути таким образом получаете столько нужных сервисов с нужными параметрами сколько вам нужно, не плодя бесконечное количество файлов описания сервисов.

→ Ссылка
Автор решения: Sergey Petrsov

А что вам мешает в одном docker-compose поднять два контейнера Postgresql? Примерно так:

version: '3.5'
services:
  postgres:
    container_name: booking_air_example
    image: postgres:11.7
    environment:
      POSTGRES_USER: ${POSTGRES_USER:-postgres}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-root}
      PGDATA: /data/postgres
    volumes:
      - postgres:/data/postgres
      - //docker/init.sql:/docker-entrypoint-initdb.d/init.sql
    ports:
      - "5433:5432"
    networks:
      - postgres
    restart: unless-stopped
  
  postgres1:
    container_name: booking_air_2
    image: postgres:11.7
    environment:
      POSTGRES_USER: ${POSTGRES_USER:-postgres}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-root}
      PGDATA: /data/postgres
    volumes:
      - postgres:/data/postgres
      - //docker/init.sql:/docker-entrypoint-initdb.d/init.sql
    ports:
      - "5432:5432"
    networks:
      - postgres
    restart: unless-stopped

  pgadmin:
    container_name: pgadmin_container
    image: dpage/pgadmin4
    environment:
      PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL:[email protected]}
      PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD:-admin}
    volumes:
      - pgadmin:/root/.pgadmin
    ports:
      - "${PGADMIN_PORT:-5050}:80"
    networks:
      - postgres
    depends_on:
      - postgres
      - postgres1
    restart: unless-stopped

networks:
  postgres:
    driver: bridge

volumes:
  postgres:
  postgres1:
  pgadmin:
→ Ссылка
Автор решения: Илья

Чтобы так связать в общую сеть два контейнера (когда последовательно разные compose-файлы запускаешь), нужно внизу второго контейнера указать:

networks:
    network_name: имя_сети
        external: true
        driver: bridge

только здесь имя сети будет не таким, как в первом сервисе, а какой-нибудь postgres_postgres (в вашем случае) - это зависит от имени сети и имени сервиса, посмотреть названия существующих сетей можно командой docker network ls.

→ Ссылка
Автор решения: eri

Перетирают друг друга из-за того что пишут данные в один том.

   volumes:
      - postgres:/data/postgres

Чтоб они были одной сети - непонятно зачем... ведь порт проброшен на хоста! Но можно. Создайте новую глобальную подсеть докера

docker network create -d bridge my-pgs

И в композе как

networks:
    my-pgs:
        name: my-pgs
        external: true
        driver: bridge
→ Ссылка