Skip to content

Commit 8810b60

Browse files
committed
✨ Add patroni image
Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev>
1 parent b8fc13b commit 8810b60

6 files changed

Lines changed: 299 additions & 0 deletions

File tree

.github/workflows/patroni.yaml

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
on:
2+
push:
3+
branches:
4+
- main
5+
paths:
6+
- .github/workflows/patroni.yaml
7+
- patroni/*
8+
- '!patroni/README.md'
9+
10+
permissions:
11+
contents: write
12+
packages: write
13+
14+
jobs:
15+
build-image:
16+
strategy:
17+
matrix:
18+
pg_version:
19+
- "17"
20+
- "16"
21+
- "15"
22+
- "14"
23+
- "13"
24+
25+
name: Build Image
26+
runs-on: ubuntu-latest
27+
env:
28+
REGISTRY: ghcr.io
29+
IMAGE_NAME: parmincloud/containers/patroni
30+
PATRONI_VERSION: 4.0.6
31+
32+
steps:
33+
- name: Checkout repository
34+
uses: actions/checkout@v4
35+
36+
- name: Set up QEMU
37+
uses: docker/setup-qemu-action@v3
38+
39+
- name: Setup Docker buildx
40+
uses: docker/setup-buildx-action@v3
41+
42+
- name: Log into registry ${{ env.REGISTRY }}
43+
uses: docker/login-action@v3
44+
with:
45+
registry: ${{ env.REGISTRY }}
46+
username: ${{ github.actor }}
47+
password: ${{ secrets.GITHUB_TOKEN }}
48+
49+
- name: Extract Docker metadata
50+
id: meta
51+
uses: docker/metadata-action@v5
52+
with:
53+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
54+
55+
- name: Build and push Docker image
56+
id: build-and-push-release
57+
uses: docker/build-push-action@v6
58+
with:
59+
cache-from: type=gha
60+
cache-to: type=gha,mode=max
61+
context: ./patroni
62+
file: ./patroni/Containerfile
63+
labels: ${{ steps.meta.outputs.labels }}
64+
push: true
65+
platforms: linux/amd64
66+
build-args: |
67+
PGVERSION=${{ matrix.pg_version }}
68+
PATRONI_VERSION=${{ env.PATRONI_VERSION }}
69+
tags: |
70+
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.PATRONI_VERSION }}-pg${{ matrix.pg_version }}
71+

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ Publicly available Container Images (published on `ghcr.io`)
55
## Available images
66

77
* [PHP](./php/README.md)
8+
* [Patroni](./patroni/README.md)

patroni/Containerfile

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
ARG PGVERSION
2+
ARG PATRONI_VERSION
3+
FROM postgres:${PGVERSION}
4+
5+
ARG PGVERSION
6+
ARG PATRONI_VERSION
7+
ENV PATRONI_CONFIG=/etc/patroni.yml
8+
9+
RUN apt-get update && \
10+
apt-get install -y --no-install-recommends \
11+
python3-pip \
12+
python3-dev \
13+
python3-full \
14+
libpq-dev \
15+
build-essential \
16+
postgresql-plpython3-${PGVERSION} \
17+
curl \
18+
jq \
19+
net-tools \
20+
iputils-ping \
21+
dumb-init \
22+
vim \
23+
less \
24+
locales \
25+
&& \
26+
rm -rf /var/lib/apt/lists/*
27+
28+
RUN python3 -m venv /opt/patroni-venv
29+
ENV PATH="/opt/patroni-venv/bin:$PATH"
30+
31+
RUN pip3 install --no-cache-dir \
32+
patroni[all,psycopg3]==${PATRONI_VERSION}
33+
34+
COPY patroni.yml ${PATRONI_CONFIG}
35+
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
36+
RUN chmod +x /usr/local/bin/entrypoint.sh
37+
38+
ENV PATRONI_POSTGRESQL_DATA_DIR=/var/lib/postgresql/data
39+
ENV PATRONI_POSTGRESQL_CONFIG_DIR=${PATRONI_POSTGRESQL_DATA_DIR}
40+
41+
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
42+
CMD ["patroni"]

patroni/README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Patroni Container images
2+
3+
Minimal Patroni container images for running PostgreSQL clusters in containers (specially non-kubernetes environments).
4+
5+
## Available images
6+
7+
We are supprting latest patroni version with supported PostgreSQL versions. (17, 16, 15, 14, 13)
8+
9+
`ghcr.io/parmincloud/containers/patroni:<patroni_version>-pg<pg_version>`
10+
11+
Currently available images are:
12+
13+
* `ghcr.io/parmincloud/containers/patroni:4.0.6-pg17`
14+
* `ghcr.io/parmincloud/containers/patroni:4.0.6-pg16`
15+
* `ghcr.io/parmincloud/containers/patroni:4.0.6-pg15`
16+
* `ghcr.io/parmincloud/containers/patroni:4.0.6-pg14`
17+
* `ghcr.io/parmincloud/containers/patroni:4.0.6-pg13`
18+
19+
## Usage
20+
21+
Bind mount your configuration file to `/etc/patroni.yml` and run the container (Can be overritten by setting `PATRONI_CONFIG`).
22+
and also bind mount your data directory to `/var/lib/postgresql/data`.
23+
24+
Do not forget to expose required ports (according to your configuration file).
25+
default configuration file is available at [./patroni.yml](./patroni.yml).

patroni/entrypoint.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env bash
2+
3+
set -exu -o pipefail
4+
5+
if [ $1 != "patroni" ]; then
6+
exec "$@"
7+
fi
8+
9+
echo "Checking if patroni configuration file exists..."
10+
if [ ! -n "${PATRONI_CONFIG}" ]; then
11+
echo "PATRONI_CONFIG is not set. Exiting."
12+
exit 1
13+
fi
14+
if [ ! -f "${PATRONI_CONFIG}" ]; then
15+
echo "Patroni configuration file ${PATRONI_CONFIG} does not exist. Exiting."
16+
exit 1
17+
fi
18+
19+
echo "Starting Patroni..."
20+
exec patroni \
21+
"${PATRONI_CONFIG}"
22+
"$@"

patroni/patroni.yml

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
#scope: batman
2+
#namespace: /service/
3+
#name: postgresql0
4+
5+
restapi:
6+
listen: 0.0.0.0:8008
7+
# connect_address: 127.0.0.1:8008
8+
# cafile: /etc/ssl/certs/ssl-cacert-snakeoil.pem
9+
# certfile: /etc/ssl/certs/ssl-cert-snakeoil.pem
10+
# keyfile: /etc/ssl/private/ssl-cert-snakeoil.key
11+
# authentication:
12+
# username: username
13+
# password: password
14+
15+
#ctl:
16+
# insecure: false # Allow connections to Patroni REST API without verifying certificates
17+
# certfile: /etc/ssl/certs/ssl-cert-snakeoil.pem
18+
# keyfile: /etc/ssl/private/ssl-cert-snakeoil.key
19+
# cacert: /etc/ssl/certs/ssl-cacert-snakeoil.pem
20+
21+
#etcd:
22+
#Provide host to do the initial discovery of the cluster topology:
23+
# host: 127.0.0.1:2379
24+
#Or use "hosts" to provide multiple endpoints
25+
#Could be a comma separated string:
26+
#hosts: host1:port1,host2:port2
27+
#or an actual yaml list:
28+
#hosts:
29+
#- host1:port1
30+
#- host2:port2
31+
#Once discovery is complete Patroni will use the list of advertised clientURLs
32+
#It is possible to change this behavior through by setting:
33+
#use_proxies: true
34+
35+
#raft:
36+
# data_dir: .
37+
# self_addr: 127.0.0.1:2222
38+
# partner_addrs:
39+
# - 127.0.0.1:2223
40+
# - 127.0.0.1:2224
41+
42+
# The bootstrap configuration. Works only when the cluster is not yet initialized.
43+
# If the cluster is already initialized, all changes in the `bootstrap` section are ignored!
44+
bootstrap:
45+
# This section will be written into Etcd:/<namespace>/<scope>/config after initializing new cluster
46+
# and all other cluster members will use it as a `global configuration`.
47+
# WARNING! If you want to change any of the parameters that were set up
48+
# via `bootstrap.dcs` section, please use `patronictl edit-config`!
49+
dcs:
50+
ttl: 30
51+
loop_wait: 10
52+
retry_timeout: 10
53+
maximum_lag_on_failover: 1048576
54+
# primary_start_timeout: 300
55+
# synchronous_mode: false
56+
#standby_cluster:
57+
#host: 127.0.0.1
58+
#port: 1111
59+
#primary_slot_name: patroni
60+
postgresql:
61+
use_pg_rewind: true
62+
pg_hba:
63+
- local all all trust
64+
# For kerberos gss based connectivity (discard @.*$)
65+
#- host replication replicator 127.0.0.1/32 gss include_realm=0
66+
#- host all all 0.0.0.0/0 gss include_realm=0
67+
- host replication replicator all md5
68+
- host all all all md5
69+
# - hostssl all all all md5
70+
# use_slots: true
71+
parameters:
72+
max_connections: 100
73+
# wal_level: hot_standby
74+
# hot_standby: "on"
75+
# max_connections: 100
76+
# max_worker_processes: 8
77+
# wal_keep_segments: 8
78+
# max_wal_senders: 10
79+
# max_replication_slots: 10
80+
# max_prepared_transactions: 0
81+
# max_locks_per_transaction: 64
82+
# wal_log_hints: "on"
83+
# track_commit_timestamp: "off"
84+
# archive_mode: "on"
85+
# archive_timeout: 1800s
86+
# archive_command: mkdir -p ../wal_archive && test ! -f ../wal_archive/%f && cp %p ../wal_archive/%f
87+
# recovery_conf:
88+
# restore_command: cp ../wal_archive/%f %p
89+
90+
# some desired options for 'initdb'
91+
initdb: # Note: It needs to be a list (some options need values, others are switches)
92+
- locale: en_US.UTF-8
93+
- encoding: UTF8
94+
- data-checksums
95+
96+
# Additional script to be launched after initial cluster creation (will be passed the connection URL as parameter)
97+
# post_init: /usr/local/bin/setup_cluster.sh
98+
99+
postgresql:
100+
listen: 0.0.0.0:5432
101+
# connect_address: 127.0.0.1:5432
102+
103+
# proxy_address: 127.0.0.1:5433 # The address of connection pool (e.g., pgbouncer) running next to Patroni/Postgres. Only for service discovery.
104+
data_dir: /var/lib/postgresql/data
105+
# bin_dir:
106+
config_dir: /var/lib/postgresql/data
107+
pgpass: /tmp/pgpass0
108+
# authentication:
109+
# replication:
110+
# username: replicator
111+
# password: rep-pass
112+
# superuser:
113+
# username: postgres
114+
# password: patroni
115+
# rewind: # Has no effect on postgres 10 and lower
116+
# username: rewind_user
117+
# password: rewind_password
118+
# Server side kerberos spn
119+
# krbsrvname: postgres
120+
# parameters:
121+
# Fully qualified kerberos ticket file for the running user
122+
# same as KRB5CCNAME used by the GSS
123+
# krb_server_keyfile: /var/spool/keytabs/postgres
124+
# unix_socket_directories: '..' # parent directory of data_dir
125+
# Additional fencing script executed after acquiring the leader lock but before promoting the replica
126+
#pre_promote: /path/to/pre_promote.sh
127+
128+
#watchdog:
129+
# mode: automatic # Allowed values: off, automatic, required
130+
# device: /dev/watchdog
131+
# safety_margin: 5
132+
133+
tags:
134+
# failover_priority: 1
135+
# sync_priority: 1
136+
noloadbalance: false
137+
clonefrom: false
138+
nostream: false

0 commit comments

Comments
 (0)