deploy: Docker compose + entrypoint (pull-loop autosync), Nix revert script, .env (gitignored) for Gitea deploy token
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -4,3 +4,8 @@ app/kontra-bin
|
|||||||
# Obsidian cache (content repo may be opened as a vault)
|
# Obsidian cache (content repo may be opened as a vault)
|
||||||
.obsidian/
|
.obsidian/
|
||||||
app/src/*_templ.go
|
app/src/*_templ.go
|
||||||
|
|
||||||
|
# secrets
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
kontra-bin
|
||||||
|
|||||||
29
deploy/deploy-apply.sh
Normal file
29
deploy/deploy-apply.sh
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Apply Kontra Nix additions on .13 and rebuild. Run as: sudo bash deploy-apply.sh --from /var/www/kontra_day/deploy
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
DEPLOY_DIR="${1:-/var/www/kontra_day/deploy}"
|
||||||
|
CFG=/etc/nixos/configuration.nix
|
||||||
|
BAK=$CFG.bak-kontra-$(date +%Y%m%d-%H%M%S)
|
||||||
|
|
||||||
|
echo "== backup configuration.nix -> $BAK"
|
||||||
|
cp -a "$CFG" "$BAK"
|
||||||
|
|
||||||
|
echo "== patch configuration.nix"
|
||||||
|
python3 "$DEPLOY_DIR/patch-nix.py" "$CFG"
|
||||||
|
|
||||||
|
echo "== Nix syntax check"
|
||||||
|
if ! nix-instantiate --parse "$CFG" >/dev/null; then
|
||||||
|
echo "!! Nix syntax FAILED — restoring backup"
|
||||||
|
cp -a "$BAK" "$CFG"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "OK"
|
||||||
|
|
||||||
|
echo "== nixos-rebuild switch (may take minutes)"
|
||||||
|
nixos-rebuild switch --show-trace 2>&1 | tail -40
|
||||||
|
|
||||||
|
echo "== status"
|
||||||
|
systemctl --no-pager --full status kontra.service 2>/dev/null | head -12
|
||||||
|
systemctl --no-pager list-timers kontra-pull.timer 2>/dev/null | head -4
|
||||||
|
echo "ALL DONE"
|
||||||
26
deploy/docker-kontra-up.sh
Normal file
26
deploy/docker-kontra-up.sh
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Kontra → Docker on .13. Runs as sam (docker group). Requires root once for the Nix revert.
|
||||||
|
# Usage: bash docker-kontra-up.sh [--revert-first]
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
cd /home/sam/Docker/Containers/kontra
|
||||||
|
|
||||||
|
if [ "${1:-}" = "--revert-first" ]; then
|
||||||
|
echo "== REVERTING Nix systemd additions (needs sudo) =="
|
||||||
|
sudo bash /var/www/kontra_day/deploy/revert-kontra-nix.sh
|
||||||
|
echo " (ignore home-manager errors — not Kontra's concern; Kontra units are gone)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "== build + start kontra container =="
|
||||||
|
docker compose up -d --build 2>&1 | tail -25
|
||||||
|
|
||||||
|
echo "== wait for boot =="
|
||||||
|
sleep 4
|
||||||
|
echo "== container status =="
|
||||||
|
docker ps --format "{{.Names}} | {{.Status}} | {{.Ports}}" | grep kontra || true
|
||||||
|
|
||||||
|
echo "== direct test =="
|
||||||
|
curl -s -o /dev/null -w "localhost:8600 -> HTTP %{http_code}\n" http://127.0.0.1:8600/ || echo "not up yet (check: docker logs kontra)"
|
||||||
|
echo "== logs tail =="
|
||||||
|
docker logs --tail 15 kontra 2>&1 | tail -15
|
||||||
|
echo "DONE"
|
||||||
27
deploy/docker/Dockerfile
Normal file
27
deploy/docker/Dockerfile
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# Kontra — GOTH news-opinion site. Self-contained container.
|
||||||
|
# Build context = /home/sam/Docker/Containers/kontra (has src/{go.mod,go.sum,src/...})
|
||||||
|
FROM golang:1.26-bookworm AS build
|
||||||
|
# templ CLI for codegen (generates *_templ.go before build)
|
||||||
|
RUN go install github.com/a-h/templ/cmd/templ@v0.3.1020
|
||||||
|
ENV PATH="/root/go/bin:${PATH}"
|
||||||
|
WORKDIR /src
|
||||||
|
COPY src/go.mod src/go.sum ./
|
||||||
|
RUN go mod download
|
||||||
|
COPY src/src/ ./src/
|
||||||
|
WORKDIR /src/src
|
||||||
|
RUN templ generate
|
||||||
|
RUN go build -trimpath -ldflags="-s -w" -o /kontra-bin .
|
||||||
|
|
||||||
|
FROM debian:bookworm-slim
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
ca-certificates git openssh-client bash \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=build /kontra-bin /usr/local/bin/kontra-bin
|
||||||
|
|
||||||
|
# entrypoint (pull loop + webserver) from runtime mount
|
||||||
|
COPY entrypoint.sh /usr/local/bin/kontra-entrypoint
|
||||||
|
RUN chmod +x /usr/local/bin/kontra-entrypoint
|
||||||
|
|
||||||
|
EXPOSE 8600
|
||||||
|
ENTRYPOINT ["/usr/local/bin/kontra-entrypoint", "kontra-bin", "8600"]
|
||||||
18
deploy/docker/docker-compose.yml
Normal file
18
deploy/docker/docker-compose.yml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
services:
|
||||||
|
kontra:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: kontra
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "8600:8600"
|
||||||
|
volumes:
|
||||||
|
- /var/www/kontra_day/content:/var/www/kontra_day/content
|
||||||
|
- /home/sam/.ssh/id_ed25519:/root/.ssh/id_ed25519:ro
|
||||||
|
environment:
|
||||||
|
- PORT=8600
|
||||||
|
- KONTRA_CONTENT=/var/www/kontra_day/content
|
||||||
|
- KONTRA_MEDIA=/media
|
||||||
|
extra_hosts:
|
||||||
|
- "gitea.lab.audasmedia.com.au:192.168.20.35"
|
||||||
55
deploy/docker/entrypoint.sh
Normal file
55
deploy/docker/entrypoint.sh
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Kontra container entrypoint.
|
||||||
|
# - pulls content from Gitea every 30s
|
||||||
|
# - runs the webserver; restarts on content change (binary loads content at boot)
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
BIN="${1:-kontra-bin}"
|
||||||
|
PORT="${2:-8600}"
|
||||||
|
CONTENT="/var/www/kontra_day/content"
|
||||||
|
GIT=/usr/bin/git
|
||||||
|
|
||||||
|
# Gitea SSH key for sam (mounted into the container)
|
||||||
|
export GIT_SSH_COMMAND="ssh -o StrictHostKeyChecking=accept-new -i /root/.ssh/id_ed25519"
|
||||||
|
|
||||||
|
# git refuses repos owned by another uid (host sam=1000); trust the mounted repo.
|
||||||
|
"$GIT" config --global --add safe.directory "$CONTENT" >/dev/null 2>&1 || true
|
||||||
|
"$GIT" config --global user.email "kontra-bot@localhost" >/dev/null 2>&1 || true
|
||||||
|
"$GIT" config --global user.name "kontra-bot" >/dev/null 2>&1 || true
|
||||||
|
|
||||||
|
# Initial clone if the mounted dir is empty (fresh deployment).
|
||||||
|
if [ ! -d "$CONTENT/.git" ]; then
|
||||||
|
echo "cloning kontra-content..."
|
||||||
|
"$GIT" clone git@gitea.lab.audasmedia.com.au:2222/sam/kontra-content.git "$CONTENT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
"$GIT" -C "$CONTENT" rev-parse --is-inside-work-tree >/dev/null 2>&1 || true
|
||||||
|
|
||||||
|
start_server() {
|
||||||
|
# exec: replaces THIS shell, so $! is the real binary PID; kill hits it.
|
||||||
|
KONTRA_CONTENT="$CONTENT" KONTRA_MEDIA="/media" PORT="$PORT" exec "$BIN"
|
||||||
|
}
|
||||||
|
|
||||||
|
# First start.
|
||||||
|
start_server &
|
||||||
|
SERVER_PID=$!
|
||||||
|
|
||||||
|
# Pull every 30s; restart server when HEAD actually changes.
|
||||||
|
PREV=$("$GIT" -C "$CONTENT" rev-parse HEAD 2>/dev/null || echo "")
|
||||||
|
while true; do
|
||||||
|
sleep 30
|
||||||
|
if "$GIT" -C "$CONTENT" pull --ff-only origin main >/tmp/pull.log 2>&1; then
|
||||||
|
CUR=$("$GIT" -C "$CONTENT" rev-parse HEAD)
|
||||||
|
if [ -n "$PREV" ] && [ -n "$CUR" ] && [ "$PREV" != "$CUR" ]; then
|
||||||
|
echo "$(date +%T) content changed ($PREV -> $CUR); restarting server"
|
||||||
|
kill "$SERVER_PID" 2>/dev/null || true
|
||||||
|
wait "$SERVER_PID" 2>/dev/null || true
|
||||||
|
sleep 1
|
||||||
|
start_server &
|
||||||
|
SERVER_PID=$!
|
||||||
|
fi
|
||||||
|
PREV=$CUR
|
||||||
|
else
|
||||||
|
echo "pull failed:"; cat /tmp/pull.log
|
||||||
|
fi
|
||||||
|
done
|
||||||
14
deploy/fix-pull-path.sh
Normal file
14
deploy/fix-pull-path.sh
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Fix kontra-pull ExecStart: /bin/bash -> /run/current-system/sw/bin/bash on .13
|
||||||
|
set -euo pipefail
|
||||||
|
CFG=/etc/nixos/configuration.nix
|
||||||
|
BAK=$CFG.bak-kontra-fix-$(date +%Y%m%d-%H%M%S)
|
||||||
|
cp -a "$CFG" "$BAK"
|
||||||
|
sed -i 's|/bin/bash /var/www/kontra_day/bin/kontra-pull.sh|/run/current-system/sw/bin/bash /var/www/kontra_day/bin/kontra-pull.sh|' "$CFG"
|
||||||
|
echo "patched. verifying:"
|
||||||
|
grep -n "kontra-pull.sh" "$CFG"
|
||||||
|
nix-instantiate --parse "$CFG" >/dev/null && echo "Nix syntax OK"
|
||||||
|
echo "== nixos-rebuild switch =="
|
||||||
|
nixos-rebuild switch --show-trace 2>&1 | tail -25
|
||||||
|
echo "== status =="
|
||||||
|
systemctl --no-pager status kontra-pull.service 2>/dev/null | head -8 || true
|
||||||
53
deploy/fix-pull2.sh
Normal file
53
deploy/fix-pull2.sh
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Fix kontra-pull.sh: use runuser (not su) + point service at sam-writable deploy path.
|
||||||
|
set -euo pipefail
|
||||||
|
CFG=/etc/nixos/configuration.nix
|
||||||
|
BAK=$CFG.bak-kontra-fix2-$(date +%Y%m%d-%H%M%S)
|
||||||
|
cp -a "$CFG" "$BAK"
|
||||||
|
echo "backup: $BAK"
|
||||||
|
|
||||||
|
# Replace the ExecStart path in the Nix config (pull service -> deploy/ copy)
|
||||||
|
python3 - "$CFG" <<'PYEOF'
|
||||||
|
import sys
|
||||||
|
p = sys.argv[1]
|
||||||
|
src = open(p).read()
|
||||||
|
old = 'ExecStart = "/run/current-system/sw/bin/bash /var/www/kontra_day/bin/kontra-pull.sh";'
|
||||||
|
new = 'ExecStart = "/run/current-system/sw/bin/bash /var/www/kontra_day/deploy/kontra-pull.sh";'
|
||||||
|
if old in src:
|
||||||
|
src = src.replace(old, new)
|
||||||
|
else:
|
||||||
|
print("WARN: old ExecStart not found; check manually")
|
||||||
|
open(p,'w').write(src)
|
||||||
|
PYEOF
|
||||||
|
grep -n "kontra-pull.sh" "$CFG"
|
||||||
|
|
||||||
|
# Install fixed script into deploy/ (sam-writable)
|
||||||
|
cat > /var/www/kontra_day/deploy/kontra-pull.sh <<'SH'
|
||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
CONTENT=/var/www/kontra_day/content
|
||||||
|
GIT=/run/current-system/sw/bin/git
|
||||||
|
RUNUSER=/run/current-system/sw/bin/runuser
|
||||||
|
BEFORE=$("$RUNUSER" -u sam -- "$GIT" -C "$CONTENT" rev-parse HEAD)
|
||||||
|
"$RUNUSER" -u sam -- "$GIT" -C "$CONTENT" pull --ff-only origin main >/tmp/kontra-pull.log 2>&1 || { echo "pull failed:"; cat /tmp/kontra-pull.log; exit 1; }
|
||||||
|
AFTER=$("$RUNUSER" -u sam -- "$GIT" -C "$CONTENT" rev-parse HEAD)
|
||||||
|
if [ -n "$BEFORE" ] && [ -n "$AFTER" ] && [ "$BEFORE" != "$AFTER" ]; then
|
||||||
|
echo "content changed: $BEFORE -> $AFTER; restarting kontra"
|
||||||
|
/run/current-system/sw/bin/systemctl restart kontra.service
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
SH
|
||||||
|
chmod 0755 /var/www/kontra_day/deploy/kontra-pull.sh
|
||||||
|
|
||||||
|
# syntax check
|
||||||
|
nix-instantiate --parse "$CFG" >/dev/null && echo "Nix syntax OK" || { echo "SYNTAX FAIL"; cp -a "$BAK" "$CFG"; exit 1; }
|
||||||
|
|
||||||
|
echo "== nixos-rebuild switch =="
|
||||||
|
nixos-rebuild switch --show-trace 2>&1 | tail -20
|
||||||
|
echo "== force a run + status =="
|
||||||
|
systemctl start kontra-pull.service 2>&1 | head -2
|
||||||
|
sleep 3
|
||||||
|
systemctl --no-pager status kontra-pull.service 2>/dev/null | head -8
|
||||||
|
echo "== content head =="
|
||||||
|
cd /var/www/kontra_day/content && git log --oneline -1
|
||||||
|
echo "DONE"
|
||||||
30
deploy/install-kontra.sh
Normal file
30
deploy/install-kontra.sh
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Install Kontra deploy on .13 — run as root (sudo bash install.sh).
|
||||||
|
# Copies: service units, pull script; enables service + timer.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
DIR=/var/www/kontra_day
|
||||||
|
BIN=$DIR/bin
|
||||||
|
|
||||||
|
echo "== placing pull script =="
|
||||||
|
install -m 0755 -o root -g root deploy/kontra-pull.sh $BIN/kontra-pull.sh
|
||||||
|
|
||||||
|
echo "== installing systemd units =="
|
||||||
|
install -m 0644 deploy/kontra.service /etc/systemd/system/kontra.service
|
||||||
|
install -m 0644 deploy/kontra-pull.service /etc/systemd/system/kontra-pull.service
|
||||||
|
install -m 0644 deploy/kontra-pull.timer /etc/systemd/system/kontra-pull.timer
|
||||||
|
|
||||||
|
echo "== daemon-reload =="
|
||||||
|
systemctl daemon-reload
|
||||||
|
|
||||||
|
echo "== enable+start kontra =="
|
||||||
|
systemctl enable --now kontra.service || true
|
||||||
|
systemctl start kontra.service || true
|
||||||
|
|
||||||
|
echo "== enable+start pull timer =="
|
||||||
|
systemctl enable --now kontra-pull.timer || true
|
||||||
|
|
||||||
|
echo "== status =="
|
||||||
|
systemctl --no-pager --full status kontra.service | head -15
|
||||||
|
systemctl --no-pager list-timers kontra-pull.timer | head -5
|
||||||
|
echo "DONE"
|
||||||
8
deploy/kontra-pull.service
Normal file
8
deploy/kontra-pull.service
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Kontra deploy pull (root; pulls as sam, restarts site if changed)
|
||||||
|
Wants=network-online.target
|
||||||
|
After=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/bin/bash /var/www/kontra_day/bin/kontra-pull.sh
|
||||||
19
deploy/kontra-pull.sh
Normal file
19
deploy/kontra-pull.sh
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Kontra content deploy: pull from Gitea; restart site if content changed.
|
||||||
|
# Runs as ROOT (systemd oneshot). Git runs as 'sam' (uses sam's Gitea SSH key)
|
||||||
|
# via runuser (NixOS-native drop-privilege); restart needs root.
|
||||||
|
set -e
|
||||||
|
CONTENT=/var/www/kontra_day/content
|
||||||
|
GIT=/run/current-system/sw/bin/git
|
||||||
|
RUNUSER=/run/current-system/sw/bin/runuser
|
||||||
|
|
||||||
|
BEFORE=$("$RUNUSER" -u sam -- "$GIT" -C "$CONTENT" rev-parse HEAD)
|
||||||
|
"$RUNUSER" -u sam -- "$GIT" -C "$CONTENT" pull --ff-only origin main >/tmp/kontra-pull.log 2>&1 \
|
||||||
|
|| { echo "pull failed:"; cat /tmp/kontra-pull.log; exit 1; }
|
||||||
|
AFTER=$("$RUNUSER" -u sam -- "$GIT" -C "$CONTENT" rev-parse HEAD)
|
||||||
|
|
||||||
|
if [ -n "$BEFORE" ] && [ -n "$AFTER" ] && [ "$BEFORE" != "$AFTER" ]; then
|
||||||
|
echo "content changed: $BEFORE -> $AFTER; restarting kontra"
|
||||||
|
"/run/current-system/sw/bin/systemctl" restart kontra.service
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
10
deploy/kontra-pull.timer
Normal file
10
deploy/kontra-pull.timer
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Kontra content pull timer (every 30s)
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnBootSec=30s
|
||||||
|
OnUnitActiveSec=30s
|
||||||
|
AccuracySec=2s
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
20
deploy/kontra.service
Normal file
20
deploy/kontra.service
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Kontra — GOTH news-opinion site
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=sam
|
||||||
|
Group=users
|
||||||
|
WorkingDirectory=/var/www/kontra_day
|
||||||
|
Environment=KONTRA_CONTENT=/var/www/kontra_day/content
|
||||||
|
Environment=KONTRA_MEDIA=/media
|
||||||
|
Environment=PORT=8600
|
||||||
|
# Binds :8600 (localhost-adjacent; .13 Caddy vhost reverse_proxies to it).
|
||||||
|
ExecStart=/var/www/kontra_day/bin/kontra-bin
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=3
|
||||||
|
NoNewPrivileges=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
94
deploy/patch-kontra-nix.sh
Normal file
94
deploy/patch-kontra-nix.sh
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Apply Kontra additions to /etc/nixos/configuration.nix on .13, then rebuild.
|
||||||
|
# Run as: sudo bash patch-kontra-nix.sh
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
CFG=/etc/nixos/configuration.nix
|
||||||
|
BAK=$CFG.bak-kontra-$(date +%Y%m%d-%H%M%S)
|
||||||
|
cp -a "$CFG" "$BAK"
|
||||||
|
echo "backup: $BAK"
|
||||||
|
|
||||||
|
python3 - "$CFG" <<'PYEOF'
|
||||||
|
import sys, io
|
||||||
|
|
||||||
|
path = sys.argv[1]
|
||||||
|
src = open(path).read()
|
||||||
|
|
||||||
|
# --- 1) Caddy extraConfig: append reverse_proxy block before the closing `'';`
|
||||||
|
caddy_add = '''
|
||||||
|
http://kontra.lab.audasmedia.com.au:8000 {
|
||||||
|
reverse_proxy localhost:8600
|
||||||
|
}
|
||||||
|
http://admin.kontra.lab.audasmedia.com.au:8000 {
|
||||||
|
reverse_proxy localhost:8600
|
||||||
|
}
|
||||||
|
http://kontra.home.lab:8000 {
|
||||||
|
reverse_proxy localhost:8600
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
|
||||||
|
# The extraConfig string ends with '\n '';' (line 77). Insert before that.
|
||||||
|
needle = "\n '';"
|
||||||
|
i = src.rindex(needle, 0, src.index("services.caddy"))
|
||||||
|
src = src[:i] + caddy_add + needle + src[i+len(needle):]
|
||||||
|
|
||||||
|
# --- 2) systemd services + timer: insert after the services.caddy attr close (line 79)
|
||||||
|
services_add = '''
|
||||||
|
# --- KONTRA (GOTH news-opinion site) ---
|
||||||
|
systemd.services.kontra = {
|
||||||
|
description = "Kontra GOTH news-opinion site";
|
||||||
|
after = [ "network-online.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "simple";
|
||||||
|
User = "sam";
|
||||||
|
Group = "users";
|
||||||
|
WorkingDirectory = "/var/www/kontra_day";
|
||||||
|
Environment = [ "KONTRA_CONTENT=/var/www/kontra_day/content" "KONTRA_MEDIA=/media" "PORT=8600" ];
|
||||||
|
ExecStart = "/var/www/kontra_day/bin/kontra-bin";
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = "3";
|
||||||
|
NoNewPrivileges = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.kontra-pull = {
|
||||||
|
description = "Pull Kontra content from Gitea (every 30s timer)";
|
||||||
|
after = [ "network-online.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
ExecStart = "/bin/bash /var/www/kontra_day/bin/kontra-pull.sh";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.timers.kontra-pull = {
|
||||||
|
description = "Kontra content pull timer (30s)";
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
timerConfig = {
|
||||||
|
OnBootSec = "30s";
|
||||||
|
OnUnitActiveSec = "30s";
|
||||||
|
AccuracySec = "2s";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
'''
|
||||||
|
# Insert after the services.caddy closing "};" (line 79). Find "};" following services.caddy.
|
||||||
|
anchor = "services.caddy"
|
||||||
|
idx = src.index(anchor)
|
||||||
|
close = src.find("};", idx)
|
||||||
|
close2 = src.find("};", close + 2) # services attr closes with one more "};"? see structure
|
||||||
|
# The caddy attr is " services.caddy = {\n ... \n '';\n};" -- one close. Insert after it.
|
||||||
|
insert_at = close + 2
|
||||||
|
src = src[:insert_at] + "\n" + services_add + src[insert_at:]
|
||||||
|
|
||||||
|
open(path, "w").write(src)
|
||||||
|
print("patched configuration.nix")
|
||||||
|
PY
|
||||||
|
|
||||||
|
echo "== sanity: syntax check =="
|
||||||
|
nix-instantiate --parse "$CFG" >/dev/null && echo "Nix syntax OK" || { echo "NIX SYNTAX FAILED — restoring backup"; cp -a "$BAK" "$CFG"; exit 1; }
|
||||||
|
|
||||||
|
echo "== nixos-rebuild switch (this may take a while) =="
|
||||||
|
nixos-rebuild switch --show-trace 2>&1 | tail -30
|
||||||
|
echo "DONE"
|
||||||
73
deploy/patch-nix.py
Normal file
73
deploy/patch-nix.py
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Apply Kontra additions to a copy of configuration.nix. Test on /tmp, then run on .13."""
|
||||||
|
import sys
|
||||||
|
|
||||||
|
path = sys.argv[1]
|
||||||
|
src = open(path).read()
|
||||||
|
|
||||||
|
# --- 1) Caddy extraConfig: append reverse_proxy block before closing ''; ---
|
||||||
|
caddy_add = """
|
||||||
|
http://kontra.lab.audasmedia.com.au:8000 {
|
||||||
|
reverse_proxy localhost:8600
|
||||||
|
}
|
||||||
|
http://admin.kontra.lab.audasmedia.com.au:8000 {
|
||||||
|
reverse_proxy localhost:8600
|
||||||
|
}
|
||||||
|
http://kontra.home.lab:8000 {
|
||||||
|
reverse_proxy localhost:8600
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
needle = "\n'';"
|
||||||
|
idx_caddy = src.index("services.caddy")
|
||||||
|
i = src.index(needle, idx_caddy)
|
||||||
|
src = src[:i] + caddy_add + needle + src[i + len(needle):]
|
||||||
|
|
||||||
|
# --- Step 2) systemd service + timer after services.caddy closes ---
|
||||||
|
services_add = """
|
||||||
|
# --- KONTRA (GOTH news-opinion site) ---
|
||||||
|
systemd.services.kontra = {
|
||||||
|
description = "Kontra GOTH news-opinion site";
|
||||||
|
after = [ "network-online.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "simple";
|
||||||
|
User = "sam";
|
||||||
|
Group = "users";
|
||||||
|
WorkingDirectory = "/var/www/kontra_day";
|
||||||
|
Environment = [ "KONTRA_CONTENT=/var/www/kontra_day/content" "KONTRA_MEDIA=/media" "PORT=8600" ];
|
||||||
|
ExecStart = "/var/www/kontra_day/bin/kontra-bin";
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = "3";
|
||||||
|
NoNewPrivileges = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.kontra-pull = {
|
||||||
|
description = "Pull Kontra content from Gitea (30s timer)";
|
||||||
|
after = [ "network-online.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
ExecStart = "/run/current-system/sw/bin/bash /var/www/kontra_day/deploy/kontra-pull.sh";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.timers.kontra-pull = {
|
||||||
|
description = "Kontra content pull timer (30s)";
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
timerConfig = {
|
||||||
|
OnBootSec = "30s";
|
||||||
|
OnUnitActiveSec = "30s";
|
||||||
|
AccuracySec = "2s";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
"""
|
||||||
|
anchor = "services.caddy"
|
||||||
|
idx = src.index(anchor)
|
||||||
|
close = src.find("};", idx) # closes services.caddy attr
|
||||||
|
insert_at = close + 2
|
||||||
|
src = src[:insert_at] + "\n" + services_add + src[insert_at:]
|
||||||
|
|
||||||
|
open(path, "w").write(src)
|
||||||
|
print("patched:", path)
|
||||||
33
deploy/revert-kontra-nix.sh
Normal file
33
deploy/revert-kontra-nix.sh
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Revert ALL Kontra additions from /etc/nixos/configuration.nix on .13.
|
||||||
|
# Restores the untouched pre-Kontra backup, then rebuilds (removes systemd kontra + pull + caddy vhosts).
|
||||||
|
# Run as: sudo bash revert-kontra-nix.sh
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
CFG=/etc/nixos/configuration.nix
|
||||||
|
PRE=/etc/nixos/configuration.nix.bak-kontra-20260908-195305 # first backup = pre-Kontra (no additions)
|
||||||
|
|
||||||
|
if [ ! -f "$PRE" ]; then
|
||||||
|
echo "!! pre-Kontra backup not found at $PRE — aborting (nothing reverted)."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Safety: confirm the CURRENT file actually contains Kontra markers before overwriting
|
||||||
|
if ! grep -q "KONTRA" "$CFG"; then
|
||||||
|
echo "!! Current configuration.nix has no Kontra markers. Leaving as-is."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "== restoring pre-Kontra configuration.nix"
|
||||||
|
cp -a "$PRE" "$CFG"
|
||||||
|
echo " restored. Kontra markers now: $(grep -c CONTRA "$CFG" || true)"
|
||||||
|
|
||||||
|
echo "== Nix syntax check"
|
||||||
|
nix-instantiate --parse "$CFG" >/dev/null && echo "OK" || { echo "SYNTAX FAIL — no change made"; exit 1; }
|
||||||
|
|
||||||
|
echo "== nixos-rebuild switch (removes kontra service + timer + caddy vhosts)"
|
||||||
|
nixos-rebuild switch --show-trace 2>&1 | tail -20
|
||||||
|
|
||||||
|
echo "== confirm removal"
|
||||||
|
systemctl --no-pager list-units --all 2>/dev/null | grep -i kontra || echo " no kontra units (clean)"
|
||||||
|
echo "DONE — Kontra Nix additions reverted."
|
||||||
Reference in New Issue
Block a user