#!/usr/bin/env bash set -euo pipefail APP_DIR="${APP_DIR:-/opt/ypchat}" REPO_URL="${REPO_URL:-ssh://git@tsschulz.de:2222/torsten/singlechat}" BRANCH="${BRANCH:-main}" SERVICE_NAME="${SERVICE_NAME:-ypchat}" RUN_USER="${RUN_USER:-www-data}" RUN_GROUP="${RUN_GROUP:-www-data}" DEPLOY_USER="${DEPLOY_USER:-${SUDO_USER:-$(id -un)}}" DEPLOY_GROUP="${DEPLOY_GROUP:-$(id -gn "$DEPLOY_USER")}" LOCK_DIR="${LOCK_DIR:-/tmp/actualize-singlechat}" LOCK_FILE="${LOCK_FILE:-$LOCK_DIR/deploy.lock}" NPM_CACHE_DIR="${NPM_CACHE_DIR:-$APP_DIR/.npm-cache}" log() { printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" } run_as_deploy_user() { if [ "$(id -u)" -eq 0 ]; then sudo -u "$DEPLOY_USER" env HOME="$(getent passwd "$DEPLOY_USER" | cut -d: -f6)" npm_config_cache="$NPM_CACHE_DIR" "$@" else env HOME="$APP_DIR" npm_config_cache="$NPM_CACHE_DIR" "$@" fi } need_cmd() { if ! command -v "$1" >/dev/null 2>&1; then echo "FEHLER: $1 ist nicht installiert." >&2 exit 1 fi } need_cmd git need_cmd npm need_cmd node need_cmd rsync need_cmd flock need_cmd openssl if [ "$(id -u)" -ne 0 ]; then need_cmd sudo fi mkdir -p "$LOCK_DIR" if [ "$(id -u)" -eq 0 ]; then chown "$DEPLOY_USER:$DEPLOY_GROUP" "$LOCK_DIR" 2>/dev/null || true fi exec 9>"$LOCK_FILE" if ! flock -n 9; then echo "Deployment laeuft bereits: $LOCK_FILE" >&2 exit 1 fi log "Starte YpChat Rollout" log "APP_DIR=$APP_DIR" log "REPO_URL=$REPO_URL" log "BRANCH=$BRANCH" log "SERVICE_NAME=$SERVICE_NAME" log "DEPLOY_USER=$DEPLOY_USER" mkdir -p "$APP_DIR" "$NPM_CACHE_DIR" if [ "$(id -u)" -eq 0 ]; then chown -R "$DEPLOY_USER:$DEPLOY_GROUP" "$APP_DIR" "$NPM_CACHE_DIR" fi if [ ! -d "$APP_DIR/.git" ]; then log "Erstelle initialen Git-Checkout fuer $APP_DIR" if [ "$(id -u)" -eq 0 ]; then tmp_checkout="$(sudo -u "$DEPLOY_USER" mktemp -d)" else tmp_checkout="$(mktemp -d)" fi run_as_deploy_user git clone --branch "$BRANCH" --single-branch "$REPO_URL" "$tmp_checkout" rsync -a --delete \ --no-owner \ --no-group \ --omit-dir-times \ --exclude '.env' \ --exclude '.npm-cache/' \ --exclude 'node_modules/' \ --exclude 'client/node_modules/' \ --exclude 'client/dist/' \ --exclude 'docroot/dist/' \ --exclude 'logs/' \ --exclude 'tmp/' \ "$tmp_checkout/" "$APP_DIR/" rm -rf "$tmp_checkout" fi if [ "$(id -u)" -eq 0 ]; then chown -R "$DEPLOY_USER:$DEPLOY_GROUP" "$APP_DIR" "$NPM_CACHE_DIR" fi cd "$APP_DIR" if ! run_as_deploy_user git remote get-url origin >/dev/null 2>&1; then run_as_deploy_user git remote add origin "$REPO_URL" fi current_origin="$(run_as_deploy_user git remote get-url origin)" if [ "$current_origin" != "$REPO_URL" ]; then log "Setze Git-Origin von $current_origin auf $REPO_URL" run_as_deploy_user git remote set-url origin "$REPO_URL" fi log "Hole neuesten Stand" run_as_deploy_user git fetch --prune origin "$BRANCH" run_as_deploy_user git reset --hard "origin/$BRANCH" run_as_deploy_user git clean -fd \ -e .env \ -e .npm-cache/ \ -e node_modules/ \ -e client/node_modules/ \ -e client/dist/ \ -e logs/ \ -e tmp/ \ -e docroot/dist/ if [ "$(id -u)" -eq 0 ]; then chown -R "$DEPLOY_USER:$DEPLOY_GROUP" "$APP_DIR" "$NPM_CACHE_DIR" fi log "Installiere Root-Dependencies" run_as_deploy_user npm ci log "Installiere Client-Dependencies" run_as_deploy_user npm --prefix client ci if [ ! -f "$APP_DIR/.env" ]; then log "Erstelle .env" session_secret="$(openssl rand -hex 32)" cat > "$APP_DIR/.env" </dev/null 2>&1; then log "Starte Service neu: $SERVICE_NAME" if [ "$(id -u)" -eq 0 ]; then systemctl restart "$SERVICE_NAME" systemctl --no-pager --lines=20 status "$SERVICE_NAME" else sudo systemctl restart "$SERVICE_NAME" sudo systemctl --no-pager --lines=20 status "$SERVICE_NAME" fi else log "systemctl nicht gefunden, Service-Neustart uebersprungen" fi log "YpChat Rollout abgeschlossen"