Skip to content

Support for multiple users and multiple databases #256

@wilmardo

Description

@wilmardo

Currently I am using the upstream image and a replica with hot_standby=on.
I mount a shell script to /docker-entrypoint-initdb.d/ to create multiple users and multiple databases. These script read from an environment variable in the format <user>:<password>:<db1>,<db2>|<second_user>:<password>:<db2>

# Create user harbor with password pass when non existing then create databases registry and clair and grant access to harbor when databases are non existing.
# Then create user test with password pass when non existing and create test_db and grant access to test.
POSTGRES_MULTIPLE_DATABASES="harbor:pass:registry,clair,notary_server,notary_signer|test:pass:test_db"
#!/bin/bash

set -e
set -u

# Source for the create user logic:
# https://stackoverflow.com/a/49858797
function create_user() {
	local user=$1
	local password=$2
	echo "  Creating user '$user'"
	psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
    DO \$\$
    BEGIN
      CREATE USER $user WITH ENCRYPTED PASSWORD '$password';
      EXCEPTION WHEN OTHERS THEN
      RAISE NOTICE 'not creating role $user -- it already exists';
    END
    \$\$;
EOSQL
}

function create_database() {
	local database=$1
	local owner=$2
	echo "  Creating database '$database' and granting to '$owner'"
	psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
    DO \$\$
    BEGIN
      CREATE DATABASE $database;
      GRANT ALL PRIVILEGES ON DATABASE $database TO $owner;
      EXCEPTION WHEN OTHERS THEN
      RAISE NOTICE 'not creating and granting database $database -- it already exists';
    END
    \$\$;
EOSQL
}

function main() {
  if [ -n "$POSTGRES_MULTIPLE_DATABASES" ]; then
    echo "Multiple database creation requested: $POSTGRES_MULTIPLE_DATABASES"
    # Declare variables
    local user
    local password
    local db_list

    for entry in $(echo "$POSTGRES_MULTIPLE_DATABASES" | tr '|' ' '); do
      # Split user
      user=$(echo "$entry" | tr ':' ' ' | awk  '{print $1}')
      # Split password
      password=$(echo "$entry" | tr ':' ' ' | awk  '{print $2}')
      # Split access list
      db_list=$(echo "$entry" | tr ':' ' ' | awk  '{print $3}')

      create_user "$user" "$password"
      for db in $(echo "$db_list" | tr ',' ' '); do
        create_database "$db" "$user"
      done
    done
    echo "Multiple databases created"
  fi
}

main

Is this something you would like to be built in the Docker containers and made available within the Helm chart?

Suggestions for improvements are welcome to!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions