30
votes

I have a project consisting of two main java apps that use eight postgres databases, so is there a way in docker-compose to build eight different databases so that each one has a different owner and password? Can I even do that in docker-compose?

example:

services:
    postgresql:
        build: db/.
        ports:
            - "5432:5432"
        environment:
          - POSTGRES_DB=database1
          - POSTGRES_USER=database1
          - POSTGRES_PASSWORD=database1

I know I can put all the .sql files in the docker-entrypoint-initdb.d and postgres will make them automatically, but how do I declare what .sql file goes in what database?

Tnx, Tom

3
Scale up or scale out. Another option is to have multiple postgres containers. Fits my one db per app architecture and perhaps less your 2 apps over 8 dbs. But for others, it is worth considering. Then you don't have to think about any janky workarounds, and have more independant dbs that you can bring up and down easier. Though it is much more resource demanding. - flurdy

3 Answers

23
votes

According to this Github issue might be possible to achieve multiple databases by using bash scripts which you will have to pass in your Dockerfile

EDIT:

To create multiple Databases you could use the following script:

https://github.com/mrts/docker-postgresql-multiple-databases

or

https://github.com/MartinKaburu/docker-postgresql-multiple-databases

Which suggest that you have to clone one of the above git repos and mount it as a volume to: /docker-entrypoint-initdb.d then you would be able to pass multiple database names by using: POSTGRES_MULTIPLE_DATABASES variable

16
votes

Usually when I need more than one database in a docker project it's a test database. I find it easier to simply spin up a second docker container, without worrying about scripts or volume separation. The main trick is to not conflict the default ports (e.g. 5432 for postgres) and you're good to go. Then docker-compose can be something as simple as this:

version: '3.0'

services: 

  db:
    image: postgres
    environment: 
      - POSTGRES_DB
      - POSTGRES_USER
      - POSTGRES_PASSWORD
    ports:
      - ${POSTGRES_DEV_PORT}:5432
    volumes:
      - app-volume:/var/lib/postgresql/data

  db-test:
    image: postgres
    environment: 
      - POSTGRES_DB
      - POSTGRES_USER
      - POSTGRES_PASSWORD
    ports:
      - ${POSTGRES_TEST_PORT}:5432
    # Notice I don't even use a volume here since I don't care to persist test data between runs

volumes:
  app-volume: #
10
votes

Well - take a look at this Github project: https://github.com/mrts/docker-postgresql-multiple-databases

According to official postgres docker image documentation:

If you would like to do additional initialization in an image derived from this one, add one or more *.sql, *.sql.gz, or *.sh scripts under /docker-entrypoint-initdb.d (creating the directory if necessary). After the entrypoint calls initdb to create the default postgres user and database, it will run any *.sql files and source any *.sh scripts found in that directory to do further initialization before starting the service.

You will find the prepared script on that repo which you could use.