mailwolt-installer/scripts/80-app.sh

460 lines
18 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/usr/bin/env bash
set -euo pipefail
source ./lib.sh
relink_and_reload() {
if [[ -d /etc/letsencrypt/renewal-hooks/deploy ]]; then
run-parts /etc/letsencrypt/renewal-hooks/deploy || true
fi
if systemctl is-active --quiet nginx; then
systemctl reload nginx || true
fi
}
log "App bereitstellen …"
mkdir -p "$(dirname "$APP_DIR")"
chown -R "$APP_USER":"$APP_GROUP" "$(dirname "$APP_DIR")"
# Repo holen oder Laravel anlegen passe GIT_REPO/GIT_BRANCH bei Bedarf an
GIT_REPO="${GIT_REPO:-https://git.nexlab.at/boban/mailwolt.git}"
GIT_BRANCH="${GIT_BRANCH:-main}"
if [[ "${GIT_REPO}" == "https://example.com/your-repo-placeholder.git" ]]; then
[[ -d "$APP_DIR" && -n "$(ls -A "$APP_DIR" 2>/dev/null || true)" ]] || \
sudo -u "$APP_USER" -H bash -lc "cd /var/www && composer create-project laravel/laravel ${APP_USER} --no-interaction"
else
if [[ ! -d "${APP_DIR}/.git" ]]; then
sudo -u "$APP_USER" -H bash -lc "git clone --depth=1 -b ${GIT_BRANCH} ${GIT_REPO} ${APP_DIR}"
else
sudo -u "$APP_USER" -H bash -lc "cd ${APP_DIR} && git fetch --depth=1 origin ${GIT_BRANCH} && git reset --hard origin/${GIT_BRANCH}"
fi
[[ -f "${APP_DIR}/composer.json" ]] && sudo -u "$APP_USER" -H bash -lc "cd ${APP_DIR} && composer install --no-interaction --prefer-dist"
fi
ENV_FILE="${APP_DIR}/.env"
sudo -u "$APP_USER" -H bash -lc "cd ${APP_DIR} && cp -n .env.example .env || true"
grep -q '^APP_KEY=' "$ENV_FILE" || echo "APP_KEY=" >> "$ENV_FILE"
sudo -u "$APP_USER" -H bash -lc "cd ${APP_DIR} && php artisan key:generate --force || true"
# --- App-URL/Hosts ----------------------------------------------------------
SERVER_PUBLIC_IPV4="${SERVER_PUBLIC_IPV4:-}"
if [[ -z "$SERVER_PUBLIC_IPV4" ]] && command -v curl >/dev/null 2>&1; then
SERVER_PUBLIC_IPV4="$(curl -fsS --max-time 2 https://ifconfig.me 2>/dev/null || true)"
[[ "$SERVER_PUBLIC_IPV4" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] || SERVER_PUBLIC_IPV4=""
fi
[[ -n "$SERVER_PUBLIC_IPV4" ]] || SERVER_PUBLIC_IPV4="$(detect_ip)"
UI_CERT="/etc/ssl/ui/fullchain.pem"
UI_KEY="/etc/ssl/ui/privkey.pem"
if [[ -n "${UI_HOST:-}" ]]; then
APP_HOST_VAL="$UI_HOST"
APP_URL_VAL="https://${UI_HOST}"
else
APP_HOST_VAL="$SERVER_PUBLIC_IPV4"
SCHEME="http"
[[ -s "$UI_CERT" && -s "$UI_KEY" ]] && SCHEME="https"
APP_URL_VAL="${SCHEME}://${SERVER_PUBLIC_IPV4}"
fi
# --- .env schreiben ---------------------------------------------------------
upsert_env APP_URL "${APP_URL_VAL}"
if [[ "${PROXY_MODE:-0}" -eq 1 ]]; then
TP_LIST="127.0.0.1,::1"
[[ -n "${NPM_IP:-}" ]] && TP_LIST="${TP_LIST},${NPM_IP}"
upsert_env TRUSTED_PROXIES "$TP_LIST"
upsert_env TRUSTED_HEADERS "x-forwarded-all"
else
upsert_env TRUSTED_PROXIES ""
upsert_env TRUSTED_HEADERS "x-forwarded-all"
fi
upsert_env APP_HOST "${APP_HOST_VAL}"
upsert_env APP_NAME "${APP_NAME}"
upsert_env APP_ENV "${APP_ENV:-production}"
upsert_env APP_DEBUG "${APP_DEBUG:-false}"
upsert_env APP_LOCALE "${APP_LOCALE:-de}"
upsert_env APP_FALLBACK_LOCALE "en"
upsert_env SERVER_PUBLIC_IPV4 "${SERVER_PUBLIC_IPV4}"
upsert_env SERVER_PUBLIC_IPV6 "${SERVER_PUBLIC_IPV6:-}"
upsert_env SYSMAIL_SUB "${SYSMAIL_SUB}"
upsert_env SYSMAIL_DOMAIN "${SYSMAIL_DOMAIN}"
upsert_env DKIM_ENABLE "${DKIM_ENABLE}"
upsert_env DKIM_SELECTOR "${DKIM_SELECTOR}"
upsert_env DKIM_GENERATE "${DKIM_GENERATE}"
upsert_env BASE_DOMAIN "${BASE_DOMAIN}"
upsert_env UI_SUB "${UI_SUB}"
upsert_env WEBMAIL_SUB "${WEBMAIL_SUB}"
upsert_env MTA_SUB "${MTA_SUB}"
upsert_env LE_EMAIL "${LE_EMAIL:-admin@${BASE_DOMAIN}}"
upsert_env DB_CONNECTION "mysql"
upsert_env DB_HOST "127.0.0.1"
upsert_env DB_PORT "3306"
upsert_env DB_DATABASE "${DB_NAME}"
upsert_env DB_USERNAME "${DB_USER}"
upsert_env DB_PASSWORD "${DB_PASS}"
upsert_env CACHE_SETTINGS_STORE "redis"
upsert_env CACHE_STORE "redis"
upsert_env CACHE_DRIVER "redis"
upsert_env CACHE_PREFIX "${APP_USER_PREFIX}_cache:"
upsert_env SESSION_DRIVER "redis"
upsert_env SESSION_SECURE_COOKIE "true"
upsert_env SESSION_SAMESITE "lax"
upsert_env REDIS_CLIENT "phpredis"
upsert_env REDIS_HOST "127.0.0.1"
upsert_env REDIS_PORT "6379"
upsert_env REDIS_PASSWORD "${REDIS_PASS}"
upsert_env REDIS_DB "0"
upsert_env REDIS_CACHE_DB "1"
upsert_env REDIS_CACHE_CONNECTION "cache"
upsert_env REDIS_CACHE_LOCK_CONNECTION "default"
upsert_env BROADCAST_DRIVER "reverb"
upsert_env QUEUE_CONNECTION "redis"
upsert_env LOG_CHANNEL "daily"
upsert_env REVERB_APP_ID "${APP_USER_PREFIX}"
grep -q '^REVERB_APP_KEY=' "$ENV_FILE" || upsert_env REVERB_APP_KEY "${APP_USER_PREFIX}_$(openssl rand -hex 16)"
grep -q '^REVERB_APP_SECRET=' "$ENV_FILE" || upsert_env REVERB_APP_SECRET "${APP_USER_PREFIX}_$(openssl rand -hex 32)"
upsert_env REVERB_HOST "\${APP_HOST}"
upsert_env REVERB_PORT "443"
upsert_env REVERB_SCHEME "https"
upsert_env REVERB_PATH "/ws"
upsert_env REVERB_SCALING_ENABLED "true"
upsert_env REVERB_SCALING_CHANNEL "reverb"
upsert_env VITE_REVERB_APP_KEY "\${REVERB_APP_KEY}"
upsert_env VITE_REVERB_HOST "\${REVERB_HOST}"
upsert_env VITE_REVERB_PORT "\${REVERB_PORT}"
upsert_env VITE_REVERB_SCHEME "\${REVERB_SCHEME}"
upsert_env VITE_REVERB_PATH "\${REVERB_PATH}"
upsert_env REVERB_SERVER_APP_KEY "\${REVERB_APP_KEY}"
upsert_env REVERB_SERVER_HOST "127.0.0.1"
upsert_env REVERB_SERVER_PORT "8080"
upsert_env REVERB_SERVER_PATH ""
upsert_env REVERB_SERVER_SCHEME "http"
# --- DEV Block (optional) ---------------------------------------------------
DEV_MODE="${DEV_MODE:-0}"
if [[ "$DEV_MODE" = "1" ]]; then
sed -i '/^# --- MailWolt DEV/,/^# --- \/MailWolt DEV/d' "${ENV_FILE}"
cat >> "${ENV_FILE}" <<CONF
# --- MailWolt DEV ---
VITE_DEV_HOST=127.0.0.1
VITE_DEV_PORT=5173
VITE_HMR_PROTOCOL=wss
VITE_HMR_CLIENT_PORT=443
VITE_HMR_HOST=${SERVER_PUBLIC_IPV4}
VITE_DEV_ORIGIN=$(grep '^APP_URL=' "${ENV_FILE}" | cut -d= -f2-)
# --- /MailWolt DEV ---
CONF
fi
# --- Zertifikate in /etc/ssl/* bereitstellen, bevor Laravel irgendwas liest --
relink_and_reload
# --- RECHTE FIXEN: storage & bootstrap/cache (www-data + mailwolt) ----------
log "Setze korrekte Rechte für Laravel-Verzeichnisse …"
cd "${APP_DIR}"
chgrp -R www-data storage bootstrap/cache || true
find storage bootstrap/cache -type d -exec chmod 2775 {} \; || true
find storage bootstrap/cache -type f -exec chmod 0664 {} \; || true
setfacl -R -m u:www-data:rwx,u:${APP_USER}:rwx storage bootstrap/cache || true
setfacl -dR -m u:www-data:rwx,u:${APP_USER}:rwx storage bootstrap/cache || true
log "[✓] Schreibrechte für Laravel korrigiert."
# --- Caches leeren, Migrationen ausführen -----------------------------------
sudo -u "$APP_USER" -H bash -lc "cd ${APP_DIR} && php artisan optimize:clear"
sudo -u "$APP_USER" -H bash -lc "cd ${APP_DIR} && php artisan migrate --force"
# --- Seeder (legt Domains/DKIM etc. an) -------------------------------------
if [[ "${BASE_DOMAIN}" != "example.com" ]]; then
sudo -u "$APP_USER" -H bash -lc "cd ${APP_DIR} && php artisan db:seed --class=SystemDomainSeeder --force"
fi
# --- DKIM für SYSMAIL_DOMAIN via App erzeugen & in OpenDKIM einhängen -------
DKIM_ENABLE="${DKIM_ENABLE:-1}"
DKIM_SELECTOR="${DKIM_SELECTOR:-mwl1}"
SYSMAIL_DOMAIN="${SYSMAIL_DOMAIN:-sysmail.${BASE_DOMAIN}}"
if [[ "${DKIM_ENABLE}" = "1" && -n "${SYSMAIL_DOMAIN}" ]]; then
log "Erzeuge/aktualisiere DKIM für ${SYSMAIL_DOMAIN} (Selector: ${DKIM_SELECTOR}) …"
TMP_PRIV="$(mktemp /tmp/dkim_priv_XXXXXX.pem)"
TMP_TXT="$(mktemp /tmp/dkim_txt_XXXXXX.txt)"
chown "${APP_USER}:${APP_GROUP}" "$TMP_PRIV" "$TMP_TXT"
chmod 600 "$TMP_PRIV" "$TMP_TXT"
sudo -u "${APP_USER}" -H bash -lc "cd ${APP_DIR} && php -r '
require \"vendor/autoload.php\";
\$app = require \"bootstrap/app.php\";
\$kernel = \$app->make(Illuminate\\Contracts\\Console\\Kernel::class); \$kernel->bootstrap();
\$domain = App\\Models\\Domain::firstOrCreate([\"domain\"=>\"${SYSMAIL_DOMAIN}\"],[\"is_active\"=>1,\"is_system\"=>1]);
\$svc = app(App\\Services\\DkimService::class);
\$res = \$svc->generateForDomain(\$domain, 2048, \"${DKIM_SELECTOR}\");
file_put_contents(\"${TMP_PRIV}\", \$res[\"private_pem\"]);
file_put_contents(\"${TMP_TXT}\", \$res[\"dns_txt\"]);
echo \"OK\\n\";
'"
if [[ -x /usr/local/sbin/mailwolt-install-dkim ]]; then
sudo /usr/local/sbin/mailwolt-install-dkim "${SYSMAIL_DOMAIN}" "${DKIM_SELECTOR}" "${TMP_PRIV}" "${TMP_TXT}" || true
fi
rm -f "${TMP_PRIV}" "${TMP_TXT}" || true
else
log "DKIM übersprungen (DKIM_ENABLE=${DKIM_ENABLE}, SYSMAIL_DOMAIN='${SYSMAIL_DOMAIN}')."
fi
# --- TLSA aus App heraus (idempotent; läuft, wenn Zert lesbar ist) ----------
sudo -u "$APP_USER" -H bash -lc "cd ${APP_DIR} && php artisan dns:tlsa:refresh || true"
# --- Build Frontend (nur wenn nötig) ----------------------------------------
if [[ -f "${APP_DIR}/package.json" && ! -f "${APP_DIR}/public/build/manifest.json" ]]; then
if ! command -v node >/dev/null 2>&1; then
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt-get install -y nodejs
fi
sudo -u "$APP_USER" -H bash -lc "cd ${APP_DIR} && (npm ci --no-audit --no-fund || npm install)"
sudo -u "$APP_USER" -H bash -lc "cd ${APP_DIR} && (npm run build || npx --yes vite build)"
fi
# --- Abschluss: Caches + Rechte + Reloads -----------------------------------
sudo -u "$APP_USER" -H bash -lc "cd ${APP_DIR} && php artisan optimize:clear && php artisan config:cache && php artisan optimize:clear"
chown -R "$APP_USER":"$APP_GROUP" "$APP_DIR"
chmod -R u=rwX,g=rwX,o=rX "$APP_DIR"
install -d -m 0775 -o "$APP_USER" -g "$APP_GROUP" "$APP_DIR/storage" "$APP_DIR/bootstrap/cache"
relink_and_reload
systemctl restart php*-fpm || true
##!/usr/bin/env bash
#set -euo pipefail
#source ./lib.sh
#
#relink_and_reload() {
# if [[ -d /etc/letsencrypt/renewal-hooks/deploy ]]; then
# run-parts /etc/letsencrypt/renewal-hooks/deploy || true
# fi
# # Nur reloaden, wenn nginx läuft (während Erstinstallation evtl. noch nicht aktiv)
# if systemctl is-active --quiet nginx; then
# systemctl reload nginx || true
# fi
#}
#
#log "App bereitstellen …"
#mkdir -p "$(dirname "$APP_DIR")"
#chown -R "$APP_USER":"$APP_GROUP" "$(dirname "$APP_DIR")"
#
## Repo holen oder Laravel anlegen passe GIT_REPO/GIT_BRANCH bei Bedarf an
#GIT_REPO="${GIT_REPO:-https://git.nexlab.at/boban/mailwolt.git}"
#GIT_BRANCH="${GIT_BRANCH:-main}"
#
#if [[ "${GIT_REPO}" == "https://example.com/your-repo-placeholder.git" ]]; then
# [[ -d "$APP_DIR" && -n "$(ls -A "$APP_DIR" 2>/dev/null || true)" ]] || \
# sudo -u "$APP_USER" -H bash -lc "cd /var/www && composer create-project laravel/laravel ${APP_USER} --no-interaction"
#else
# if [[ ! -d "${APP_DIR}/.git" ]]; then
# sudo -u "$APP_USER" -H bash -lc "git clone --depth=1 -b ${GIT_BRANCH} ${GIT_REPO} ${APP_DIR}"
# else
# sudo -u "$APP_USER" -H bash -lc "cd ${APP_DIR} && git fetch --depth=1 origin ${GIT_BRANCH} && git reset --hard origin/${GIT_BRANCH}"
# fi
# [[ -f "${APP_DIR}/composer.json" ]] && sudo -u "$APP_USER" -H bash -lc "cd ${APP_DIR} && composer install --no-interaction --prefer-dist"
#fi
#
#ENV_FILE="${APP_DIR}/.env"
#sudo -u "$APP_USER" -H bash -lc "cd ${APP_DIR} && cp -n .env.example .env || true"
#grep -q '^APP_KEY=' "$ENV_FILE" || echo "APP_KEY=" >> "$ENV_FILE"
#sudo -u "$APP_USER" -H bash -lc "cd ${APP_DIR} && php artisan key:generate --force || true"
#
## --- Hilfen -----------------------------------------------------------------
## DNS-Check (A/AAAA zeigt auf SERVER_PUBLIC_IPV4) kommt aus lib.sh
## resolve_ok "$host" -> 0/1
#
## APP_HOST und APP_URL bestimmen
#SERVER_PUBLIC_IPV4="${SERVER_PUBLIC_IPV4:-}"
#if [[ -z "$SERVER_PUBLIC_IPV4" ]] && command -v curl >/dev/null 2>&1; then
# SERVER_PUBLIC_IPV4="$(curl -fsS --max-time 2 https://ifconfig.me 2>/dev/null || true)"
# [[ "$SERVER_PUBLIC_IPV4" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] || SERVER_PUBLIC_IPV4=""
#fi
#[[ -n "$SERVER_PUBLIC_IPV4" ]] || SERVER_PUBLIC_IPV4="$(detect_ip)"
#
## 2) Domain bevorzugen, wenn UI_HOST gesetzt (z.B. hinter Nginx Proxy Manager)
#UI_CERT="/etc/ssl/ui/fullchain.pem"
#UI_KEY="/etc/ssl/ui/privkey.pem"
#
#if [[ -n "${UI_HOST:-}" ]]; then
# APP_HOST_VAL="$UI_HOST"
# APP_URL_VAL="https://${UI_HOST}" # TLS terminiert am Proxy
#else
# APP_HOST_VAL="$SERVER_PUBLIC_IPV4"
# SCHEME="http"
# [[ -s "$UI_CERT" && -s "$UI_KEY" ]] && SCHEME="https"
# APP_URL_VAL="${SCHEME}://${SERVER_PUBLIC_IPV4}"
#fi
#
## --- .env schreiben (vollständig wie vorher) --------------------------------
#upsert_env APP_URL "${APP_URL_VAL}"
#
#if [[ "$PROXY_MODE" -eq 1 ]]; then
# TP_LIST="127.0.0.1,::1"
# [[ -n "$NPM_IP" ]] && TP_LIST="${TP_LIST},${NPM_IP}"
# upsert_env TRUSTED_PROXIES "$TP_LIST"
# upsert_env TRUSTED_HEADERS "x-forwarded-all"
#else
# upsert_env TRUSTED_PROXIES ""
# upsert_env TRUSTED_HEADERS "x-forwarded-all"
#fi
#
#upsert_env APP_HOST "${APP_HOST_VAL}"
#upsert_env APP_NAME "${APP_NAME}"
#upsert_env APP_ENV "${APP_ENV:-production}"
#upsert_env APP_DEBUG "${APP_DEBUG:-false}"
#
## Locale
#upsert_env APP_LOCALE "${APP_LOCALE:-de}"
#upsert_env APP_FALLBACK_LOCALE "en"
#
## Server IPs
#upsert_env SERVER_PUBLIC_IPV4 "${SERVER_PUBLIC_IPV4}"
#if [[ -n "${SERVER_PUBLIC_IPV6:-}" ]]; then
# upsert_env SERVER_PUBLIC_IPV6 "${SERVER_PUBLIC_IPV6}"
#else
# upsert_env SERVER_PUBLIC_IPV6 ""
#fi
#
## Hosts & LE
#upsert_env BASE_DOMAIN "${BASE_DOMAIN}"
#upsert_env UI_SUB "${UI_SUB}"
#upsert_env WEBMAIL_SUB "${WEBMAIL_SUB}"
#upsert_env MTA_SUB "${MTA_SUB}"
#upsert_env LE_EMAIL "${LE_EMAIL:-admin@${BASE_DOMAIN}}"
#
## DB
#upsert_env DB_CONNECTION "mysql"
#upsert_env DB_HOST "127.0.0.1"
#upsert_env DB_PORT "3306"
#upsert_env DB_DATABASE "${DB_NAME}"
#upsert_env DB_USERNAME "${DB_USER}"
#upsert_env DB_PASSWORD "${DB_PASS}"
#
## Cache/Session/Redis
#upsert_env CACHE_SETTINGS_STORE "redis"
#upsert_env CACHE_STORE "redis"
#upsert_env CACHE_DRIVER "redis"
#upsert_env CACHE_PREFIX "${APP_USER_PREFIX}_cache:"
#upsert_env SESSION_DRIVER "redis"
#upsert_env SESSION_SECURE_COOKIE "true"
#upsert_env SESSION_SAMESITE "lax"
#upsert_env REDIS_CLIENT "phpredis"
#upsert_env REDIS_HOST "127.0.0.1"
#upsert_env REDIS_PORT "6379"
#upsert_env REDIS_PASSWORD "${REDIS_PASS}"
#upsert_env REDIS_DB "0"
#upsert_env REDIS_CACHE_DB "1"
#upsert_env REDIS_CACHE_CONNECTION "cache"
#upsert_env REDIS_CACHE_LOCK_CONNECTION "default"
#
## Reverb / Queue / Logs
#upsert_env BROADCAST_DRIVER "reverb"
#upsert_env QUEUE_CONNECTION "redis"
#upsert_env LOG_CHANNEL "daily"
#
## Reverb Credentials/Host
#upsert_env REVERB_APP_ID "${APP_USER_PREFIX}"
## nur Generieren, wenn leer sonst vorhandene Werte erhalten
#grep -q '^REVERB_APP_KEY=' "$ENV_FILE" || upsert_env REVERB_APP_KEY "${APP_USER_PREFIX}_$(openssl rand -hex 16)"
#grep -q '^REVERB_APP_SECRET=' "$ENV_FILE" || upsert_env REVERB_APP_SECRET "${APP_USER_PREFIX}_$(openssl rand -hex 32)"
#upsert_env REVERB_HOST "\${APP_HOST}"
#upsert_env REVERB_PORT "443"
#upsert_env REVERB_SCHEME "https"
#upsert_env REVERB_PATH "/ws"
#upsert_env REVERB_SCALING_ENABLED "true"
#upsert_env REVERB_SCALING_CHANNEL "reverb"
#
## Vite Expose
#upsert_env VITE_REVERB_APP_KEY "\${REVERB_APP_KEY}"
#upsert_env VITE_REVERB_HOST "\${REVERB_HOST}"
#upsert_env VITE_REVERB_PORT "\${REVERB_PORT}"
#upsert_env VITE_REVERB_SCHEME "\${REVERB_SCHEME}"
#upsert_env VITE_REVERB_PATH "\${REVERB_PATH}"
#
## Reverb Server (Backend)
#upsert_env REVERB_SERVER_APP_KEY "\${REVERB_APP_KEY}"
#upsert_env REVERB_SERVER_HOST "127.0.0.1"
#upsert_env REVERB_SERVER_PORT "8080"
#upsert_env REVERB_SERVER_PATH ""
#upsert_env REVERB_SERVER_SCHEME "http"
#
## DEV-Block (optional per DEV_MODE=1)
#DEV_MODE="${DEV_MODE:-0}"
#if [[ "$DEV_MODE" = "1" ]]; then
# # vor doppelten Blöcken schützen
# sed -i '/^# --- MailWolt DEV/,/^# --- \/MailWolt DEV/d' "${ENV_FILE}"
# cat >> "${ENV_FILE}" <<CONF
## --- MailWolt DEV ---
#VITE_DEV_HOST=127.0.0.1
#VITE_DEV_PORT=5173
#VITE_HMR_PROTOCOL=wss
#VITE_HMR_CLIENT_PORT=443
#VITE_HMR_HOST=${SERVER_PUBLIC_IPV4}
#VITE_DEV_ORIGIN=$(grep '^APP_URL=' "${ENV_FILE}" | cut -d= -f2-)
## --- /MailWolt DEV ---
#CONF
#fi
#
## --- LE-Symlinks & Nginx (vor Seeder), damit UI/Webmail schon LE-Zert nutzen ---
#relink_and_reload
#
## Laravel Caches säubern und migrieren
#sudo -u "$APP_USER" -H bash -lc "cd ${APP_DIR} && php artisan optimize:clear"
#
## Migration erzwingen (damit 'settings' & Co. existieren)
#sudo -u "$APP_USER" -H bash -lc "cd ${APP_DIR} && php artisan migrate --force"
#
#
#
## System-Domain seeden, wenn eine echte Domain gesetzt wurde
#if [[ "${BASE_DOMAIN}" != "example.com" ]]; then
# sudo -u "$APP_USER" -H bash -lc "cd ${APP_DIR} && php artisan db:seed --class=SystemDomainSeeder --force"
#fi
#
#sudo -u "$APP_USER" -H bash -lc "cd ${APP_DIR} && php artisan config:cache"
#
## --- Frontend / Vite: einmaliger Build, wenn kein manifest.json vorhanden ---
#if [[ -f "${APP_DIR}/package.json" && ! -f "${APP_DIR}/public/build/manifest.json" ]]; then
# # Node nur installieren, wenn nicht vorhanden
# if ! command -v node >/dev/null 2>&1; then
# curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
# apt-get install -y nodejs
# fi
#
# # Dependencies installieren (bevorzugt ci, Fallback auf install)
# sudo -u "$APP_USER" -H bash -lc "cd ${APP_DIR} && (npm ci --no-audit --no-fund || npm install)"
#
# # Build ausführen (wenn kein "build"-Script, nutze npx vite)
# sudo -u "$APP_USER" -H bash -lc "cd ${APP_DIR} && (npm run build || npx --yes vite build)"
#fi
#
#sudo -u "$APP_USER" -H bash -lc "cd ${APP_DIR} && php artisan optimize:clear && php artisan config:cache"
#
#
## Rechte & Laravel Cache
#chown -R "$APP_USER":"$APP_GROUP" "$APP_DIR"
#chmod -R u=rwX,g=rwX,o=rX "$APP_DIR"
#install -d -m 0775 -o "$APP_USER" -g "$APP_GROUP" "$APP_DIR/storage" "$APP_DIR/bootstrap/cache"
#
#sudo -u "$APP_USER" -H bash -lc "cd ${APP_DIR} && php artisan optimize:clear && php artisan config:cache"
#
#relink_and_reload
#
#sudo systemctl restart php*-fpm || true