From a1d139ce6b623c88240ca0507fc11e324b693cd3 Mon Sep 17 00:00:00 2001 From: Scott Sharkey Date: Wed, 12 Jul 2023 19:55:41 -0400 Subject: [PATCH 1/5] update to postgis15-3.3 --- Dockerfile | 2 +- LICENSE | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index ee9c3d0..c8d27fe 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,2 +1,2 @@ -FROM postgres:9.6 +FROM postgres:15-3.3 COPY create-multiple-postgresql-databases.sh /docker-entrypoint-initdb.d/ diff --git a/LICENSE b/LICENSE index af2d520..0d001e6 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2017 Mart Sõmermaa +Copyright (c) 2017 Mart Sõmermaa and 2023 Scott Sharkey Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 60f1c3a0ea086f1097441790161af97d9a950fac Mon Sep 17 00:00:00 2001 From: Scott Sharkey Date: Wed, 12 Jul 2023 21:00:47 -0400 Subject: [PATCH 2/5] Add full example, convert to postgis --- Dockerfile | 2 +- README.md | 28 +++++++----- create-multiple-postgresql-databases.sh | 26 ++++++----- create-multiple-postgresql-full.sh | 58 +++++++++++++++++++++++++ docker-compose.yml | 15 +++++++ 5 files changed, 106 insertions(+), 23 deletions(-) create mode 100644 create-multiple-postgresql-full.sh create mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile index c8d27fe..13fd18f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,2 +1,2 @@ -FROM postgres:15-3.3 +FROM postgis:15-3.3 COPY create-multiple-postgresql-databases.sh /docker-entrypoint-initdb.d/ diff --git a/README.md b/README.md index d4b6a15..e678693 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,9 @@ mechanism. ### By mounting a volume Clone the repository, mount its directory as a volume into -`/docker-entrypoint-initdb.d` and declare database names separated by commas in -`POSTGRES_MULTIPLE_DATABASES` environment variable as follows +`/docker-entrypoint-initdb.d` and declare database names separated by commas and each +entry with database, user and password separated by double colons in the (???) +`POSTGRES_MULTIPLE_DATABASES` environment variable as follows: (`docker-compose` syntax): myapp-postgresql: @@ -27,9 +28,10 @@ Clone the repository, mount its directory as a volume into volumes: - ../docker-postgresql-multiple-databases:/docker-entrypoint-initdb.d environment: - - POSTGRES_MULTIPLE_DATABASES: db1,db2 - - POSTGRES_USER: myapp - - POSTGRES_PASSWORD: + - POSTGRES_MULTIPLE_DATABASES=db1:user1:pwd1,db2:user2:pwd2 + - POSTGRES_USER=myapp + - POSTGRES_PASSWORD= + - POSTGRES_DB=db ### By building a custom image @@ -45,13 +47,19 @@ to the container: myapp-postgresql: image: eu.gcr.io/your-project/postgres-multi-db environment: - - POSTGRES_MULTIPLE_DATABASES: db1,db2 - - POSTGRES_USER: myapp - - POSTGRES_PASSWORD: + - POSTGRES_MULTIPLE_DATABASES=db1:user1:pwd1,db2:user2:pwd2 + - POSTGRES_USER=myapp + - POSTGRES_PASSWORD= + - POSTGRES_DB=db ### Non-standard database names -If you need to use non-standard database names (hyphens, uppercase letters etc), quote them in `POSTGRES_MULTIPLE_DATABASES`: +If you need to use non-standard database names (hyphens, uppercase letters etc), quote +them in `POSTGRES_MULTIPLE_DATABASES`: environment: - - POSTGRES_MULTIPLE_DATABASES: "test-db-1","test-db-2" + - POSTGRES_MULTIPLE_DATABASES: "test-db-1:user:pwd","test-db-2:user:pwd" + +The `create-multiple-postgresql-full.sh` and `docker-compose.yml` files show an example +of how to create both databases and users exclusively to them and assign passwords to +them. `user1` will not have access to `db1`,`db2`. diff --git a/create-multiple-postgresql-databases.sh b/create-multiple-postgresql-databases.sh index aa665fa..513f605 100755 --- a/create-multiple-postgresql-databases.sh +++ b/create-multiple-postgresql-databases.sh @@ -4,19 +4,21 @@ set -e set -u 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 dbinfo=$1 + IFS=":" read -r database user password <<< "$dbinfo" + + echo "Creating database '$database' with user '$user' and password '$password'" + psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "postgres" <<-EOSQL + CREATE USER $user; + ALTER USER $user WITH ENCRYPTED PASSWORD '$password'; + CREATE DATABASE $database ENCODING "UTF8 LC_COLLATE = "en_US.UTF-8" LC_CTYPE = "en_US.UTF-8" TEMPLATE="template0"; + GRANT ALL PRIVILEGES ON DATABASE $database TO $user; } if [ -n "$POSTGRES_MULTIPLE_DATABASES" ]; then - echo "Multiple database creation requested: $POSTGRES_MULTIPLE_DATABASES" - for db in $(echo $POSTGRES_MULTIPLE_DATABASES | tr ',' ' '); do - create_user_and_database $db - done - echo "Multiple databases created" + echo "Multiple database creation requested: $POSTGRES_MULTIPLE_DATABASES" + for db in $(echo $POSTGRES_MULTIPLE_DATABASES | tr ',' ' '); do + create_user_and_database $db + done + echo "Multiple databases created" fi diff --git a/create-multiple-postgresql-full.sh b/create-multiple-postgresql-full.sh new file mode 100644 index 0000000..714b676 --- /dev/null +++ b/create-multiple-postgresql-full.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +set -e +set -u + +containsElement () { + IFS=$'\n' + local array=$1 val=$2 result=0 + for var in $array; do + if [[ "$var" == "$val" ]]; then + result=1 + break + fi + done + echo "$result" +} + +function create_user_and_database() { + local database=$1 user=$2 password=$3 + local query_users="select rolname from pg_roles;" + local query_databases="select datname from pg_database;" + local roles=$(echo "$query_users" | psql -tA) + local databases=$(echo "$query_databases" | psql -Aqt) + user_exist=$(containsElement "$roles" "$user") + database_exist=$(containsElement "$databases" "$database") + + if [[ "$user_exist" == 1 ]]; then + echo "User '$user' exist. Skipping" + else + echo "Create User '$user'."; + psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" \ + -c "CREATE USER $user WITH PASSWORD '$password'"; + fi + if [[ "$database_exist" == 1 ]]; then + echo "Database '$database' exists. Skipping." + else + echo "Create Database '$database'" + psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" \ + -c "CREATE DATABASE $database;" + fi + psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" \ + -c "GRANT ALL PRIVILEGES ON DATABASE $database TO $user;" +} + +if [ -n "$POSTGRES_MULTIPLE_DATABASES" ]; then + echo "Multiple database creation requested: $POSTGRES_MULTIPLE_DATABASES" + IFS=', ' read -r -a databases <<< "$POSTGRES_MULTIPLE_DATABASES" + IFS=', ' read -r -a users <<< "$POSTGRES_MULTIPLE_USERS" + IFS=', ' read -r -a passwords <<< "$POSTGRES_MULTIPLE_PASSWORDS" + for index in ${!databases[@]}; do + if [[ $index < ${#databases[*]} && $index < ${#users[*]} && $index < ${#passwords[*]} ]] ; then + create_user_and_database "${databases[index]//[\'\"\`]/}" "${users[index]//[\'\"\`]/}" "${passwords[index]//[\'\"\`]/}" + else + echo "DATABASE '${databases[index]}' OR USER '${users[index]}' EMPTY" + fi + done + echo "Multiple databases created" +fi diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..e47d2a8 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,15 @@ +services: + postgres: + image: postgis:15-3.3 + container_name: example-postgres + environment: + - POSTGRES_MULTIPLE_DATABASES="db1","db2","db3" + - POSTGRES_MULTIPLE_USERS="user1","user2","user3 + - POSTGRES_MULTIPLE_PASSWORDS="password1","password2","password3" + - POSTGRES_USER=superrole + - POSTGRES_PASSWORD=superpassword + ports: + - "5432:5432" + volumes: + - ./create-multiple-postgresql-full.sh:/docker-entrypoint-initdb.d/create-multiple-postgresql-full.sh + restart: always From ff39252539838e19126cc008d3eda68252f5384c Mon Sep 17 00:00:00 2001 From: Scott Sharkey Date: Wed, 12 Jul 2023 21:07:52 -0400 Subject: [PATCH 3/5] doc: Update README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e678693..05bf74d 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,8 @@ them in `POSTGRES_MULTIPLE_DATABASES`: environment: - POSTGRES_MULTIPLE_DATABASES: "test-db-1:user:pwd","test-db-2:user:pwd" +### Example + The `create-multiple-postgresql-full.sh` and `docker-compose.yml` files show an example of how to create both databases and users exclusively to them and assign passwords to them. `user1` will not have access to `db1`,`db2`. From 414cc1ea9a32c1d33c7ca43024ebfcfbcea596a7 Mon Sep 17 00:00:00 2001 From: Scott Sharkey Date: Wed, 12 Jul 2023 21:13:18 -0400 Subject: [PATCH 4/5] chore: chmod +x shell scripts --- create-multiple-postgresql-databases.sh | 2 +- create-multiple-postgresql-full.sh | 0 2 files changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 create-multiple-postgresql-full.sh diff --git a/create-multiple-postgresql-databases.sh b/create-multiple-postgresql-databases.sh index 513f605..d4b5e81 100755 --- a/create-multiple-postgresql-databases.sh +++ b/create-multiple-postgresql-databases.sh @@ -9,7 +9,7 @@ function create_user_and_database() { echo "Creating database '$database' with user '$user' and password '$password'" psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "postgres" <<-EOSQL - CREATE USER $user; + CREATE USER $user IF NOT EXISTS; ALTER USER $user WITH ENCRYPTED PASSWORD '$password'; CREATE DATABASE $database ENCODING "UTF8 LC_COLLATE = "en_US.UTF-8" LC_CTYPE = "en_US.UTF-8" TEMPLATE="template0"; GRANT ALL PRIVILEGES ON DATABASE $database TO $user; diff --git a/create-multiple-postgresql-full.sh b/create-multiple-postgresql-full.sh old mode 100644 new mode 100755 From 92699eb705a8b5a29619389e720b25cfc5e2dcf5 Mon Sep 17 00:00:00 2001 From: Scott Sharkey Date: Wed, 12 Jul 2023 21:38:17 -0400 Subject: [PATCH 5/5] updated postgis references --- Dockerfile | 2 +- docker-compose.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 13fd18f..5146836 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,2 +1,2 @@ -FROM postgis:15-3.3 +FROM postgis/postgis:15-3.3 COPY create-multiple-postgresql-databases.sh /docker-entrypoint-initdb.d/ diff --git a/docker-compose.yml b/docker-compose.yml index e47d2a8..d1b1788 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,13 +1,13 @@ services: postgres: - image: postgis:15-3.3 + image: postgis/postgis:15-3.3 container_name: example-postgres environment: - POSTGRES_MULTIPLE_DATABASES="db1","db2","db3" - POSTGRES_MULTIPLE_USERS="user1","user2","user3 - POSTGRES_MULTIPLE_PASSWORDS="password1","password2","password3" - - POSTGRES_USER=superrole - - POSTGRES_PASSWORD=superpassword + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=password ports: - "5432:5432" volumes: