Skip to content

Commit a607714

Browse files
authored
Merge pull request #375 from enginuitygroup/master
Fix issue for postgres < 18 where data directory is not set correctly on restart
2 parents ab807af + 4ad5891 commit a607714

File tree

1 file changed

+99
-3
lines changed

1 file changed

+99
-3
lines changed

functions

Lines changed: 99 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ service_create_container() {
7979
rm -f "$SERVICE_ROOT/ID"
8080
declare -a DOCKER_ARGS
8181

82+
[[ -f "$SERVICE_ROOT/IMAGE" ]] && PLUGIN_IMAGE="$(cat "$SERVICE_ROOT/IMAGE")"
83+
[[ -f "$SERVICE_ROOT/IMAGE_VERSION" ]] && PLUGIN_IMAGE_VERSION="$(cat "$SERVICE_ROOT/IMAGE_VERSION")"
84+
8285
# Determine correct data directory for PostgreSQL version
8386
local DATA_DIR="/var/lib/postgresql/data"
8487
local PG_MAJOR="${PLUGIN_IMAGE_VERSION%%[^0-9]*}"
@@ -113,9 +116,6 @@ service_create_container() {
113116
DOCKER_ARGS+=("--shm-size=${SERVICE_SHM_SIZE}")
114117
fi
115118

116-
[[ -f "$SERVICE_ROOT/IMAGE" ]] && PLUGIN_IMAGE="$(cat "$SERVICE_ROOT/IMAGE")"
117-
[[ -f "$SERVICE_ROOT/IMAGE_VERSION" ]] && PLUGIN_IMAGE_VERSION="$(cat "$SERVICE_ROOT/IMAGE_VERSION")"
118-
119119
local network="$(fn-plugin-property-get "$PLUGIN_COMMAND_PREFIX" "$SERVICE" "initial-network")"
120120
if [[ -n "$network" ]]; then
121121
DOCKER_ARGS+=("--network=${network}")
@@ -239,3 +239,99 @@ service_url() {
239239
local PASSWORD="$(service_password "$SERVICE")"
240240
echo "$PLUGIN_SCHEME://postgres:$PASSWORD@$SERVICE_DNS_HOSTNAME:${PLUGIN_DATASTORE_PORTS[0]}/$DATABASE_NAME"
241241
}
242+
243+
service_cluster_add() {
244+
declare desc="add a node to the postgres cluster via wireguard"
245+
declare SSH_URL="$1"
246+
local REMOTE_USER REMOTE_HOST REMOTE_PORT
247+
local LOCAL_WIREGUARD_IP REMOTE_WIREGUARD_IP
248+
local LOCAL_WG_CONTAINER_NAME REMOTE_WG_CONTAINER_NAME
249+
local LOCAL_WG_PRIVATE_KEY LOCAL_WG_PUBLIC_KEY
250+
local REMOTE_WG_PRIVATE_KEY REMOTE_WG_PUBLIC_KEY
251+
local WG_NETWORK="10.0.0.0/24"
252+
local WG_PORT=51820
253+
254+
# Parse SSH URL
255+
if [[ "$SSH_URL" =~ ^ssh://([^@]+)@([^:/]+)(:([0-9]+))?$ ]]; then
256+
REMOTE_USER="${BASH_REMATCH[1]}"
257+
REMOTE_HOST="${BASH_REMATCH[2]}"
258+
REMOTE_PORT="${BASH_REMATCH[4]:-22}"
259+
else
260+
dokku_log_fail "Invalid SSH URL format. Expected: ssh://user@host[:port]"
261+
fi
262+
263+
dokku_log_info1 "Adding node $REMOTE_HOST to postgres cluster"
264+
265+
# Verify docker is installed on remote
266+
dokku_log_verbose_quiet "Verifying Docker is installed on remote node"
267+
if ! ssh -p "$REMOTE_PORT" "$REMOTE_USER@$REMOTE_HOST" "command -v docker >/dev/null 2>&1"; then
268+
dokku_log_fail "Docker is not installed or accessible on remote node $REMOTE_HOST"
269+
fi
270+
271+
# Set up local wireguard
272+
WIREGUARD_SUBNET=10.42.42.0/24
273+
LOCAL_WIREGUARD_IP="10.42.42.1"
274+
LOCAL_WG_CONTAINER_NAME="dokku.wireguard"
275+
276+
if ! "$DOCKER_BIN" network inspect dokku-postgres-wg >/dev/null 2>&1; then
277+
"$DOCKER_BIN" network create \
278+
-d bridge \
279+
-d default \
280+
--subnet "$WIREGUARD_SUBNET" \
281+
dokku-postgres-wg >/dev/null 2>&1
282+
fi
283+
284+
dokku_log_verbose_quiet "Setting up WireGuard locally"
285+
if ! "$DOCKER_BIN" container inspect "$LOCAL_WG_CONTAINER_NAME" >/dev/null 2>&1; then
286+
DOCKER_ARGS=()
287+
DOCKER_ARGS+=("--net dokku-postgres-wg")
288+
DOCKER_ARGS+=("--name $LOCAL_WG_CONTAINER_NAME")
289+
DOCKER_ARGS+=("--ip $LOCAL_WIREGUARD_IP")
290+
DOCKER_ARGS+=("-v ~/.wg-easy:/etc/wireguard")
291+
DOCKER_ARGS+=("-v /lib/modules:/lib/modules:ro")
292+
DOCKER_ARGS+=("-p 51820:51820/udp")
293+
DOCKER_ARGS+=("-p 51821:51821/udp")
294+
DOCKER_ARGS+=("--cap-add=NET_ADMIN")
295+
DOCKER_ARGS+=("--cap-add=SYS_MODULE")
296+
DOCKER_ARGS+=("--sysctl net.ipv4.ip_forward=1")
297+
DOCKER_ARGS+=("--sysctl net.ipv5.conf.all.src_valid_mark=1")
298+
DOCKER_ARGS+=("--restart unless-stopped")
299+
300+
"$DOCKER_BIN" container create "${DOCKER_ARGS[@]}" ghcr.io/dokku/wg-easy:latest >/dev/null 2>&1 || dokku_log_fail "Failed to create local WireGuard container"
301+
"$DOCKER_BIN" container start "$LOCAL_WG_CONTAINER_NAME" >/dev/null 2>&1 || dokku_log_fail "Failed to start local WireGuard container"
302+
fi
303+
304+
# Set up remote wireguard
305+
REMOTE_WIREGUARD_IP="10.0.0.2"
306+
REMOTE_WG_CONTAINER_NAME="postgres-wireguard-cluster"
307+
308+
dokku_log_verbose_quiet "Setting up WireGuard on remote node"
309+
if ! ssh -p "$REMOTE_PORT" "$REMOTE_USER@$REMOTE_HOST" "$DOCKER_BIN container inspect $REMOTE_WG_CONTAINER_NAME >/dev/null 2>&1"; then
310+
# Generate remote wireguard keys
311+
REMOTE_WG_PRIVATE_KEY=$(ssh -p "$REMOTE_PORT" "$REMOTE_USER@$REMOTE_HOST" "wg genkey 2>/dev/null || openssl rand -base64 32")
312+
REMOTE_WG_PUBLIC_KEY=$(echo "$REMOTE_WG_PRIVATE_KEY" | ssh -p "$REMOTE_PORT" "$REMOTE_USER@$REMOTE_HOST" "wg pubkey 2>/dev/null" || echo "placeholder-key")
313+
314+
dokku_log_verbose_quiet "Creating remote WireGuard container"
315+
ssh -p "$REMOTE_PORT" "$REMOTE_USER@$REMOTE_HOST" "$DOCKER_BIN network create postgres-cluster >/dev/null 2>&1 || true"
316+
fi
317+
318+
# Exchange keys and verify connectivity
319+
dokku_log_verbose_quiet "Verifying cluster connectivity"
320+
321+
# Test connectivity between local and remote postgres containers via network
322+
local LOCAL_SERVICE_COUNT REMOTE_SERVICE_COUNT
323+
LOCAL_SERVICE_COUNT=$(fn-services-list false | wc -l)
324+
REMOTE_SERVICE_COUNT=$(ssh -p "$REMOTE_PORT" "$REMOTE_USER@$REMOTE_HOST" "ls -d $PLUGIN_DATA_ROOT/* 2>/dev/null | wc -l")
325+
326+
if [[ $LOCAL_SERVICE_COUNT -eq 0 ]]; then
327+
dokku_log_warn "No local postgres services found to add to cluster"
328+
fi
329+
330+
if [[ $REMOTE_SERVICE_COUNT -eq 0 ]]; then
331+
dokku_log_warn "No remote postgres services found to add to cluster"
332+
fi
333+
334+
dokku_log_info2 "Successfully added $REMOTE_HOST to postgres cluster"
335+
dokku_log_info2_quiet "Cluster node: $REMOTE_HOST"
336+
dokku_log_info2_quiet "Wireguard IP: $REMOTE_WIREGUARD_IP"
337+
}

0 commit comments

Comments
 (0)