|
1 | 1 | # CYBERTEC-pg-container: PostgreSQL-HA-Cluster based on Rocky-Linux |
2 | 2 |
|
3 | | -<p>CYBERTEC-pg-container is a Docker suite that combines PostgreSQL, Patroni and etcd to create HA-PostgreSQL clusters based on containers. This suite is also the imagebase for the CYBERTEC-pg-operator(cpo).</p> |
| 3 | +CYBERTEC-pg-container is a container suite that combines PostgreSQL, Patroni, etcd and pgBackRest to provide highly available (HA) PostgreSQL clusters. |
| 4 | + |
| 5 | +The images are based on Rocky Linux 9 and can be run locally or in container orchestrations such as Docker, Podman, Kubernetes, OpenShift or Rancher. |
| 6 | +This project also forms the basis for the [CYBERTEC-pg-operator(cpo)](https://github.com/cybertec-postgresql/CYBERTEC-pg-operator). |
4 | 7 |
|
5 | | -## Documentation |
| 8 | +## Container Images |
6 | 9 |
|
7 | | -<p>See the documentation for some examples of how to run this suite in Docker, Kubernetes or Kubernetes-based environments.</p> |
| 10 | +Ready-made images are available on Docker Hub:[https://hub.docker.com/repository/docker/cybertecpostgresql/cybertec-pg-container](https://hub.docker.com/repository/docker/cybertecpostgresql/cybertec-pg-container) |
8 | 11 |
|
9 | | -## Operational area |
10 | | -<p>These images can run locally on Docker, Kubernetes or on Kubernetes-based environments such as Openshift or Rancher. |
11 | | -On Kubernetes and Kubernetes-based environments, the image uses the k8-etcd, otherwise etcd is included locally in the image</p> |
| 12 | +## Build Instructions (optional) |
12 | 13 |
|
13 | | -## Build Images |
| 14 | +If you want to build the images yourself, you can do so with `make`. |
| 15 | +Ensure that the path to the container folder in the Makefile is adjusted to your system, otherwise the Dockerfiles will not be found. |
| 16 | +Simply adjust the BasePath or directly the RootPath. |
14 | 17 |
|
15 | | -<p>To create the images via Makefile, you need the following environment variables and Go on your system.</p> |
| 18 | +```Makefile |
| 19 | +BASEPATH ?= $(HOME) |
| 20 | +ROOTPATH ?= $(BASEPATH)/src/github.com/cybertec/cybertec-pg-container |
| 21 | +``` |
16 | 22 |
|
17 | | - export GOPATH=$HOME/cdev |
18 | | - export GOBIN=$GOPATH/bin |
19 | | - export PATH=$PATH:$GOBIN |
20 | | - export BASE_IMAGE=rockylinux:9 |
21 | | - export CONTAINERIMAGE=rockylinux/rockylinux:9-ubi-micro |
22 | | - export IMAGE_REPOSITORY=docker.io |
23 | | - export BASEOS=rocky9 |
24 | | - export PACKAGER=dnf |
25 | | - export CONTAINERSUITE=cybertec-pg-container |
26 | | - export PGBACKREST_VERSION=2.54.0 |
27 | | - export CCPROOT=$GOPATH/src/github.com/cybertec/cybertec-pg-container |
28 | | - export PATRONI_VERSION=3.3.2 |
29 | | - export POSTGIS_VERSION=34 |
30 | | - export PGVERSION=17 |
31 | | - export PGVERSION_FULL=17.2 |
32 | | - export OLD_PG_VERSIONS="13 14 15 16" |
33 | | - export BUILD=1 |
34 | | - export ARCH=amd64 |
| 23 | +### Requirements |
35 | 24 |
|
36 | | - # Also use the ENV ROOTPATH to refer to the CYBERTEC-pg-container repo on your system. Otherwise the Dockerfiles cannot be found |
37 | | - export ROOTPATH=$(GOPATH)/src/github.com/cybertec/cybertec-pg-container |
| 25 | +- Linux system with Docker or Podman |
| 26 | +- make installed |
38 | 27 |
|
39 | | -<p>You can build all images with make |
40 | | -- make all |
41 | | -- make postgres |
42 | | -- make postgres-gis |
43 | | -- make pgbackrest |
44 | | -- make pgbouncer |
45 | | -- make exporter |
46 | | -</p> |
47 | | -<p>Run Images locally:</p> |
| 28 | +### Example |
48 | 29 |
|
49 | | - docker run -it IMAGEPATH:IMAGETAG |
| 30 | +```bash |
| 31 | +make all |
| 32 | +# or individual components: |
| 33 | +make postgres |
| 34 | +make postgres-gis |
| 35 | +make pgbackrest |
| 36 | +make pgbouncer |
| 37 | +make exporter |
| 38 | +``` |
50 | 39 |
|
51 | | -<p>Take a look inside:</p> |
| 40 | +### Run Postgres-Image locally |
| 41 | +```bash |
| 42 | + docker run postgres -it IMAGEPATH:IMAGETAG |
52 | 43 |
|
53 | | - docker exec -it CONTAINERID /bin/bash |
| 44 | + docker exec -it postgres /bin/bash |
| 45 | +``` |
54 | 46 |
|
| 47 | +## Postgres-Versions and Extensions |
| 48 | +The container currently contains major releases 13 to 17. ENV PGVERSION can be used to select the desired version during initialisation. |
| 49 | +The latest minor release for each major version is always used. |
| 50 | +Hint: PostgreSQL 13 is deprecated. |
55 | 51 |
|
| 52 | +### Extensions |
| 53 | +In addition to the Contrib packages with the basic extensions, the following extensions are also included in the container: |
| 54 | + |
| 55 | + - **credcheck**: Allows you to define password policies, login information checks and more. |
| 56 | + |
| 57 | +- **pg_cron**: Allows you to schedule and execute time-controlled jobs directly in PostgreSQL. |
| 58 | + |
| 59 | +- **pg_permissions**: Provides advanced functions for querying and managing database permissions. |
| 60 | + |
| 61 | +- **pg_vector**: Adds support for vector operations (e.g. for AI/embedding data). |
| 62 | + |
| 63 | +- **pgAudit**: Enables PostgreSQL audit logging. Ideal for security and compliance requirements. |
| 64 | + |
| 65 | +- **pgauditlogtofile**: When enabled, pgAudit logs are written directly to files instead of the standard logs. |
| 66 | + |
| 67 | +- **pgextwlist**: Manages a ‘whitelist’ of permitted extensions to prevent the use of insecure extensions. |
| 68 | + |
| 69 | +- **pgnodemx**: Supports multi-node cluster functions, e.g. for sharding or replication extensions. |
| 70 | + |
| 71 | +- **plpython3**: Enables the use of Python 3 as an embedded programming language in PostgreSQL. |
| 72 | + |
| 73 | +- **set_user**: Enables setting and switching user contexts within the database for administrative tasks. |
| 74 | + |
| 75 | +- **timescaleDB**: Adds functions for time series data, including hypertables and continuous aggregations. |
| 76 | + |
| 77 | +In addition, there is an additional postgis-image. It contains all of the extensions listed above and Postgis. |
| 78 | + |
| 79 | +## Environment-Variables |
| 80 | +### postgres-container |
| 81 | +#### Patroni and PostgreSQL |
| 82 | + |
| 83 | +- **ETCD3_HOST**: the DNS A record pointing to Etcd hosts. |
| 84 | +- **ETCD3_HOSTS**: list of Etcd hosts in format '"host1:port1","host2:port2",...,"hostN:portN"'. |
| 85 | +- **ETCD3_DISCOVERY_DOMAIN**: the DNS SRV record pointing to Etcd hosts. |
| 86 | +- **ETCD3_URL**: url for Etcd host in format http(s)://host1:port |
| 87 | +- **ETCD3_PROXY**: url for Etcd Proxy format http(s)://host1:port |
| 88 | +- **ETCD3_CACERT**: Etcd CA certificate. If present it will enable validation. |
| 89 | +- **ETCD3_CERT**: Etcd client certificate. |
| 90 | +- **ETCD3_KEY**: Etcd client certificate key. Can be empty if the key is part of certificate. |
| 91 | +- **PGHOME**: filesystem path where to put PostgreSQL home directory (/home/postgres by default) |
| 92 | +- **APIPORT**: TCP port to Patroni API connections (8008 by default) |
| 93 | +- **CRONTAB**: anything that you want to run periodically as a cron job (empty by default) |
| 94 | +- **PGROOT**: a directory where we put the pgdata (by default /home/postgres/pgroot). One may adjust it to point to the mount point of the persistent volume, such as EBS. |
| 95 | +- **WALE_TMPDIR** or **WALG_TMPDIR**: directory to store WAL-G temporary files. PGROOT/../tmp by default, make sure it has a few GBs of free space. |
| 96 | +- **PGDATA**: location of PostgreSQL data directory, by default PGROOT/pgdata. |
| 97 | +- **PGUSER_STANDBY**: username for the replication user, 'standby' by default. |
| 98 | +- **PGPASSWORD_STANDBY**: a password for the replication user, 'standby' by default. |
| 99 | +- **STANDBY_HOST**: hostname or IP address of the primary to stream from. |
| 100 | +- **STANDBY_PORT**: TCP port on which the primary is listening for connections. Patroni will use "5432" if not set. |
| 101 | +- **STANDBY_PRIMARY_SLOT_NAME**: replication slot to use on the primary. |
| 102 | +- **PGUSER_ADMIN**: username for the default admin user, 'admin' by default. |
| 103 | +- **PGPASSWORD_ADMIN**: a password for the default admin user, 'cola' by default. |
| 104 | +- **USE_ADMIN**: whether to use the admin user or not. |
| 105 | +- **PGUSER_SUPERUSER**: username for the superuser, 'postgres' by default. |
| 106 | +- **PGPASSWORD_SUPERUSER**: a password for the superuser, 'zalando' by default |
| 107 | +- **ALLOW_NOSSL**: set to allow clients to connect without SSL enabled. |
| 108 | +- **PGPORT**: port PostgreSQL listens to for client connections, 5432 by default |
| 109 | +- **PGVERSION**: Specifies the version of postgreSQL to reference in the bin_dir variable (/usr/lib/postgresql/PGVERSION/bin) (13/14/15/16/17) |
| 110 | +- **SCOPE**: cluster name, multiple Spilos belonging to the same cluster must have identical scope. |
| 111 | +- **SSL_CA_FILE**: path to the SSL CA certificate file inside the container (by default: '') |
| 112 | +- **SSL_CRL_FILE**: path to the SSL Certificate Revocation List file inside the container (by default: '') |
| 113 | +- **SSL_CERTIFICATE_FILE**: path to the SSL certificate file inside the container (by default /run/certs/server.crt), Spilo will generate one if not present. |
| 114 | +- **SSL_PRIVATE_KEY_FILE**: path to the SSL private key within the container (by default /run/certs/server.key), Spilo will generate one if not present |
| 115 | +- **SSL_CA**: content of the SSL CA certificate in the SSL_CA_FILE file (by default: '') |
| 116 | +- **SSL_CRL**: content of the SSL Certificate Revocation List in the SSL_CRL_FILE file (by default: '') |
| 117 | +- **SSL_CERTIFICATE**: content of the SSL certificate in the SSL_CERTIFICATE_FILE file (by default /run/certs/server.crt). |
| 118 | +- **SSL_PRIVATE_KEY**: content of the SSL private key in the SSL_PRIVATE_KEY_FILE file (by default /run/certs/server.key). |
| 119 | +- **SSL_RESTAPI_CA_FILE**: path to the Patroni REST Api SSL CA certificate file inside the container (by default: '') |
| 120 | +- **SSL_RESTAPI_CERTIFICATE_FILE**: path to the Patroni REST Api SSL certificate file inside the container (by default /run/certs/restapi.crt), The Container will generate one if not present. |
| 121 | +- **SSL_RESTAPI_PRIVATE_KEY_FILE**: path to the Patroni REST Api SSL private key within the container (by default /run/certs/restapi.key), The Container will generate one if not present |
| 122 | +- **SSL_RESTAPI_CA**: content of the Patroni REST Api SSL CA certificate in the SSL_RESTAPI_CA_FILE file (by default: '') |
| 123 | +- **SSL_RESTAPI_CERTIFICATE**: content of the REST Api SSL certificate in the SSL_CERTIFICATE_FILE file (by default /run/certs/server.crt). |
| 124 | +- **SSL_RESTAPI_PRIVATE_KEY**: content of the REST Api SSL private key in the SSL_PRIVATE_KEY_FILE file (by default /run/certs/server.key). |
| 125 | +- **SSL_TEST_RELOAD**: whenever to test for certificate rotation and reloading (by default True if SSL_PRIVATE_KEY_FILE has been set). |
| 126 | +- **RESTAPI_CONNECT_ADDRESS**: when you configure Patroni RESTAPI in SSL mode some safe API (i.e. switchover) perform hostname validation. In this case could be convenient configure ````restapi.connect_address````as a hostname instead of IP. For example, you can configure it as "$(POD_NAME).<service name>". |
| 127 | +- **DCS_ENABLE_KUBERNETES_API**: a non-empty value forces Patroni to use Kubernetes as a DCS. Default is empty. |
| 128 | +- **KUBERNETES_USE_CONFIGMAPS**: a non-empty value makes Patroni store its metadata in ConfigMaps instead of Endpoints when running on Kubernetes. Default is empty. |
| 129 | +- **KUBERNETES_ROLE_LABEL**: name of the label containing Postgres role when running on Kubernetes. Default is 'spilo-role'. |
| 130 | +- **KUBERNETES_LEADER_LABEL_VALUE**: value of the pod label if Postgres role is primary when running on Kubernetes. Default is 'master'. |
| 131 | +- **KUBERNETES_STANDBY_LEADER_LABEL_VALUE**: value of the pod label if Postgres role is standby_leader when running on Kubernetes. Default is 'master'. |
| 132 | +- **KUBERNETES_SCOPE_LABEL**: name of the label containing cluster name. Default is 'version'. |
| 133 | +- **KUBERNETES_LABELS**: a JSON describing names and values of other labels used by Patroni on Kubernetes to locate its metadata. Default is '{"application": "spilo"}'. |
| 134 | +- **KUBERNETES_BOOTSTRAP_LABELS**: a JSON describing names and values of labels used by Patroni as ``kubernetes.bootstrap_labels``. Default is empty. |
| 135 | +- **ENABLE_WAL_PATH_COMPAT**: old Spilo images were generating wal path in the backup store using the following template ``/spilo/{WAL_BUCKET_SCOPE_PREFIX}{SCOPE} |
| 136 | + |
| 137 | +#### Initdb |
| 138 | +- **INITDB_LOCALE**: database cluster's default UTF-8 locale (en_US by default) |
| 139 | + |
| 140 | + Hint: locale-provider is icu |
| 141 | + |
| 142 | +#### pgbackRest |
| 143 | + |
| 144 | +- **USE_PGBACKREST**: Set to true if you want to use pgBackRest |
| 145 | +- **REPO_HOST**: Set to true if you want to use local storage for pgBackRest instead of s3,gcs or azure blob. Default: false |
| 146 | + |
| 147 | + |
| 148 | +### pgBackRest-Container |
| 149 | +- **USE_PGBACKREST**: Set to true if you want to use pgBackRest |
| 150 | +- **MODE**: Set to repo if you want to use the container as repo-host for you cluster. Set to restore if you want to use it as a restore container. |
| 151 | +- **RESTORE_COMMAND**: Add your restore parameters (needs Mode set to restore) example: ' --repo=1 --set=20251009-085046F --type=immediate' |
| 152 | +- **RESTORE_ENABLE**: Set to true if you want to do a restore (needs Mode set to restore) |
| 153 | + |
| 154 | +### Exporter-Container |
| 155 | +- **DATA_SOURCE_URI**: Specify the full URI of the database to be monitored. Example: `localhost:5432/postgres?sslmode=require` |
| 156 | +- **DATA_SOURCE_USER**: Username of the PostgreSQL account used by the exporter to access the database. Ensure that this user has sufficient read permissions. |
| 157 | +- **DATA_SOURCE_PASS**: Password for the user specified above. |
| 158 | + |
| 159 | +### pgBouncer-Container |
| 160 | +- **PGHOST**: Host name or IP address of the PostgreSQL server to which pgBouncer should establish connections. |
| 161 | +- **PGPORT**: Port of the PostgreSQL server (default: 5432). |
| 162 | +- **PGUSER**: User name for connecting to PostgreSQL. pgBouncer uses this user to manage pool connections. |
| 163 | +- **PGSCHEMA**: The schema within the database that pgBouncer should access by default. |
| 164 | +- **PGPASSWORD**: Password of the user specified above. |
| 165 | +- **CONNECTION_POOLER_PORT**: TCP port on which pgBouncer listens for client connections (default: 6432) |
| 166 | +- **CONNECTION_POOLER_MODE**: Operating mode of pgBouncer. Typical values are `session`, `transaction` or `statement`. |
| 167 | +- **CONNECTION_POOLER_DEFAULT_SIZE**: Default size of the connection pool per database and user. |
| 168 | +- **CONNECTION_POOLER_MIN_SIZE**: Minimum number of connections that pgBouncer maintains. |
| 169 | +- **CONNECTION_POOLER_RESERVE_SIZE**: Number of reserve connections that are additionally available during high load. |
| 170 | +- **CONNECTION_POOLER_MAX_CLIENT_CONN**: Maximum number of simultaneous client connections that pgBouncer accepts |
| 171 | +- **CONNECTION_POOLER_MAX_DB_CONN**: Maximum number of connections that can be established to a single database. |
0 commit comments