Automatically create databases with docker compose and postgres
Postgres docker image creates, by default, a user called postgres
with postgres
password (this changes in postgres 12: you need to explicitly specify a password) and a database called postgres
This means that in most of situations, what you need is:
DATABASE_URL: postgres://postgres:postgres@postgres:5432/postgres
# Or, if you change the password:
DATABASE_URL: postgres://postgres:secret@postgres:5432/postgres
Create databases using psql #
But in some scenarios you need at least a couple of databases for each project: one for development, other for testing.
One option is to run psql inside the docker container:
docker exec -it <project-name>_postgres_1 psql -U postgres
... and create them manually:
CREATE DATABASE <database>
GRANT ALL PRIVILEGES ON DATABASE <database> to postgres
Create databases automatically #
The postgres docker image will run any *.sh
file inside /docker-entrypoint-initdb.d
.
So the idea is to add an initialization file using a docker container volumes:
version: "3.4"
services:
postgres:
image: postgres
restart: unless-stopped
volumes:
- postgres:/var/lib/postgresql/data
- ./init-database.sh:/docker-entrypoint-initdb.d/init-database.sh
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
ports:
- 5432:5432
volumes:
postgres:
And the init file connects to posqgres via psql and run the initialization:
init-database.yml
:
#!/bin/bash
set -e
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
CREATE USER docker;
CREATE DATABASE my-project_development;
GRANT ALL PRIVILEGES ON DATABASE my-project_development TO docker;
CREATE DATABASE my-project_test;
GRANT ALL PRIVILEGES ON DATABASE my-project_test TO docker;
EOSQL