Nordico
Nordico

Reputation: 1307

How to deploy the same compose in different stacks and adapt container names automatically?

I am trying to design a docker-compose.yml file that will allow me to easily launch environments to develop inside of. Sometimes I would like to have 2 or more of these up at the same time but doing it naively I get ERROR: for pdb Cannot create container for service pdb: Conflict. The container name "/pdb" is already in use by container ... (even if they are on different stacks).

version: '3.4'

services:

  pdb:
    hostname: "pdb"
    container_name: "pdb"
    image: "postgres:latest"

(...other services...)

Is there a way to automatically name these in a distinguishable but systematic way? For example something like this:

version: '3.4'

services:

  pdb:
    hostname: "${stack_name}_pdb"
    container_name: "${stack_name}_pdb"
    image: "postgres:latest"

(...other services...)

EDIT: Apparently this is a somewhat service specific question so here is the complete compose file just in case...

version: '3.4'

services:

  rmq:
    hostname: "rmq"
    container_name: "rmq"
    image: "rabbitmq:latest"
    networks:
      - "fakenet"
    ports:
      - "5672:5672"
    healthcheck:
      test: "rabbitmq-diagnostics -q ping"
      interval: 30s
      timeout: 30s
      retries: 3

  pdb:
    hostname: "pdb"
    container_name: "pdb"
    image: "postgres:latest"
    networks:
      - "fakenet"
    ports:
      - 5432:5432
    environment:
      POSTGRES_PASSWORD: ******
      POSTGRES_USER: postgres
      POSTGRES_DB: test_db
    volumes:
      - "./deploy/pdb:/docker-entrypoint-initdb.d"
      - "./data/dbase:/var/lib/postgresql/data"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready"]
      interval: 10s
      timeout: 5s
      retries: 5

  workenv:
    hostname: "aiida"
    container_name: "aiida"
    image: "aiida_workenv:v0.1"
    expose:
      - "8888" # AiiDa Lab
      - "8890" # Jupyter Lab
      - "5000" # REST API
    ports: # local:container
      - 8888:8888
      - 8890:8890
      - 5000:5000
    volumes:
      - "./data/codes:/home/devuser/codes"
      - "./data/aiida:/home/devuser/.aiida"
    depends_on:
      pdb:
        condition: service_healthy
      rmq:
        condition: service_healthy
    networks:
      - "fakenet"
    environment:
      LC_ALL: "en_US.UTF-8"
      LANG: "en_US.UTF-8"
      PSQL_HOST: "pdb"
      PSQL_PORT: "5432"
    command: "tail -f /dev/null"

networks:
  fakenet:
    driver: bridge

Upvotes: 0

Views: 498

Answers (1)

David Maze
David Maze

Reputation: 159403

Just don't manually set container_name: at all. Compose will automatically assign a name based on the current project name. Similarly, you don't usually need to set hostname: (RabbitMQ is one extremely specific exception, if you're using that).

If you do need to publish ports out of your Compose setup to be able to access them from the host system, the other obvious pitfall is that the first ports: number must be unique across the entire host. You can specify a single number for ports: to let Docker pick the host port, though you'll need to look it up later with docker-compose port.

version: '3.8'
services:
  pdb:
    image: "postgres:latest"
    # no hostname: or ports:

  app:
    build: .
    environment:
      PGHOST: pdb
    ports:
      - 3000 # container-side port, Docker picks host port
docker-compose -p myname -d up
docker-compose -p myname port app 3000

Upvotes: 2

Related Questions