my-homelab-configs/infra/matrix-server/bootstrap.sh

74 lines
3.1 KiB
Bash

#!/usr/bin/env bash
# Deploy/update the self-hosted Matrix stack (Synapse + Postgres + Element).
# Idempotent: renders homeserver.yaml from the committed template, ensures
# correct data-dir ownership, and starts containers.
#
# Secrets are read from an install-dir .env (written by jeannie deploy_matrix),
# NOT from the repo. The signing key is created by Synapse on first boot.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ENV_FILE="${MATRIX_ENV_FILE:-${SCRIPT_DIR}/.env}"
if [[ ! -f "${ENV_FILE}" ]]; then
echo "Missing secret env file ${ENV_FILE}. Run jeannie deploy-matrix first." >&2
exit 1
fi
set -a
# shellcheck disable=SC1090
. "${ENV_FILE}"
set +a
MATRIX_SERVER_NAME="${MATRIX_SERVER_NAME:-matrix.lab2025.duckdns.org}"
MATRIX_POSTGRES_DB="${MATRIX_POSTGRES_DB:-synapse}"
MATRIX_POSTGRES_USER="${MATRIX_POSTGRES_USER:-synapse}"
SYNAPSE_UID="${MATRIX_SYNAPSE_UID:-991}"
POSTGRES_UID="${MATRIX_POSTGRES_UID:-70}"
render_homeserver() {
local tpl="${SCRIPT_DIR}/homeserver.yaml.tpl"
local out="${SCRIPT_DIR}/synapse-data/homeserver.yaml"
for var in MATRIX_SERVER_NAME MATRIX_POSTGRES_DB MATRIX_POSTGRES_USER \
MATRIX_POSTGRES_PASSWORD MATRIX_REGISTRATION_SHARED_SECRET \
MATRIX_MACAROON_SECRET_KEY MATRIX_FORM_SECRET; do
if [[ -z "${!var:-}" ]]; then
echo "Missing required secret/env ${var}" >&2
exit 1
fi
done
# shellcheck disable=SC2016
envsubst \
'${MATRIX_SERVER_NAME} ${MATRIX_POSTGRES_DB} ${MATRIX_POSTGRES_USER} ${MATRIX_POSTGRES_PASSWORD} ${MATRIX_REGISTRATION_SHARED_SECRET} ${MATRIX_MACAROON_SECRET_KEY} ${MATRIX_FORM_SECRET}' \
<"${tpl}" >"${out}"
cp "${SCRIPT_DIR}/log_config.yaml" "${SCRIPT_DIR}/synapse-data/${MATRIX_SERVER_NAME}.log.config"
}
sudo mkdir -p "${SCRIPT_DIR}/synapse-data" "${SCRIPT_DIR}/postgres-data"
# First boot: generate signing key + log config (the files a hand-written
# homeserver.yaml would not provide). Without this Synapse fails to boot on a
# missing signing key. Only touches the data dir (not postgres).
if [[ ! -f "${SCRIPT_DIR}/synapse-data/${MATRIX_SERVER_NAME}.signing.key" ]]; then
echo "First boot: generating Synapse signing key + log config..."
docker compose --env-file "${ENV_FILE}" -f "${SCRIPT_DIR}/docker-compose.yml" \
run --rm --no-deps synapse generate --config-path /data/homeserver.yaml
fi
render_homeserver
# Ownership foot-gun: wrong uid prevents boot (synapse 991, postgres 70).
sudo chown -R "${SYNAPSE_UID}:${SYNAPSE_UID}" "${SCRIPT_DIR}/synapse-data"
sudo chown -R "${POSTGRES_UID}:${POSTGRES_UID}" "${SCRIPT_DIR}/postgres-data"
docker compose --env-file "${ENV_FILE}" -f "${SCRIPT_DIR}/docker-compose.yml" up -d
echo "Matrix stack up:"
echo " Synapse http://127.0.0.1:${MATRIX_SYNAPSE_PORT:-8008}"
echo " Element http://127.0.0.1:${MATRIX_ELEMENT_PORT:-8081}"
echo " server_name ${MATRIX_SERVER_NAME}"
cat <<'EOF'
Next: register users (hermes bot, and any humans) via the shared-secret CLI:
docker exec -u 991 matrix-synapse register_new_matrix_user -c /data/homeserver.yaml -u NAME -p PASS [--no-admin]
EOF