Uebertragung per tar, Abgleich auf dem Zielhost
Deploy auf den Timer-Server / deploy (push) Failing after 13s
Deploy auf den Timer-Server / deploy (push) Failing after 13s
rsync scheitert im Runner-Container am Docker-Host ('pipe: Permission
denied', auch im 22.04-Image). Das Paket geht jetzt per tar hinueber und
wird auf dem Server abgeglichen, wo rsync normal laeuft.
Dabei die Rechte geradegezogen: der Deploy-Benutzer besitzt den Code und
braucht dafuer kein sudo. Das frueher vorgesehene 'chown -R timerapp' nach
jedem Lauf haette ihm die Schreibrechte fuer den naechsten Lauf entzogen -
und die Einrichtungsanleitung haette dem Dienst das Datenverzeichnis
weggenommen. Jetzt: Code gehoert deploy, data/ gehoert timerapp.
Ein Diagnoseschritt meldet zu Beginn Benutzer, Werkzeuge, Rechte und
sudo-Regeln, damit solche Faelle im Protokoll sichtbar sind.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -21,7 +21,6 @@ jobs:
|
|||||||
DEPLOY_USER: ${{ vars.DEPLOY_USER }}
|
DEPLOY_USER: ${{ vars.DEPLOY_USER }}
|
||||||
DEPLOY_PATH: ${{ vars.DEPLOY_PATH }}
|
DEPLOY_PATH: ${{ vars.DEPLOY_PATH }}
|
||||||
DEPLOY_SERVICE: ${{ vars.DEPLOY_SERVICE }}
|
DEPLOY_SERVICE: ${{ vars.DEPLOY_SERVICE }}
|
||||||
DEPLOY_OWNER: ${{ vars.DEPLOY_OWNER }}
|
|
||||||
HEALTH_URL: ${{ vars.HEALTH_URL }}
|
HEALTH_URL: ${{ vars.HEALTH_URL }}
|
||||||
# Repository-Secrets (Settings -> Actions -> Secrets)
|
# Repository-Secrets (Settings -> Actions -> Secrets)
|
||||||
DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
|
DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
|
||||||
@@ -70,17 +69,47 @@ jobs:
|
|||||||
chmod 600 ~/.ssh/id_ed25519
|
chmod 600 ~/.ssh/id_ed25519
|
||||||
chmod 644 ~/.ssh/known_hosts
|
chmod 644 ~/.ssh/known_hosts
|
||||||
|
|
||||||
- name: Dateien uebertragen
|
- name: Verbindung pruefen
|
||||||
run: |
|
run: |
|
||||||
# --delete raeumt geloeschte Dateien auf dem Server weg. Die
|
ssh -o BatchMode=yes "$DEPLOY_USER@$DEPLOY_HOST" "DEPLOY_PATH='$DEPLOY_PATH' bash -s" <<'PRUEF'
|
||||||
# ausgeschlossenen Pfade sind davon ausgenommen (kein --delete-excluded!):
|
echo "Angemeldet als $(id -un) auf $(hostname)"
|
||||||
# Konfiguration, Datenbank und node_modules bleiben unangetastet.
|
for w in rsync npm node systemctl; do
|
||||||
|
printf ' %-10s %s\n' "$w" "$(command -v $w || echo FEHLT)"
|
||||||
|
done
|
||||||
|
echo "Rechte:"
|
||||||
|
ls -ld "$DEPLOY_PATH" "$DEPLOY_PATH/backend" "$DEPLOY_PATH/data" 2>&1 | sed 's/^/ /'
|
||||||
|
echo "Schreibtest im Anwendungsverzeichnis:"
|
||||||
|
if touch "$DEPLOY_PATH/.schreibtest" 2>/dev/null; then
|
||||||
|
rm -f "$DEPLOY_PATH/.schreibtest"; echo " ok"
|
||||||
|
else
|
||||||
|
echo " FEHLGESCHLAGEN - der Deploy-Benutzer darf dort nicht schreiben"
|
||||||
|
fi
|
||||||
|
echo "sudo-Rechte:"; sudo -n -l 2>&1 | tail -5 | sed 's/^/ /'
|
||||||
|
PRUEF
|
||||||
|
|
||||||
|
- name: Dateien uebertragen und abgleichen
|
||||||
|
run: |
|
||||||
|
# rsync laeuft NICHT im Runner-Container: dessen Docker-Host verbietet
|
||||||
|
# den pipe()-Aufruf ("pipe: Permission denied"). Deshalb geht das
|
||||||
|
# Paket per tar hinueber und der Abgleich passiert auf dem Zielhost.
|
||||||
|
tar -czf paket.tgz -C quelle --exclude=.git --exclude=.gitea .
|
||||||
|
|
||||||
|
ssh -o BatchMode=yes "$DEPLOY_USER@$DEPLOY_HOST" \
|
||||||
|
'rm -rf /tmp/timer-app-release && mkdir -p /tmp/timer-app-release && tar -xzf - -C /tmp/timer-app-release' \
|
||||||
|
< paket.tgz
|
||||||
|
|
||||||
|
# --delete raeumt geloeschte Dateien weg. Die ausgeschlossenen Pfade
|
||||||
|
# sind davon ausgenommen (kein --delete-excluded!): Konfiguration,
|
||||||
|
# Datenbank und node_modules bleiben unangetastet.
|
||||||
|
ssh -o BatchMode=yes "$DEPLOY_USER@$DEPLOY_HOST" \
|
||||||
|
"DEPLOY_PATH='$DEPLOY_PATH' bash -euo pipefail -s" > uebertragen.txt <<'SYNC'
|
||||||
rsync -rlpt --delete --out-format='%n' \
|
rsync -rlpt --delete --out-format='%n' \
|
||||||
--exclude='.git/' --exclude='.gitea/' \
|
|
||||||
--exclude='.env' --exclude='.env.*' \
|
--exclude='.env' --exclude='.env.*' \
|
||||||
--exclude='data/' --exclude='node_modules/' \
|
--exclude='data/' --exclude='node_modules/' \
|
||||||
-e 'ssh -o BatchMode=yes' \
|
/tmp/timer-app-release/ "$DEPLOY_PATH/"
|
||||||
quelle/ "$DEPLOY_USER@$DEPLOY_HOST:$DEPLOY_PATH/" | tee uebertragen.txt
|
rm -rf /tmp/timer-app-release
|
||||||
|
SYNC
|
||||||
|
cat uebertragen.txt
|
||||||
|
|
||||||
- name: Abhaengigkeiten, Neustart und Health-Check
|
- name: Abhaengigkeiten, Neustart und Health-Check
|
||||||
run: |
|
run: |
|
||||||
@@ -97,7 +126,6 @@ jobs:
|
|||||||
ssh -o BatchMode=yes "$DEPLOY_USER@$DEPLOY_HOST" \
|
ssh -o BatchMode=yes "$DEPLOY_USER@$DEPLOY_HOST" \
|
||||||
"NPM='$NPM' RESTART='$RESTART' \
|
"NPM='$NPM' RESTART='$RESTART' \
|
||||||
DEPLOY_PATH='$DEPLOY_PATH' DEPLOY_SERVICE='$DEPLOY_SERVICE' \
|
DEPLOY_PATH='$DEPLOY_PATH' DEPLOY_SERVICE='$DEPLOY_SERVICE' \
|
||||||
DEPLOY_OWNER='${DEPLOY_OWNER:-timerapp:timerapp}' \
|
|
||||||
HEALTH_URL='${HEALTH_URL:-http://127.0.0.1:3003/health}' \
|
HEALTH_URL='${HEALTH_URL:-http://127.0.0.1:3003/health}' \
|
||||||
bash -euo pipefail -s" <<'REMOTE'
|
bash -euo pipefail -s" <<'REMOTE'
|
||||||
SUDO=""; [ "$(id -u)" -eq 0 ] || SUDO="sudo -n"
|
SUDO=""; [ "$(id -u)" -eq 0 ] || SUDO="sudo -n"
|
||||||
@@ -108,9 +136,6 @@ jobs:
|
|||||||
$SUDO npm ci --omit=dev --no-audit --no-fund
|
$SUDO npm ci --omit=dev --no-audit --no-fund
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Alles unter dem Anwendungsverzeichnis gehoert dem Dienstbenutzer.
|
|
||||||
$SUDO chown -R "$DEPLOY_OWNER" "$DEPLOY_PATH"
|
|
||||||
|
|
||||||
if [ "$RESTART" = nein ]; then
|
if [ "$RESTART" = nein ]; then
|
||||||
echo "--- Keine Backend-Aenderung: Neustart nicht noetig"
|
echo "--- Keine Backend-Aenderung: Neustart nicht noetig"
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
@@ -487,7 +487,9 @@ Stand selbsttaetig auf den Server aus. Der Workflow liegt in
|
|||||||
|
|
||||||
### Was der Workflow tut
|
### Was der Workflow tut
|
||||||
|
|
||||||
1. Uebertraegt die versionierten Dateien per `rsync` nach `/opt/timer-app`.
|
1. Uebertraegt die versionierten Dateien als tar-Paket auf den Server und
|
||||||
|
gleicht sie dort per `rsync` gegen `/opt/timer-app` ab. (Im Runner-Container
|
||||||
|
laesst der Docker-Host rsync nicht laufen - `pipe: Permission denied`.)
|
||||||
**Nicht angefasst** werden `backend/.env`, `data/` und `node_modules/` —
|
**Nicht angefasst** werden `backend/.env`, `data/` und `node_modules/` —
|
||||||
sie sind vom Abgleich ausgenommen und ueberleben auch das `--delete`,
|
sie sind vom Abgleich ausgenommen und ueberleben auch das `--delete`,
|
||||||
das geloeschte Dateien auf dem Server aufraeumt.
|
das geloeschte Dateien auf dem Server aufraeumt.
|
||||||
@@ -511,14 +513,17 @@ mkdir -p /home/deploy/.ssh && chmod 700 /home/deploy/.ssh
|
|||||||
echo '<oeffentlicher Schluessel>' >> /home/deploy/.ssh/authorized_keys
|
echo '<oeffentlicher Schluessel>' >> /home/deploy/.ssh/authorized_keys
|
||||||
chown -R deploy:deploy /home/deploy/.ssh && chmod 600 /home/deploy/.ssh/authorized_keys
|
chown -R deploy:deploy /home/deploy/.ssh && chmod 600 /home/deploy/.ssh/authorized_keys
|
||||||
|
|
||||||
# Schreibrecht auf das Anwendungsverzeichnis
|
# Der Code gehoert dem Deploy-Benutzer, der Dienst liest ihn nur.
|
||||||
chown -R deploy:timerapp /opt/timer-app && chmod -R g+rX /opt/timer-app
|
chown -R deploy:timerapp /opt/timer-app && chmod -R g+rX /opt/timer-app
|
||||||
|
|
||||||
|
# WICHTIG: das Datenverzeichnis gehoert dem Dienst - sonst kann die
|
||||||
|
# Anwendung ihre Datenbank nicht mehr schreiben.
|
||||||
|
chown -R timerapp:timerapp /opt/timer-app/data && chmod 750 /opt/timer-app/data
|
||||||
|
|
||||||
# Genau die drei Befehle ohne Passwort - nicht mehr
|
# Genau die drei Befehle ohne Passwort - nicht mehr
|
||||||
cat > /etc/sudoers.d/deploy-timer-app <<'EOF'
|
cat > /etc/sudoers.d/deploy-timer-app <<'EOF'
|
||||||
deploy ALL=(root) NOPASSWD: /bin/systemctl restart timer-app, \
|
deploy ALL=(root) NOPASSWD: /bin/systemctl restart timer-app, \
|
||||||
/bin/journalctl -u timer-app *, \
|
/bin/journalctl -u timer-app *
|
||||||
/bin/chown -R timerapp\:timerapp /opt/timer-app
|
|
||||||
EOF
|
EOF
|
||||||
chmod 440 /etc/sudoers.d/deploy-timer-app
|
chmod 440 /etc/sudoers.d/deploy-timer-app
|
||||||
visudo -c
|
visudo -c
|
||||||
@@ -532,7 +537,6 @@ Im Repo unter **Settings -> Actions** hinterlegen:
|
|||||||
| Variable | `DEPLOY_USER` | `deploy` |
|
| Variable | `DEPLOY_USER` | `deploy` |
|
||||||
| Variable | `DEPLOY_PATH` | `/opt/timer-app` |
|
| Variable | `DEPLOY_PATH` | `/opt/timer-app` |
|
||||||
| Variable | `DEPLOY_SERVICE` | `timer-app` |
|
| Variable | `DEPLOY_SERVICE` | `timer-app` |
|
||||||
| Variable | `DEPLOY_OWNER` | `timerapp:timerapp` |
|
|
||||||
| Variable | `HEALTH_URL` | `http://127.0.0.1:3003/health` |
|
| Variable | `HEALTH_URL` | `http://127.0.0.1:3003/health` |
|
||||||
| Secret | `DEPLOY_SSH_KEY` | privater Deploy-Schluessel (ganze Datei inkl. BEGIN/END-Zeilen) |
|
| Secret | `DEPLOY_SSH_KEY` | privater Deploy-Schluessel (ganze Datei inkl. BEGIN/END-Zeilen) |
|
||||||
| Secret | `DEPLOY_KNOWN_HOSTS` | `ssh-keyscan 192.168.1.5` — Zeile(n) fuer den Zielhost |
|
| Secret | `DEPLOY_KNOWN_HOSTS` | `ssh-keyscan 192.168.1.5` — Zeile(n) fuer den Zielhost |
|
||||||
|
|||||||
Reference in New Issue
Block a user