Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allowing custom user and password for each database. #30

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,24 @@ to the container:
- POSTGRES_USER: myapp
- POSTGRES_PASSWORD:

### Custom user and password for each database

If you need to use a custom user and password for each database, you can do it by adding the `POSTGRES_USER_<uppercase database name>`
and `POSTGRES_PASSWORD_<uppercase database name>` environment variables:

myapp-postgresql:
image: postgres:9.6.2
volumes:
- ../docker-postgresql-multiple-databases:/docker-entrypoint-initdb.d
environment:
- POSTGRES_MULTIPLE_DATABASES: db1,db2
- POSTGRES_USER: myapp
- POSTGRES_PASSWORD:
- POSTGRES_USER_DB1: myapp_db1
- POSTGRES_PASSWORD_DB1:
- POSTGRES_USER_DB2: myapp_db2
- POSTGRES_PASSWORD_DB2:

### Non-standard database names

If you need to use non-standard database names (hyphens, uppercase letters etc), quote them in `POSTGRES_MULTIPLE_DATABASES`:
Expand Down
110 changes: 104 additions & 6 deletions create-multiple-postgresql-databases.sh
Original file line number Diff line number Diff line change
@@ -1,18 +1,116 @@
#!/bin/bash
#
# Source: https://github.com/mrts/docker-postgresql-multiple-databases
# Author: Mart Sõmermaa (https://github.com/mrts)
# contributor: Jens Peter Secher (https://github.com/jpsecher)
# contributor: Emanuele Scarsella (https://github.com/emanuele-scarsella)
# License: MIT
#

set -e
set -u

# Create a user and a database, if they don't already exist
# Arguments:
# $1 - Database name
function create_user_and_database() {
local database=$1
echo " Creating user and database '$database'"
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
CREATE USER $database;
CREATE DATABASE $database;
GRANT ALL PRIVILEGES ON DATABASE $database TO $database;
EOSQL
local user=$(get_user_for_database $database)
local password=$(get_password_for_database $database)
if user_exists $user; then
echo "User '$user' already exists, skipping"
else
echo "Creating user '$user' ${password:+(with password)}"
create_user $user $password
fi
if database_exists $database; then
echo "Database '$database' already exists, skipping"
else
echo "Creating database '$database' and granting all privileges to user '$user'"
create_database $database $user
fi
}

# Create a PostgreSQL user
# Arguments:
# $1 - User name
# $2 - User password (optional)
function create_user() {
local user=$1
local password=$2
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
CREATE USER "$user" ${password:+WITH PASSWORD '$password'};
EOSQL
}

# Create a PostgreSQL database and assign ownership
# Arguments:
# $1 - Database name
# $2 - User name
function create_database() {
local database=$1
local user=$2
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
CREATE DATABASE "$database" WITH OWNER "$user";
GRANT ALL PRIVILEGES ON DATABASE "$database" TO "$user";
EOSQL
}

# Check if a PostgreSQL user exists
# Arguments:
# $1 - User name
# Returns:
# 0 if user exists, 1 otherwise
function user_exists() {
local user=$1
local result
result=$(psql -t -v ON_ERROR_STOP=1 \
--username "$POSTGRES_USER" \
--dbname "$POSTGRES_DB" \
-c "SELECT 1 FROM pg_roles WHERE rolname = '$user';")
if [[ "$result" =~ 1 ]]; then
return 0
fi
return 1
}

# Check if a PostgreSQL database exists
# Arguments:
# $1 - Database name
# Returns:
# 0 if database exists, 1 otherwise
function database_exists() {
local database="$1"
if psql -lqt --username "$POSTGRES_USER" | cut -d \| -f 1 | grep -qw "$database"; then
return 0
else
return 1
fi
}

# Retrieve the user for a given database
# Arguments:
# $1 - Database name
# Returns:
# User name derived from environment variables or defaults to database name
function get_user_for_database() {
local database=$1
local user_var="POSTGRES_USER_${database^^}"
echo "${!user_var:-$database}"
}

# Retrieve the password for a given database
# Arguments:
# $1 - Database name
# Returns:
# Password derived from environment variables or empty if not set
function get_password_for_database() {
local database=$1
local password_var="POSTGRES_PASSWORD_${database^^}"
echo "${!password_var:-}"
}

# Main script logic: Create multiple databases if specified in the environment variable
if [ -n "$POSTGRES_MULTIPLE_DATABASES" ]; then
echo "Multiple database creation requested: $POSTGRES_MULTIPLE_DATABASES"
for db in $(echo $POSTGRES_MULTIPLE_DATABASES | tr ',' ' '); do
Expand Down