From 86e9fb57abed8a9efcf7a3df4aee6c37bd8870bc Mon Sep 17 00:00:00 2001 From: Replit Agent Date: Thu, 18 Jun 2026 15:57:14 +0000 Subject: [PATCH] Set up automated deployment and configuration for SkillGuard Configure deployment workflows, SSH settings, and environment variables for the SkillGuard project. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 0d01f99a-ea6a-447d-82fd-311715434a39 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Event-Id: f938974b-4b4e-47df-8a70-53fbb1c1de6e Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/e32d2b99-1721-47dd-833c-98b372f48008/0d01f99a-ea6a-447d-82fd-311715434a39/b33cDqP Replit-Helium-Checkpoint-Created: true --- .forgejo/workflows/deploy.yml | 24 +++ .ssh/config | 14 ++ .ssh/id_ed25519_forgejo | 8 + hetzner-deployment/.gitkeep | 0 hetzner-deployment/deploy-database-dump.sh | 104 +++++++++++ hetzner-deployment/deploy-full-release.sh | 130 ++++++++++++++ hetzner-deployment/deploy-github-push.sh | 46 +++++ hetzner-deployment/init.sh | 106 ++++++++++++ hetzner-deployment/ssh_context.sh | 163 ++++++++++++++++++ hetzner-deployment/targets/example.env | 14 ++ .../targets/kwali8-landingpage.env | 7 + hetzner-deployment/targets/skillguard.env | 7 + 12 files changed, 623 insertions(+) create mode 100644 .forgejo/workflows/deploy.yml create mode 100644 .ssh/config create mode 100644 .ssh/id_ed25519_forgejo create mode 100644 hetzner-deployment/.gitkeep create mode 100755 hetzner-deployment/deploy-database-dump.sh create mode 100755 hetzner-deployment/deploy-full-release.sh create mode 100755 hetzner-deployment/deploy-github-push.sh create mode 100755 hetzner-deployment/init.sh create mode 100755 hetzner-deployment/ssh_context.sh create mode 100644 hetzner-deployment/targets/example.env create mode 100644 hetzner-deployment/targets/kwali8-landingpage.env create mode 100644 hetzner-deployment/targets/skillguard.env diff --git a/.forgejo/workflows/deploy.yml b/.forgejo/workflows/deploy.yml new file mode 100644 index 0000000..0da2f63 --- /dev/null +++ b/.forgejo/workflows/deploy.yml @@ -0,0 +1,24 @@ +name: Deploy to Production + +on: + push: + branches: + - main + +jobs: + deploy: + runs-on: self-hosted + steps: + - name: Code aktualisieren + run: | + git -C /opt/skillguard fetch /opt/forgejo/data/git/repositories/avameo/skillguard.git main + git -C /opt/skillguard reset --hard FETCH_HEAD + + - name: Dependencies installieren + run: npm ci --prefix /opt/skillguard + + - name: Build ausführen + run: npm run build --prefix /opt/skillguard + + - name: Service neu starten + run: sudo systemctl restart skillguard.service diff --git a/.ssh/config b/.ssh/config new file mode 100644 index 0000000..73288a7 --- /dev/null +++ b/.ssh/config @@ -0,0 +1,14 @@ +# >>> ANPASSEN: frei wählbarer Alias, mit dem du dich verbindest (z. B. ssh forgejo) +Host + # >>> ANPASSEN: echte Server-Adresse oder IP + HostName + Port 2222 + User git + IdentityFile /home/runner/workspace/.ssh/id_ed25519_forgejo + StrictHostKeyChecking no +Host forgejo-skillguard.a42i.de + HostName forgejo-skillguard.a42i.de + Port 2222 + User git + IdentityFile /home/runner/workspace/.ssh/id_ed25519_forgejo + StrictHostKeyChecking no diff --git a/.ssh/id_ed25519_forgejo b/.ssh/id_ed25519_forgejo new file mode 100644 index 0000000..e818ced --- /dev/null +++ b/.ssh/id_ed25519_forgejo @@ -0,0 +1,8 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABBJBy+0Tw +MdthFIWzIa1SA8AAAAGAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIPLnSbMdI67Xkv2A +AXxQsYExQAvd1/jdNd3u4LNJuVjvAAAAoGwXDrTwGpuHYYp2xFfb2YJ32C6fDGThaX6T/M +U3HHNHi7nFip1UnOGrFJbVllGCKAxfNliyMiC712Pubu/utd3JXx5xe1xx9arv8t6B8hDm +zWZoGnesrkgyf5IoaEBO4U8I9IwqI725LGQp1DpJozauzjf1NUvVc25VoCbQxrVoiih5OD +fmdlsJKpWIVE2vvfXwBw2Eu3hdiXacPgbT/Qc= +-----END OPENSSH PRIVATE KEY----- diff --git a/hetzner-deployment/.gitkeep b/hetzner-deployment/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/hetzner-deployment/deploy-database-dump.sh b/hetzner-deployment/deploy-database-dump.sh new file mode 100755 index 0000000..20764a4 --- /dev/null +++ b/hetzner-deployment/deploy-database-dump.sh @@ -0,0 +1,104 @@ +#!/usr/bin/env bash +set -euo pipefail + +# ============================================================================= +# deploy-database-dump.sh +# Erstellt einen PostgreSQL-Dump und uebertraegt ihn per SFTP auf die +# Zielinstanz innerhalb der Hetzner-Infrastruktur. +# +# Verwendung: ./deploy-database-dump.sh +# Beispiel: ./deploy-database-dump.sh pilot1 +# ============================================================================= + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# --- Kontext laden --- +source "${SCRIPT_DIR}/ssh_context.sh" "$@" + +# --- SSH (Key wird geladen, Passphrase einmalig abgefragt) --- +setup_ssh + +# --- Datenbank-URL pruefen --- +if [ -z "${DATABASE_URL:-}" ]; then + echo "FEHLER: DATABASE_URL ist nicht gesetzt." + exit 1 +fi + +# --- Dump erstellen --- +BACKUP_DIR="/home/runner/workspace/backups" +TIMESTAMP=$(node -e "const d=new Date();console.log(d.toISOString().replace(/[-:]/g,'').replace('T','_').slice(0,15))") +DUMP_FILE="${BACKUP_DIR}/datadump_${TARGET}_${TIMESTAMP}.dump" +SFTP_TARGET="/uploads/datadump.dump" + +mkdir -p "${BACKUP_DIR}" + +echo "" +echo "=== Datenbank-Export ===" +echo "Target: ${TARGET} (${DOMAIN})" +echo "DB: ${DB_NAME}" +echo "Ziel: ${DUMP_FILE}" +echo "" + +echo "Starte Datenbank-Export..." + +pg_dump -Fc -d "$DATABASE_URL" -f "$DUMP_FILE" & +DUMP_PID=$! + +while kill -0 "$DUMP_PID" 2>/dev/null; do + if [ -f "$DUMP_FILE" ]; then + SIZE=$(du -h "$DUMP_FILE" 2>/dev/null | cut -f1) + printf "\r Exportiert: %s ..." "$SIZE" + fi + sleep 3 +done + +wait "$DUMP_PID" +DUMP_EXIT=$? + +echo "" + +if [ $DUMP_EXIT -ne 0 ] || [ ! -f "$DUMP_FILE" ]; then + echo "FEHLER: Datenbank-Export fehlgeschlagen." + exit 1 +fi + +SIZE=$(du -h "$DUMP_FILE" | cut -f1) +echo "Export fertig: ${DUMP_FILE} (${SIZE})" + +sync + +# --- SFTP-Transfer --- +echo "" +echo "=== SFTP-Upload ===" +echo "Ziel: ${SFTP_HOST}:${SFTP_TARGET}" +echo "" + +sftp -P "${SFTP_PORT}" -i "${KEY_PATH}" "replit-user@${SFTP_HOST}" <&1) + +if echo "$REMOTE_CHECK" | grep -q "datadump.dump"; then + echo "Upload erfolgreich: Datei auf dem Server vorhanden." +else + echo "FEHLER: Datei wurde nicht auf dem Server gefunden." + exit 1 +fi + +echo "" +echo "=== Datenbank-Deployment fuer '${TARGET}' abgeschlossen ===" diff --git a/hetzner-deployment/deploy-full-release.sh b/hetzner-deployment/deploy-full-release.sh new file mode 100755 index 0000000..7c4c0c2 --- /dev/null +++ b/hetzner-deployment/deploy-full-release.sh @@ -0,0 +1,130 @@ +#!/usr/bin/env bash +set -euo pipefail + +# ============================================================================= +# deploy-full-release.sh +# Fuehrt ein vollstaendiges Release durch: Datenbank-Dump + Code-Push. +# Die Passwort-Abfrage erfolgt einmalig zu Beginn. +# +# Verwendung: ./deploy-full-release.sh +# Beispiel: ./deploy-full-release.sh pilot1 +# ============================================================================= + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# --- Kontext laden --- +source "${SCRIPT_DIR}/ssh_context.sh" "$@" + +# --- SSH (Key wird geladen, Passphrase einmalig abgefragt) --- +setup_ssh + +echo "" +echo "=========================================" +echo " Full Release: ${TARGET} (${DOMAIN})" +echo "=========================================" +echo "" + +# --- Phase 1: Datenbank --- +echo "--- Phase 1/2: Datenbank-Deployment ---" +echo "" + +if [ -z "${DATABASE_URL:-}" ]; then + echo "FEHLER: DATABASE_URL ist nicht gesetzt." + exit 1 +fi + +BACKUP_DIR="/home/runner/workspace/backups" +TIMESTAMP=$(node -e "const d=new Date();console.log(d.toISOString().replace(/[-:]/g,'').replace('T','_').slice(0,15))") +DUMP_FILE="${BACKUP_DIR}/datadump_${TARGET}_${TIMESTAMP}.dump" +SFTP_TARGET="/uploads/datadump.dump" + +mkdir -p "${BACKUP_DIR}" + +echo "Starte Datenbank-Export..." +echo "Ziel: ${DUMP_FILE}" + +pg_dump -Fc -d "$DATABASE_URL" -f "$DUMP_FILE" & +DUMP_PID=$! + +while kill -0 "$DUMP_PID" 2>/dev/null; do + if [ -f "$DUMP_FILE" ]; then + SIZE=$(du -h "$DUMP_FILE" 2>/dev/null | cut -f1) + printf "\r Exportiert: %s ..." "$SIZE" + fi + sleep 3 +done + +wait "$DUMP_PID" +DUMP_EXIT=$? + +echo "" + +if [ $DUMP_EXIT -ne 0 ] || [ ! -f "$DUMP_FILE" ]; then + echo "FEHLER: Datenbank-Export fehlgeschlagen." + exit 1 +fi + +SIZE=$(du -h "$DUMP_FILE" | cut -f1) +echo "Export fertig: ${DUMP_FILE} (${SIZE})" + +sync + +echo "Uebertrage nach ${SFTP_HOST}:${SFTP_TARGET}..." + +sftp -P "${SFTP_PORT}" -i "${KEY_PATH}" "replit-user@${SFTP_HOST}" <&1) + +if echo "$REMOTE_CHECK" | grep -q "datadump.dump"; then + echo "Upload erfolgreich." +else + echo "FEHLER: Datei wurde nicht auf dem Server gefunden." + exit 1 +fi + +echo "" +echo "--- Phase 1/2: Datenbank-Deployment abgeschlossen ---" +echo "" + +# --- Phase 2: Code --- +echo "--- Phase 2/2: Code-Deployment ---" +echo "" + +echo "Pruefe Git-Remote '${GIT_REMOTE}'..." +if ! git remote get-url "${GIT_REMOTE}" &>/dev/null; then + echo "FEHLER: Git-Remote '${GIT_REMOTE}' existiert nicht." + git remote -v + exit 1 +fi + +echo "Starte Push: main -> ${GIT_REMOTE}..." +git push "${GIT_REMOTE}" main --force + +PUSH_EXIT=$? + +if [ $PUSH_EXIT -ne 0 ]; then + echo "FEHLER: Git-Push fehlgeschlagen (Exit-Code: ${PUSH_EXIT})." + exit 1 +fi + +echo "" +echo "--- Phase 2/2: Code-Deployment abgeschlossen ---" +echo "" +echo "=========================================" +echo " Full Release fuer '${TARGET}' fertig" +echo "=========================================" diff --git a/hetzner-deployment/deploy-github-push.sh b/hetzner-deployment/deploy-github-push.sh new file mode 100755 index 0000000..62e2e28 --- /dev/null +++ b/hetzner-deployment/deploy-github-push.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +set -euo pipefail + +# ============================================================================= +# deploy-github-push.sh +# Pusht den aktuellen main-Branch an das Forgejo-Remote der Zielinstanz. +# +# Verwendung: ./deploy-github-push.sh +# Beispiel: ./deploy-github-push.sh audit +# ============================================================================= + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# --- Kontext laden --- +source "${SCRIPT_DIR}/ssh_context.sh" "$@" + +# --- SSH (Key wird geladen, Passphrase einmalig abgefragt) --- +setup_ssh + +# --- Git-Push --- +echo "" +echo "=== Code-Deployment ===" +echo "Target: ${TARGET} (${DOMAIN})" +echo "Remote: ${GIT_REMOTE}" +echo "" + +echo "Pruefe Git-Remote '${GIT_REMOTE}'..." +if ! git remote get-url "${GIT_REMOTE}" &>/dev/null; then + echo "FEHLER: Git-Remote '${GIT_REMOTE}' existiert nicht." + echo "Verfuegbare Remotes:" + git remote -v + exit 1 +fi + +echo "Starte Push: main -> ${GIT_REMOTE}..." +git push "${GIT_REMOTE}" main --force + +PUSH_EXIT=$? + +if [ $PUSH_EXIT -ne 0 ]; then + echo "FEHLER: Git-Push fehlgeschlagen (Exit-Code: ${PUSH_EXIT})." + exit 1 +fi + +echo "" +echo "=== Code-Deployment fuer '${TARGET}' abgeschlossen ===" diff --git a/hetzner-deployment/init.sh b/hetzner-deployment/init.sh new file mode 100755 index 0000000..ec3a2ef --- /dev/null +++ b/hetzner-deployment/init.sh @@ -0,0 +1,106 @@ +#!/usr/bin/env bash +set -euo pipefail + +# ============================================================================= +# init.sh +# Interaktive Einrichtung eines Deployment-Targets. +# Fragt alle relevanten Werte ab (jeweils mit Beispiel) und speichert sie unter +# targets/.env. Danach koennen die Deploy-Scripts mit dem Target-Namen +# aufgerufen werden (z. B. ./deploy-full-release.sh ). +# ============================================================================= + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +TARGETS_DIR="${SCRIPT_DIR}/targets" + +echo "===================================================" +echo " Hetzner-Deployment: Target einrichten (init.sh)" +echo "===================================================" +echo "" +echo "Die Eingaben werden gespeichert unter:" +echo " ${TARGETS_DIR}/.env" +echo "" + +if [ ! -t 0 ]; then + echo "FEHLER: Kein interaktives Terminal. init.sh muss manuell ausgefuehrt werden." + exit 1 +fi + +# --- Hilfsfunktionen --- + +# Leerzeichen am Anfang/Ende entfernen. +trim() { + printf '%s' "$1" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' +} + +# Wert fuer sicheres Schreiben in single-quotes escapen: jedes ' wird zu '\''. +# So kann der spaeter via 'source' geladene Wert keine Shell-Befehle ausloesen. +esc() { + printf "%s" "$1" | sed "s/'/'\\\\''/g" +} + +# Pflichtfeld abfragen (mit Beispiel im Prompt); leere Eingaben werden abgelehnt. +# $1 = Beschreibung, $2 = Beispiel, $3 = Name der Zielvariablen. +ask() { + local prompt="$1" example="$2" __out="$3" value="" + while true; do + read -r -p "${prompt} (z. B. ${example}): " value + value="$(trim "$value")" + if [ -n "$value" ]; then + printf -v "$__out" '%s' "$value" + break + fi + echo " -> Eingabe darf nicht leer sein." + done +} + +mkdir -p "${TARGETS_DIR}" + +# --- Target-Name --- +ask "Target-Name" "kwali8-landingpage" TARGET_NAME +if ! printf '%s' "$TARGET_NAME" | grep -Eq '^[A-Za-z0-9._-]+$'; then + echo "FEHLER: Target-Name darf nur Buchstaben, Zahlen sowie '.', '_' und '-' enthalten." + exit 1 +fi + +TARGET_FILE="${TARGETS_DIR}/${TARGET_NAME}.env" +if [ -f "${TARGET_FILE}" ]; then + echo "" + echo "Hinweis: Target '${TARGET_NAME}' existiert bereits (${TARGET_FILE})." + read -r -p "Ueberschreiben? [j/N]: " answer + case "$(printf '%s' "$answer" | tr '[:upper:]' '[:lower:]')" in + j|ja|y|yes) ;; + *) echo "Abgebrochen. Es wurde nichts geaendert."; exit 0 ;; + esac +fi + +echo "" + +# --- Restliche Werte --- +ask "SSH-Host (Forgejo-Server)" "forgejo-landing.kwali8.de" SSH_HOST +ask "SFTP-Host (Zielserver)" "forgejo-landing.kwali8.de" SFTP_HOST +ask "Datenbank-Name" "helium" DB_NAME +ask "Git-Remote-Name" "kwali8-landingpage" GIT_REMOTE +ask "Domain (Zielserver)" "kwali8.de" DOMAIN + +# --- Speichern --- +# Werte single-quoted und escaped schreiben, damit das spaetere 'source' +# in ssh_context.sh keine Command-Substitution o. ae. ausfuehren kann. +umask 077 +cat > "${TARGET_FILE}" <.env geladen. Neue Targets legt man interaktiv mit ./init.sh an. +# +# Der SSH-Key (id_ed25519_forgejo) ist mit einer Passphrase verschluesselt. +# setup_ssh() laedt ihn in einen temporaeren ssh-agent; dabei wird die +# Passphrase einmalig abgefragt (Quelle: VaultWarden). Eine falsche Passphrase +# kann den Key nicht entschluesseln -> Abbruch, keine SSH/SFTP-Verbindung. +# Ein separates Passwort-Secret ist dadurch nicht mehr noetig. +# ============================================================================= + +# --- Pfade --- +CONTEXT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +TARGETS_DIR="${CONTEXT_DIR}/targets" + +# --- Hilfsfunktion: verfuegbare Targets auflisten --- +# Eine einzige Quelle fuer die Target-Liste (keine duplizierten Strings mehr). +list_targets() { + local found="" + local f name + if [ -d "${TARGETS_DIR}" ]; then + for f in "${TARGETS_DIR}"/*.env; do + [ -e "$f" ] || continue + name="$(basename "$f" .env)" + # 'example' ist nur eine Vorlage und kein echtes Target. + [ "$name" = "example" ] && continue + found="${found:+${found}, }${name}" + done + fi + if [ -n "$found" ]; then + echo "Verfuegbare Targets: ${found}" + else + echo "Keine Targets konfiguriert. Lege eines mit ./init.sh an." + fi +} + +# --- Target-Validierung --- +TARGET="${1:-}" + +if [ -z "$TARGET" ]; then + echo "FEHLER: Target ist erforderlich." + echo "Verwendung: $0 " + list_targets + exit 1 +fi + +# Target-Name auf sichere Zeichen beschraenken, bevor daraus ein Pfad gebaut +# wird (verhindert Path-Traversal wie '../' und das Laden beliebiger Dateien). +if ! printf '%s' "$TARGET" | grep -Eq '^[A-Za-z0-9._-]+$'; then + echo "FEHLER: Ungueltiger Target-Name '${TARGET}'." + echo "Erlaubt sind nur Buchstaben, Zahlen sowie '.', '_' und '-'." + list_targets + exit 1 +fi + +# --- Target-Aufloesung (Config aus targets/.env laden) --- +TARGET_FILE="${TARGETS_DIR}/${TARGET}.env" + +if [ ! -f "${TARGET_FILE}" ]; then + echo "FEHLER: Unbekanntes Target '${TARGET}'." + list_targets + exit 1 +fi + +# shellcheck disable=SC1090 +source "${TARGET_FILE}" + +# Pflichtfelder pruefen, damit kaputte Configs frueh auffallen. +for _var in SSH_HOST SFTP_HOST DB_NAME GIT_REMOTE DOMAIN; do + if [ -z "${!_var:-}" ]; then + echo "FEHLER: '${_var}' fehlt oder ist leer in ${TARGET_FILE}." + exit 1 + fi +done +unset _var + +export TARGET SSH_HOST SFTP_HOST DB_NAME GIT_REMOTE DOMAIN + +echo "Target: ${TARGET} (${DOMAIN})" + +# --- SSH-Setup --- +setup_ssh() { + WORKSPACE_SSH_DIR="/home/runner/workspace/.ssh" + KEY_PATH="${WORKSPACE_SSH_DIR}/id_ed25519_forgejo" + local FORGEJO_SSH_PORT="2222" + SFTP_PORT="2022" + + mkdir -p "${WORKSPACE_SSH_DIR}" + + # SSH-Config fuer den aktuellen Host erstellen/aktualisieren + local TEMP_CONFIG + TEMP_CONFIG=$(mktemp) + + if [ -f "${WORKSPACE_SSH_DIR}/config" ]; then + # Bestehende Eintraege fuer diesen Host entfernen + awk -v host="${SSH_HOST}" ' + /^Host / { skip = ($2 == host); } + !skip { print; } + ' "${WORKSPACE_SSH_DIR}/config" > "${TEMP_CONFIG}" + else + touch "${TEMP_CONFIG}" + fi + + cat >> "${TEMP_CONFIG}" < nach Checkout/Reset liegt der Key auf 0644, + # was ssh-add ablehnt. Rechte hier korrigieren und Fehler sichtbar machen. + if ! chmod 600 "${KEY_PATH}"; then + echo "FEHLER: Konnte Rechte auf ${KEY_PATH} nicht auf 600 setzen." + exit 1 + fi + chmod 644 "${WORKSPACE_SSH_DIR}/config" + + # Symlinks ins Home-Verzeichnis + mkdir -p ~/.ssh + ln -sf "${WORKSPACE_SSH_DIR}/config" ~/.ssh/config + ln -sf "${KEY_PATH}" ~/.ssh/id_ed25519_forgejo + ln -sf "${KEY_PATH}.pub" ~/.ssh/id_ed25519_forgejo.pub + + # --- Verschluesselten Key in ssh-agent laden (Passphrase-Abfrage) --- + if [ ! -f "${KEY_PATH}" ]; then + echo "FEHLER: SSH-Key nicht gefunden: ${KEY_PATH}" + exit 1 + fi + + # ssh-add fragt die Passphrase ueber das Terminal ab. + if [ ! -t 0 ]; then + echo "FEHLER: Kein interaktives Terminal. Skript muss manuell ausgefuehrt werden." + exit 1 + fi + + # Frischen ssh-agent starten und beim Script-Ende automatisch beenden, + # damit der entschluesselte Key nur waehrend der Laufzeit im Speicher liegt. + eval "$(ssh-agent -s)" >/dev/null + trap 'ssh-agent -k >/dev/null 2>&1 || true' EXIT + + echo "Lade SSH-Key in den Agent (Passphrase erforderlich; siehe VaultWarden)..." + if ! ssh-add "${KEY_PATH}"; then + echo "FEHLER: SSH-Key konnte nicht geladen werden (falsche Passphrase?)." + exit 1 + fi + echo "SSH-Key geladen." + + echo "SSH-Setup fuer ${SSH_HOST} abgeschlossen." + + # Exportiere Pfade fuer andere Skripte + export WORKSPACE_SSH_DIR KEY_PATH SFTP_PORT +} diff --git a/hetzner-deployment/targets/example.env b/hetzner-deployment/targets/example.env new file mode 100644 index 0000000..fb2fe98 --- /dev/null +++ b/hetzner-deployment/targets/example.env @@ -0,0 +1,14 @@ +# Beispiel-Target-Konfiguration (Vorlage / Referenz). +# +# Diese Datei wird von ssh_context.sh bei der Target-Liste IGNORIERT +# (Dateiname 'example.env'). Sie dient nur als Vorlage. +# +# Ein echtes Target legst du am einfachsten interaktiv an: +# ./init.sh +# Alternativ diese Datei nach targets/.env kopieren und anpassen. + +SSH_HOST="forgejo-landing.kwali8.de" +SFTP_HOST="forgejo-landing.kwali8.de" +DB_NAME="helium" +GIT_REMOTE="kwali8-landingpage" +DOMAIN="kwali8.de" diff --git a/hetzner-deployment/targets/kwali8-landingpage.env b/hetzner-deployment/targets/kwali8-landingpage.env new file mode 100644 index 0000000..49632f1 --- /dev/null +++ b/hetzner-deployment/targets/kwali8-landingpage.env @@ -0,0 +1,7 @@ +# Target-Konfiguration fuer 'kwali8-landingpage' (Beispiel-Target / Referenz). +# Erstellt von init.sh oder manuell. Wird von ssh_context.sh geladen. +SSH_HOST="forgejo-landing.kwali8.de" +SFTP_HOST="forgejo-landing.kwali8.de" +DB_NAME="helium" +GIT_REMOTE="kwali8-landingpage" +DOMAIN="kwali8.de" diff --git a/hetzner-deployment/targets/skillguard.env b/hetzner-deployment/targets/skillguard.env new file mode 100644 index 0000000..818c7e4 --- /dev/null +++ b/hetzner-deployment/targets/skillguard.env @@ -0,0 +1,7 @@ +# Target-Konfiguration fuer 'skillguard'. +# Erstellt von init.sh am 2026-06-18 15:10:32. +SSH_HOST='forgejo-skillguard.a42i.de' +SFTP_HOST='forgejo-skillguard.a42i.de' +DB_NAME='helium' +GIT_REMOTE='skillguard' +DOMAIN='a42i.de'