From 6bb56e603545213d03eed955d303d88933d8e2a1 Mon Sep 17 00:00:00 2001 From: Linus Olofsson Date: Fri, 6 Nov 2026 04:43:33 +0100 Subject: [PATCH] Portfolio sync runs on the Cleura server (systemd timer every 20 min) instead of n8n -> Nurem deploy/cleura/portfolio-sync.sh: same steps as /opt/immich-sync/run-sync.sh on Nurem (fetch main, portfolio-sync.mjs, commit + push when photos changed) and then build-live.sh main on Cleura; flock against overlapping runs, the sync runs in the pinned Node container. install-portfolio-sync.sh puts it in place; secrets stay in /etc/portal/portfolio-sync.env (root 600). The snippet comment no longer mentions the removed /download/original. Co-Authored-By: Claude Opus 5.5 --- deploy/caddy-site.snippet | 4 +- deploy/cleura/install-portfolio-sync.sh | 15 ++++++++ deploy/cleura/portfolio-sync.service | 11 ++++++ deploy/cleura/portfolio-sync.sh | 51 +++++++++++++++++++++++++ deploy/cleura/portfolio-sync.timer | 10 +++++ 5 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 deploy/cleura/install-portfolio-sync.sh create mode 100644 deploy/cleura/portfolio-sync.service create mode 100644 deploy/cleura/portfolio-sync.sh create mode 100644 deploy/cleura/portfolio-sync.timer diff --git a/deploy/caddy-site.snippet b/deploy/caddy-site.snippet index 550c8c4..a4752df 100644 --- a/deploy/caddy-site.snippet +++ b/deploy/caddy-site.snippet @@ -10,8 +10,8 @@ # import ibo_www_redirect # } # imagesbyolofsson.se { -# # Befintliga specialregler (t.ex. handle /download/original* -> Immich-proxyn) -# # ska ligga FÖRE importen, så att de vinner över try_files/file_server. +# # Specialregler (på Cleura: handle för /about, /contact, /posters -> kundportalen, +# # se kundportalens deploy/cleura/caddy/Caddyfile) ska ligga FÖRE importen. # import ibo_site /srv/imagesbyolofsson/dist # } # diff --git a/deploy/cleura/install-portfolio-sync.sh b/deploy/cleura/install-portfolio-sync.sh new file mode 100644 index 0000000..b83344f --- /dev/null +++ b/deploy/cleura/install-portfolio-sync.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +# deploy/cleura/install-portfolio-sync.sh – installs the portfolio sync on the Cleura server (run as root from a +# checkout of this repo). Needs /etc/portal/portfolio-sync.env (root 600) first; see portfolio-sync.sh for the keys. +# Undo: systemctl disable --now portfolio-sync.timer && rm /etc/systemd/system/portfolio-sync.{service,timer} +set -euo pipefail +HERE=$(cd "$(dirname "$0")" && pwd) +ENVF=/etc/portal/portfolio-sync.env +[ -f "$ENVF" ] || { echo "$ENVF is missing - copy IMMICH_URL, PORTFOLIO_TAG_ID, IMMICH_API_KEY and GIT_URL there first"; exit 2; } +[ "$(stat -c %a "$ENVF")" = "600" ] || chmod 600 "$ENVF" +install -m 755 -o root -g root "$HERE/portfolio-sync.sh" /opt/portal/site/portfolio-sync.sh +install -m 644 -o root -g root "$HERE/portfolio-sync.service" /etc/systemd/system/portfolio-sync.service +install -m 644 -o root -g root "$HERE/portfolio-sync.timer" /etc/systemd/system/portfolio-sync.timer +systemctl daemon-reload +systemctl enable --now portfolio-sync.timer +systemctl list-timers portfolio-sync.timer --no-pager diff --git a/deploy/cleura/portfolio-sync.service b/deploy/cleura/portfolio-sync.service new file mode 100644 index 0000000..1580b20 --- /dev/null +++ b/deploy/cleura/portfolio-sync.service @@ -0,0 +1,11 @@ +[Unit] +Description=Immich portfolio tag -> imagesbyolofsson-se repo -> live site (deploy/cleura/portfolio-sync.sh) +After=network-online.target docker.service +Wants=network-online.target +Requires=docker.service + +[Service] +Type=oneshot +ExecStart=/opt/portal/site/portfolio-sync.sh +TimeoutStartSec=45min +Nice=10 diff --git a/deploy/cleura/portfolio-sync.sh b/deploy/cleura/portfolio-sync.sh new file mode 100644 index 0000000..97f2c2f --- /dev/null +++ b/deploy/cleura/portfolio-sync.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash +# deploy/cleura/portfolio-sync.sh – Immich "portfolio" tag -> this repo -> imagesbyolofsson.se, on the Cleura server. +# +# Replaces /opt/immich-sync/run-sync.sh on Nurem (started by n8n over SSH) when imagesbyolofsson.se moved to Cleura +# (Linus 2026-11-06: everything on the Cleura server). Same steps: fetch main, run scripts/portfolio-sync.mjs, +# commit + push to Gitea main when photos were added or removed, and then rebuild the live site with +# /opt/portal/site/build-live.sh (EXIF check included). Nothing is built when nothing changed. +# +# Installed by deploy/cleura/install-portfolio-sync.sh as /opt/portal/site/portfolio-sync.sh, run by +# portfolio-sync.timer every 20 minutes. Secrets: /etc/portal/portfolio-sync.env (root 600) with +# IMMICH_URL, PORTFOLIO_TAG_ID, IMMICH_API_KEY (read-only Immich key) and GIT_URL (Gitea URL that may push main). +set -euo pipefail +ENVF=${PORTFOLIO_SYNC_ENV:-/etc/portal/portfolio-sync.env} +DIR=${PORTFOLIO_SYNC_DIR:-/opt/portal/site/sync/repo} +NODE=node:22.22.0-alpine@sha256:e4bf2a82ad0a4037d28035ae71529873c069b13eb0455466ae0bc13363826e34 + +exec 9>/run/lock/portfolio-sync.lock +flock -n 9 || { echo "[sync] already running"; exit 0; } + +set -a; . "$ENVF"; set +a +export IMMICH_URL="${IMMICH_URL:-https://foto.imagesbyolofsson.se/api}" +export PORTFOLIO_TAG_ID="${PORTFOLIO_TAG_ID:-67d16b6c-0dea-42ef-a289-2c9e57fa5c5a}" +[ -n "${IMMICH_API_KEY:-}" ] || { echo "FATAL: IMMICH_API_KEY missing in $ENVF"; exit 2; } +[ -n "${GIT_URL:-}" ] || { echo "FATAL: GIT_URL missing in $ENVF"; exit 2; } + +if [ ! -d "$DIR/.git" ]; then + mkdir -p "$(dirname "$DIR")" + git clone -q "$GIT_URL" "$DIR" +fi +git -C "$DIR" remote set-url origin "$GIT_URL" +echo "[sync] fetch + reset main" +git -C "$DIR" fetch -q origin main +git -C "$DIR" checkout -q -B main origin/main +git -C "$DIR" reset -q --hard origin/main + +echo "[sync] scripts/portfolio-sync.mjs" +docker run --rm --memory 2g --cpus 2 --network bridge \ + -e IMMICH_URL -e IMMICH_API_KEY -e PORTFOLIO_TAG_ID \ + -v "$DIR":/app -w /app "$NODE" \ + sh -c 'npm install --no-audit --no-fund --loglevel=error >/dev/null && node scripts/portfolio-sync.mjs' + +if git -C "$DIR" status --porcelain -- src/assets/images/portfolio | grep -q .; then + git -C "$DIR" add -A src/assets/images/portfolio + git -C "$DIR" -c user.name="portfolio-sync (Cleura)" -c user.email="Admin@imagesbyolofsson.se" \ + commit -q -m "chore(portfolio): sync $(date -u +%Y-%m-%d)" + git -C "$DIR" push -q origin main + echo "[sync] pushed $(git -C "$DIR" rev-parse --short HEAD), rebuilding the live site" + /opt/portal/site/build-live.sh main +else + echo "[sync] no changes" +fi diff --git a/deploy/cleura/portfolio-sync.timer b/deploy/cleura/portfolio-sync.timer new file mode 100644 index 0000000..dadf8f4 --- /dev/null +++ b/deploy/cleura/portfolio-sync.timer @@ -0,0 +1,10 @@ +[Unit] +Description=Portfolio sync every 20 minutes (Immich has no event when a photo is tagged, so it polls) + +[Timer] +OnCalendar=*:0/20 +RandomizedDelaySec=60 +Persistent=true + +[Install] +WantedBy=timers.target