add files for building containter artifacts

Lifted in large parts from version 9.5 of the SCL postgresql container.

https://github.com/sclorg/postgresql-container
This commit is contained in:
Nils Philippsen 2017-05-11 11:56:47 +02:00
commit fa7e7e5dec
15 changed files with 830 additions and 0 deletions

View file

@ -0,0 +1,98 @@
PostgreSQL Docker image
=======================
This repository contains Dockerfiles for PostgreSQL images for general usage and OpenShift.
Users can choose between RHEL and CentOS based images.
Environment variables and volumes
----------------------------------
The image recognizes the following environment variables that you can set during
initialization by passing `-e VAR=VALUE` to the Docker run command.
| Variable name | Description |
| :--------------------------- | ---------------------------------------------- |
| `POSTGRESQL_USER` | User name for PostgreSQL account to be created |
| `POSTGRESQL_PASSWORD` | Password for the user account |
| `POSTGRESQL_DATABASE` | Database name |
| `POSTGRESQL_ADMIN_PASSWORD` | Password for the `postgres` admin account (optional) |
The following environment variables influence the PostgreSQL configuration file. They are all optional.
| Variable name | Description | Default
| :---------------------------- | ----------------------------------------------------------------------- | -------------------------------
| `POSTGRESQL_MAX_CONNECTIONS` | The maximum number of client connections allowed | 100
| `POSTGRESQL_MAX_PREPARED_TRANSACTIONS` | Sets the maximum number of transactions that can be in the "prepared" state. If you are using prepared transactions, you will probably want this to be at least as large as max_connections | 0
| `POSTGRESQL_SHARED_BUFFERS` | Sets how much memory is dedicated to PostgreSQL to use for caching data | 32M
| `POSTGRESQL_EFFECTIVE_CACHE_SIZE` | Set to an estimate of how much memory is available for disk caching by the operating system and within the database itself | 128M
You can also set the following mount points by passing the `-v /host:/container` flag to Docker.
| Volume mount point | Description |
| :----------------------- | ------------------------------------- |
| `/var/lib/pgsql/data` | PostgreSQL database cluster directory |
**Notice: When mouting a directory from the host into the container, ensure that the mounted
directory has the appropriate permissions and that the owner and group of the directory
matches the user UID or name which is running inside the container.**
Usage
----------------------
For this, we will assume that you are using the `openshift/postgresql-92-centos7` image.
If you want to set only the mandatory environment variables and not store the database
in a host directory, execute the following command:
```
$ docker run -d --name postgresql_database -e POSTGRESQL_USER=user -e POSTGRESQL_PASSWORD=pass -e POSTGRESQL_DATABASE=db -p 5432:5432 openshift/postgresql-92-centos7
```
This will create a container named `postgresql_database` running PostgreSQL with
database `db` and user with credentials `user:pass`. Port 5432 will be exposed
and mapped to the host. If you want your database to be persistent across container
executions, also add a `-v /host/db/path:/var/lib/pgsql/data` argument. This will be
the PostgreSQL database cluster directory.
If the database cluster directory is not initialized, the entrypoint script will
first run [`initdb`](http://www.postgresql.org/docs/9.2/static/app-initdb.html)
and setup necessary database users and passwords. After the database is initialized,
or if it was already present, [`postgres`](http://www.postgresql.org/docs/9.2/static/app-postgres.html)
is executed and will run as PID 1. You can stop the detached container by running
`docker stop postgresql_database`.
PostgreSQL auto-tuning
--------------------
When the PostgreSQL image is run with the `--memory` parameter set and if there
are no values provided for `POSTGRESQL_SHARED_BUFFERS` and
`POSTGRESQL_EFFECTIVE_CACHE_SIZE` those values are automatically calculated
based on the value provided in the `--memory` parameter.
The values are calculated based on the
[upstream](https://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server)
formulas. For the `shared_buffers` we use 1/4 of given memory and for the
`effective_cache_size` we set the value to 1/2 of the given memory.
PostgreSQL admin account
------------------------
The admin account `postgres` has no password set by default, only allowing local
connections. You can set it by setting the `POSTGRESQL_ADMIN_PASSWORD` environment
variable when initializing your container. This will allow you to login to the
`postgres` account remotely. Local connections will still not require a password.
Changing passwords
------------------
Since passwords are part of the image configuration, the only supported method
to change passwords for the database user (`POSTGRESQL_USER`) and `postgres`
admin user is by changing the environment variables `POSTGRESQL_PASSWORD` and
`POSTGRESQL_ADMIN_PASSWORD`, respectively.
Changing database passwords through SQL statements or any way other than through
the environment variables aforementioned will cause a mismatch between the
values stored in the variables and the actual passwords. Whenever a database
container starts it will reset the passwords to the values stored in the
environment variables.

View file

@ -0,0 +1,220 @@
# Configuration settings.
export POSTGRESQL_MAX_CONNECTIONS=${POSTGRESQL_MAX_CONNECTIONS:-100}
export POSTGRESQL_MAX_PREPARED_TRANSACTIONS=${POSTGRESQL_MAX_PREPARED_TRANSACTIONS:-0}
# Perform auto-tuning based on the container cgroups limits (only when the
# limits are set).
# Users can still override this by setting the POSTGRESQL_SHARED_BUFFERS
# and POSTGRESQL_EFFECTIVE_CACHE_SIZE variables.
if [[ "${NO_MEMORY_LIMIT:-}" == "true" || -z "${MEMORY_LIMIT_IN_BYTES:-}" ]]; then
export POSTGRESQL_SHARED_BUFFERS=${POSTGRESQL_SHARED_BUFFERS:-32MB}
export POSTGRESQL_EFFECTIVE_CACHE_SIZE=${POSTGRESQL_EFFECTIVE_CACHE_SIZE:-128MB}
else
# Use 1/4 of given memory for shared buffers
shared_buffers_computed="$(($MEMORY_LIMIT_IN_BYTES/1024/1024/4))MB"
# Setting effective_cache_size to 1/2 of total memory would be a normal conservative setting,
effective_cache="$(($MEMORY_LIMIT_IN_BYTES/1024/1024/2))MB"
export POSTGRESQL_SHARED_BUFFERS=${POSTGRESQL_SHARED_BUFFERS:-$shared_buffers_computed}
export POSTGRESQL_EFFECTIVE_CACHE_SIZE=${POSTGRESQL_EFFECTIVE_CACHE_SIZE:-$effective_cache}
fi
export POSTGRESQL_RECOVERY_FILE=$HOME/openshift-custom-recovery.conf
export POSTGRESQL_CONFIG_FILE=$HOME/openshift-custom-postgresql.conf
postinitdb_actions=
psql_identifier_regex='^[a-zA-Z_][a-zA-Z0-9_]*$'
psql_password_regex='^[a-zA-Z0-9_~!@#$%^&*()-=<>,.?;:|]+$'
# match . files when moving userdata below
shopt -s dotglob
# extglob enables the !(userdata) glob pattern below.
shopt -s extglob
function usage() {
if [ $# == 1 ]; then
echo >&2 "error: $1"
fi
cat >&2 <<EOF
You must either specify the following environment variables:
POSTGRESQL_USER (regex: '$psql_identifier_regex')
POSTGRESQL_PASSWORD (regex: '$psql_password_regex')
POSTGRESQL_DATABASE (regex: '$psql_identifier_regex')
Or the following environment variable:
POSTGRESQL_ADMIN_PASSWORD (regex: '$psql_password_regex')
Or both.
Optional settings:
POSTGRESQL_MAX_CONNECTIONS (default: 100)
POSTGRESQL_MAX_PREPARED_TRANSACTIONS (default: 0)
POSTGRESQL_SHARED_BUFFERS (default: 32MB)
For more information see /usr/share/container-scripts/postgresql/README.md
within the container or visit https://github.com/openshift/postgresql.
EOF
exit 1
}
function check_env_vars() {
if [[ -v POSTGRESQL_USER || -v POSTGRESQL_PASSWORD || -v POSTGRESQL_DATABASE ]]; then
# one var means all three must be specified
[[ -v POSTGRESQL_USER && -v POSTGRESQL_PASSWORD && -v POSTGRESQL_DATABASE ]] || usage
[[ "$POSTGRESQL_USER" =~ $psql_identifier_regex ]] || usage
[[ "$POSTGRESQL_PASSWORD" =~ $psql_password_regex ]] || usage
[[ "$POSTGRESQL_DATABASE" =~ $psql_identifier_regex ]] || usage
[ ${#POSTGRESQL_USER} -le 63 ] || usage "PostgreSQL username too long (maximum 63 characters)"
[ ${#POSTGRESQL_DATABASE} -le 63 ] || usage "Database name too long (maximum 63 characters)"
postinitdb_actions+=",simple_db"
fi
if [ -v POSTGRESQL_ADMIN_PASSWORD ]; then
[[ "$POSTGRESQL_ADMIN_PASSWORD" =~ $psql_password_regex ]] || usage
postinitdb_actions+=",admin_pass"
fi
case ",$postinitdb_actions," in
*,admin_pass,*|*,simple_db,*) ;;
*) usage ;;
esac
}
# Make sure env variables don't propagate to PostgreSQL process.
function unset_env_vars() {
unset POSTGRESQL_{DATABASE,USER,PASSWORD,ADMIN_PASSWORD}
}
# postgresql_master_addr lookups the 'postgresql-master' DNS and get list of the available
# endpoints. Each endpoint is a PostgreSQL container with the 'master' PostgreSQL running.
function postgresql_master_addr() {
local service_name=${POSTGRESQL_MASTER_SERVICE_NAME:-postgresql-master}
local endpoints=$(dig ${service_name} A +search | grep ";${service_name}" | cut -d ';' -f 2 2>/dev/null)
# FIXME: This is for debugging (docker run)
if [ -v POSTGRESQL_MASTER_IP ]; then
endpoints=${POSTGRESQL_MASTER_IP:-}
fi
if [ -z "$endpoints" ]; then
>&2 echo "Failed to resolve PostgreSQL master IP address"
exit 3
fi
echo -n "$(echo $endpoints | cut -d ' ' -f 1)"
}
# New config is generated every time a container is created. It only contains
# additional custom settings and is included from $PGDATA/postgresql.conf.
function generate_postgresql_config() {
envsubst \
< "${CONTAINER_SCRIPTS_PATH}/openshift-custom-postgresql.conf.template" \
> "${POSTGRESQL_CONFIG_FILE}"
if [ "${ENABLE_REPLICATION}" == "true" ]; then
envsubst \
< "${CONTAINER_SCRIPTS_PATH}/openshift-custom-postgresql-replication.conf.template" \
>> "${POSTGRESQL_CONFIG_FILE}"
fi
}
function generate_postgresql_recovery_config() {
envsubst \
< "${CONTAINER_SCRIPTS_PATH}/openshift-custom-recovery.conf.template" \
> "${POSTGRESQL_RECOVERY_FILE}"
}
# Generate passwd file based on current uid
function generate_passwd_file() {
export USER_ID=$(id -u)
export GROUP_ID=$(id -g)
grep -v ^postgres /etc/passwd > "$HOME/passwd"
echo "postgres:x:${USER_ID}:${GROUP_ID}:PostgreSQL Server:${HOME}:/bin/bash" >> "$HOME/passwd"
export LD_PRELOAD=libnss_wrapper.so
export NSS_WRAPPER_PASSWD=${HOME}/passwd
export NSS_WRAPPER_GROUP=/etc/group
}
function initialize_database() {
# Initialize the database cluster with utf8 support enabled by default.
# This might affect performance, see:
# http://www.postgresql.org/docs/9.5/static/locale.html
LANG=${LANG:-en_US.utf8} initdb
# PostgreSQL configuration.
cat >> "$PGDATA/postgresql.conf" <<EOF
# Custom OpenShift configuration:
include '${POSTGRESQL_CONFIG_FILE}'
EOF
# Access control configuration.
# FIXME: would be nice-to-have if we could allow connections only from
# specific hosts / subnet
cat >> "$PGDATA/pg_hba.conf" <<EOF
#
# Custom OpenShift configuration starting at this point.
#
# Allow connections from all hosts.
host all all all md5
# Allow replication connections from all hosts.
host replication all all md5
EOF
}
function create_users() {
if [[ ",$postinitdb_actions," = *,simple_db,* ]]; then
createuser "$POSTGRESQL_USER"
createdb --owner="$POSTGRESQL_USER" "$POSTGRESQL_DATABASE"
fi
if [ -v POSTGRESQL_MASTER_USER ]; then
createuser "$POSTGRESQL_MASTER_USER"
fi
}
function set_passwords() {
if [[ ",$postinitdb_actions," = *,simple_db,* ]]; then
psql --command "ALTER USER \"${POSTGRESQL_USER}\" WITH ENCRYPTED PASSWORD '${POSTGRESQL_PASSWORD}';"
fi
if [ -v POSTGRESQL_MASTER_USER ]; then
psql --command "ALTER USER \"${POSTGRESQL_MASTER_USER}\" WITH REPLICATION;"
psql --command "ALTER USER \"${POSTGRESQL_MASTER_USER}\" WITH ENCRYPTED PASSWORD '${POSTGRESQL_MASTER_PASSWORD}';"
fi
if [ -v POSTGRESQL_ADMIN_PASSWORD ]; then
psql --command "ALTER USER \"postgres\" WITH ENCRYPTED PASSWORD '${POSTGRESQL_ADMIN_PASSWORD}';"
fi
}
function set_pgdata ()
{
# backwards compatibility case, we used to put the data here,
# move it into our new expected location (userdata)
if [ -e ${HOME}/data/PG_VERSION ]; then
mkdir -p "${HOME}/data/userdata"
pushd "${HOME}/data"
# move everything except the userdata directory itself, into the userdata directory.
mv !(userdata) "userdata"
popd
else
# create a subdirectory that the user owns
mkdir -p "${HOME}/data/userdata"
fi
export PGDATA=$HOME/data/userdata
# ensure sane perms for postgresql startup
chmod 700 "$PGDATA"
}
function wait_for_postgresql_master() {
while true; do
master_fqdn=$(postgresql_master_addr)
echo "Waiting for PostgreSQL master (${master_fqdn}) to accept connections ..."
if [ -v POSTGRESQL_ADMIN_PASSWORD ]; then
PGPASSWORD=${POSTGRESQL_ADMIN_PASSWORD} psql "postgresql://postgres@${master_fqdn}" -c "SELECT 1;" && return 0
else
PGPASSWORD=${POSTGRESQL_PASSWORD} psql "postgresql://${POSTGRESQL_USER}@${master_fqdn}/${POSTGRESQL_DATABASE}" -c "SELECT 1;" && return 0
fi
sleep 1
done
}

View file

@ -0,0 +1,7 @@
# required on master for replication
wal_level = hot_standby # minimal, archive, hot_standby, or logical
max_wal_senders = 6 # max number of walsender processes
wal_keep_segments = 400 # in logfile segments, 16MB each; 0 disables
# required on replicas for replication
hot_standby = on

View file

@ -0,0 +1,21 @@
#
# Custom OpenShift configuration.
#
# NOTE: This file is rewritten every time the container is started!
# Changes to this file will be overwritten.
#
# Listen on all interfaces.
listen_addresses = '*'
# Determines the maximum number of concurrent connections to the database server. Default: 100
max_connections = ${POSTGRESQL_MAX_CONNECTIONS}
# Allow each connection to use a prepared transaction
max_prepared_transactions = ${POSTGRESQL_MAX_PREPARED_TRANSACTIONS}
# Sets the amount of memory the database server uses for shared memory buffers. Default: 32MB
shared_buffers = ${POSTGRESQL_SHARED_BUFFERS}
# Sets the planner's assumption about the effective size of the disk cache that is available to a single query
effective_cache_size = ${POSTGRESQL_EFFECTIVE_CACHE_SIZE}

View file

@ -0,0 +1,9 @@
#
# Custom OpenShift configuration.
#
# NOTE: This file is rewritten every time the container is started!
# Changes to this file will be overwritten.
#
standby_mode = on
primary_conninfo = 'host=${MASTER_FQDN} port=5432 user=${POSTGRESQL_MASTER_USER} password=${POSTGRESQL_MASTER_PASSWORD}'

View file

@ -0,0 +1,3 @@
# This will make scl collection binaries work out of box.
unset BASH_ENV PROMPT_COMMAND ENV
source scl_source enable $ENABLED_COLLECTIONS