modified: .env
modified: README.md modified: compose.yml modified: configuration.py new file: haproxy.cfg new file: init-patroni-users.sql renamed: entrypoint.sh -> netbox-entrypoint.sh renamed: Containerfile -> netbox.Containerfile modified: nginx.conf new file: patroni-entrypoint.sh new file: patroni.Containerfile new file: patroni.yml
This commit is contained in:
1 parent
136ee48052
commit
e7b53b6965
12 files changed
+404
-41
No files matched your search
@@ -3,21 +3,21 @@ This project provides a fully working Netbox Installation connected to a BIND9
|
||||
Server for DNS distribution. Further components like acme certificate management
|
||||
will be added eventually.
|
||||
|
||||
## Build netbox image
|
||||
You can either build the netbox container yourself with following command or let
|
||||
compose pull it from my own repository at git.luethi.co. Note that the reason
|
||||
## Build images
|
||||
You can either build the netbox and patroni-postgres containers yourself or let
|
||||
compose pull them from the repository at git.luethi.co. Note that the reason
|
||||
i pushed all images to my repo that compose relies on is simply convenience and
|
||||
reducing load on dockerhub. You can modify `compose.yml` to source all but the
|
||||
`netbox` images from dockerhub instead.
|
||||
`netbox` and `patroni-postgres` images from dockerhub instead.
|
||||
|
||||
```bash
|
||||
# Build the image (bakes in plugins)
|
||||
# Build all images (bakes in netbox plugins + patroni)
|
||||
podman-compose --podman-build-args '\-\-network=host' build
|
||||
```
|
||||
|
||||
## Start the Stack via compose
|
||||
```bash
|
||||
# Start the full stack
|
||||
# Start the full stack (etcd + patroni HA + netbox)
|
||||
podman compose up -d
|
||||
```
|
||||
|
||||
@@ -25,11 +25,20 @@ podman compose up -d
|
||||
|
||||
## Building the image directly without compose
|
||||
```bash
|
||||
# NetBox
|
||||
podman build \
|
||||
-f netbox.Containerfile \
|
||||
--build-arg PYTHON_VERSION=3.14 \
|
||||
--build-arg NETBOX_VERSION=4.6.5 \
|
||||
--tag localhost/netbox:4.6.5 \
|
||||
.
|
||||
|
||||
# Patroni-Postgres
|
||||
podman build \
|
||||
-f patroni.Containerfile \
|
||||
--build-arg POSTGRES_VERSION=16 \
|
||||
--tag localhost/patroni-postgres:16 \
|
||||
.
|
||||
```
|
||||
|
||||
---
|
||||
@@ -41,3 +50,113 @@ podman build \
|
||||
3. Restart: `podman-compose up -d`
|
||||
|
||||
Migrations run automatically on startup via the entrypoint.
|
||||
|
||||
---
|
||||
|
||||
## PostgreSQL HA with Patroni
|
||||
|
||||
PostgreSQL runs as a 3-node Patroni cluster (1 leader + 2 replicas) with etcd
|
||||
as the Distributed Configuration Store (DCS). HAProxy routes write traffic to
|
||||
the current leader via Patroni REST API health checks.
|
||||
|
||||
### Architecture
|
||||
|
||||
```
|
||||
┌──────────────┐
|
||||
│ etcd │ :2379
|
||||
└──────┬───────┘
|
||||
│
|
||||
┌───────────────────┼───────────────────┐
|
||||
│ │ │
|
||||
┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐
|
||||
│ patroni1 │ │ patroni2 │ │ patroni3 │
|
||||
│ pg :5432 │ │ pg :5433 │ │ pg :5434 │
|
||||
│ api :8008 │ │ api :8009 │ │ api :8010 │
|
||||
│ (leader) │◄───│ (replica) │◄───│ (replica) │
|
||||
└──────┬──────┘ └─────────────┘ └─────────────┘
|
||||
│
|
||||
┌──────▼──────┐
|
||||
│ HAProxy │ :5000 → leader :7000 → stats
|
||||
└──────┬──────┘
|
||||
│
|
||||
┌──────▼──────┐
|
||||
│ NetBox │ connects to localhost:5000
|
||||
└─────────────┘
|
||||
```
|
||||
|
||||
### Ports
|
||||
|
||||
| Service | PostgreSQL | Patroni API |
|
||||
|----------|-----------|-------------|
|
||||
| patroni1 | 5432 | 8008 |
|
||||
| patroni2 | 5433 | 8009 |
|
||||
| patroni3 | 5434 | 8010 |
|
||||
|
||||
HAProxy listens on :5000 (write) and :7000 (stats UI).
|
||||
|
||||
### Cluster management
|
||||
|
||||
```bash
|
||||
# Show cluster topology
|
||||
podman exec patroni1 patronictl list
|
||||
|
||||
# Switchover (planned leader change)
|
||||
podman exec patroni1 patronictl switchover
|
||||
|
||||
# Check cluster health
|
||||
curl http://localhost:8008/health
|
||||
curl http://localhost:8008/cluster | jq .
|
||||
|
||||
# HAProxy stats UI
|
||||
open http://localhost:7000
|
||||
```
|
||||
|
||||
### Converting existing standalone PostgreSQL to Patroni
|
||||
|
||||
If you have an existing `postgres_data` volume from the old standalone postgres
|
||||
service, follow these steps to convert it to a Patroni-managed cluster:
|
||||
|
||||
1. **Stop the stack:**
|
||||
```bash
|
||||
podman compose down
|
||||
```
|
||||
|
||||
2. **Start only the old postgres temporarily** to create Patroni users:
|
||||
```bash
|
||||
podman compose run --rm --no-deps postgres \
|
||||
psql -U netbox -d netbox -f /init-patroni-users.sql
|
||||
```
|
||||
*(If the `postgres` service no longer exists in compose, use any postgres
|
||||
16-alpine container with the same volume mounted.)*
|
||||
|
||||
3. **Update pg_hba.conf** in the existing data volume to allow replication:
|
||||
```bash
|
||||
echo 'host replication replicator 0.0.0.0/0 md5' >> \
|
||||
/var/lib/containers/storage/volumes/netbox_postgres_data/_data/pg_hba.conf
|
||||
```
|
||||
|
||||
4. **Start the new Patroni stack:**
|
||||
```bash
|
||||
podman compose up -d
|
||||
```
|
||||
|
||||
- patroni1 detects the existing data and takes over management without
|
||||
re-initializing.
|
||||
- patroni2 and patroni3 start with empty data dirs and are bootstrapped as
|
||||
replicas via `pg_basebackup` from patroni1.
|
||||
|
||||
5. **Verify:**
|
||||
```bash
|
||||
podman exec patroni1 patronictl list
|
||||
```
|
||||
Should show 1 Leader + 2 Replicas in `running` / `streaming` state.
|
||||
|
||||
### Fresh start (no existing data)
|
||||
|
||||
If you don't need to preserve existing data, simply remove the old volume and
|
||||
start fresh — Patroni will run `initdb` on patroni1 and bootstrap replicas:
|
||||
|
||||
```bash
|
||||
podman volume rm netbox_postgres_data
|
||||
podman compose up -d
|
||||
```
|
||||
Reference in new issue
Block a user