Initial commit

This commit is contained in:
2026-02-11 20:18:19 +01:00
parent f08debb99d
commit 68244adf8e
5 changed files with 249 additions and 0 deletions

76
scripts/create-db-user.sh Executable file
View File

@@ -0,0 +1,76 @@
#!/usr/bin/env bash
set -euo pipefail
if [[ $# -lt 2 || $# -gt 3 ]]; then
echo "Usage: $0 <db_name> <db_user> [db_password]"
echo "Example: $0 project1_db project1_user"
echo "Example: $0 project1_db project1_user 'very-strong-password'"
exit 1
fi
DB_NAME="$1"
DB_USER="$2"
DB_PASSWORD="${3:-}"
if [[ ! "${DB_NAME}" =~ ^[a-zA-Z0-9_]+$ ]]; then
echo "Error: db_name must match [a-zA-Z0-9_]+"
exit 1
fi
if [[ ! "${DB_USER}" =~ ^[a-zA-Z0-9_]+$ ]]; then
echo "Error: db_user must match [a-zA-Z0-9_]+"
exit 1
fi
if [[ -z "${DB_PASSWORD}" ]]; then
# Generate a random URL-safe password if none was provided.
DB_PASSWORD="$(openssl rand -base64 24 | tr -d '\n' | tr '/+' '_-')"
fi
POSTGRES_ADMIN_USER="${POSTGRES_USER:-admin}"
POSTGRES_ADMIN_DB="${POSTGRES_DB:-app}"
POSTGRES_CONTAINER="${POSTGRES_CONTAINER_NAME:-postgres}"
sql_escape() {
printf "%s" "$1" | sed "s/'/''/g"
}
DB_NAME_ESCAPED="$(sql_escape "${DB_NAME}")"
DB_USER_ESCAPED="$(sql_escape "${DB_USER}")"
DB_PASSWORD_ESCAPED="$(sql_escape "${DB_PASSWORD}")"
echo "Creating database user and database in container '${POSTGRES_CONTAINER}'..."
ROLE_EXISTS="$(docker exec "${POSTGRES_CONTAINER}" psql -U "${POSTGRES_ADMIN_USER}" -d "${POSTGRES_ADMIN_DB}" -tAc "SELECT 1 FROM pg_roles WHERE rolname='${DB_USER_ESCAPED}'" || true)"
if [[ "${ROLE_EXISTS}" == "1" ]]; then
docker exec "${POSTGRES_CONTAINER}" psql -v ON_ERROR_STOP=1 -U "${POSTGRES_ADMIN_USER}" -d "${POSTGRES_ADMIN_DB}" \
-c "ALTER ROLE \"${DB_USER}\" WITH LOGIN PASSWORD '${DB_PASSWORD_ESCAPED}' NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;"
else
docker exec "${POSTGRES_CONTAINER}" psql -v ON_ERROR_STOP=1 -U "${POSTGRES_ADMIN_USER}" -d "${POSTGRES_ADMIN_DB}" \
-c "CREATE ROLE \"${DB_USER}\" LOGIN PASSWORD '${DB_PASSWORD_ESCAPED}' NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;"
fi
DB_EXISTS="$(docker exec "${POSTGRES_CONTAINER}" psql -U "${POSTGRES_ADMIN_USER}" -d "${POSTGRES_ADMIN_DB}" -tAc "SELECT 1 FROM pg_database WHERE datname='${DB_NAME_ESCAPED}'" || true)"
if [[ "${DB_EXISTS}" == "1" ]]; then
echo "Database '${DB_NAME}' already exists."
else
docker exec "${POSTGRES_CONTAINER}" psql -v ON_ERROR_STOP=1 -U "${POSTGRES_ADMIN_USER}" -d "${POSTGRES_ADMIN_DB}" \
-c "CREATE DATABASE \"${DB_NAME}\" OWNER \"${DB_USER}\";"
fi
docker exec "${POSTGRES_CONTAINER}" psql -v ON_ERROR_STOP=1 -U "${POSTGRES_ADMIN_USER}" -d "${POSTGRES_ADMIN_DB}" \
-c "REVOKE CONNECT, TEMP ON DATABASE \"${DB_NAME}\" FROM PUBLIC;"
docker exec "${POSTGRES_CONTAINER}" psql -v ON_ERROR_STOP=1 -U "${POSTGRES_ADMIN_USER}" -d "${POSTGRES_ADMIN_DB}" \
-c "GRANT CONNECT, TEMP ON DATABASE \"${DB_NAME}\" TO \"${DB_USER}\";"
cat <<EOF
Done.
Use these values in your app .env:
DB_HOST=postgres
DB_PORT=5432
DB_NAME=${DB_NAME}
DB_USER=${DB_USER}
DB_PASSWORD=${DB_PASSWORD}
EOF