mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-09-25 01:53:03 +02:00
feat(provision): idempotent setup for local dev and remote server
This commit is contained in:
Executable
+58
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env bash
|
||||
# Provision (or verify) the server-side .env / APP_KEY on the xamxam host.
|
||||
#
|
||||
# Behavior:
|
||||
# - If remote /var/www/xamxam/.env already contains APP_KEY=... → DO NOT
|
||||
# overwrite it. Print a clear message and exit 0.
|
||||
# - If the file exists but has no APP_KEY → append a fresh key.
|
||||
# - If the file does not exist → create it with a fresh key.
|
||||
# Always fixes ownership (www-data:xamxam) and perms (640) after any write.
|
||||
#
|
||||
# Run from local via: just provision-server
|
||||
# (uses the `xamxam` SSH host as defined in ~/.ssh/config / deploy recipes)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
HOST="${1:-xamxam}"
|
||||
ENV_PATH="/var/www/xamxam/.env"
|
||||
|
||||
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; RED='\033[0;31m'; NC='\033[0m'
|
||||
ok() { printf "${GREEN}✓${NC} %s\n" "$*"; }
|
||||
warn() { printf "${YELLOW}!${NC} %s\n" "$*"; }
|
||||
info() { printf "${CYAN}→${NC} %s\n" "$*"; }
|
||||
die() { printf "${RED}✗${NC} %s\n" "$*" >&2; exit 1; }
|
||||
|
||||
info "Checking ${ENV_PATH} on ${HOST}…"
|
||||
|
||||
# Does the file exist AND already have an APP_KEY value?
|
||||
if ssh "$HOST" "test -f '$ENV_PATH' && grep -qE '^\s*APP_KEY=\S+' '$ENV_PATH'"; then
|
||||
ok "APP_KEY already present in ${ENV_PATH} on ${HOST} — NOT overwriting it."
|
||||
warn "Keeping the existing key so encrypted credentials stay decryptable."
|
||||
warn "If you intend to rotate the key, use: just reencrypt-password <new_base64_key>"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
info "APP_KEY absent — generating one on the server…"
|
||||
|
||||
# Build the new key value once, server-side.
|
||||
if ssh "$HOST" "command -v php >/dev/null 2>&1"; then
|
||||
KEY="$(ssh "$HOST" "php -r 'echo base64_encode(random_bytes(32));'")"
|
||||
else
|
||||
die "php not found on ${HOST} — cannot generate APP_KEY remotely."
|
||||
fi
|
||||
|
||||
# Append or create, always via root (app dir is not writable by www-data).
|
||||
if ssh "$HOST" "test -f '$ENV_PATH'"; then
|
||||
warn "${ENV_PATH} exists but has no APP_KEY — appending (existing lines untouched)."
|
||||
ssh "$HOST" "{ printf '\nAPP_KEY=%s\n' '$KEY'; } | sudo tee -a '$ENV_PATH' >/dev/null"
|
||||
ok "APP_KEY appended to ${ENV_PATH}."
|
||||
else
|
||||
ssh "$HOST" "echo 'APP_KEY=${KEY}' | sudo tee '$ENV_PATH' >/dev/null"
|
||||
info "Created ${ENV_PATH} with a new APP_KEY."
|
||||
fi
|
||||
|
||||
# Normalise ownership + perms regardless of which branch wrote.
|
||||
ssh "$HOST" "sudo chown www-data:xamxam '$ENV_PATH' && sudo chmod 640 '$ENV_PATH'"
|
||||
ok "Ownership www-data:xamxam, permissions 640."
|
||||
|
||||
ok "Server APP_KEY ready."
|
||||
Executable
+76
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env bash
|
||||
# One-shot provisioning for a fresh XAMXAM clone (local dev).
|
||||
#
|
||||
# Steps:
|
||||
# 1. Ensure app/.env exists with a valid APP_KEY (NEVER overwrites an existing key).
|
||||
# 2. Install dependencies: composer install + npm ci.
|
||||
# 3. Create/update the SQLite DB from schema + migrations (just migrate).
|
||||
# 4. Report the first-admin status (and how to set a password, if unset).
|
||||
#
|
||||
# Idempotent: safe to re-run on an already-provisioned clone.
|
||||
# Run via: just provision
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; RED='\033[0;31m'; NC='\033[0m'
|
||||
ok() { printf "${GREEN}✓${NC} %s\n" "$*"; }
|
||||
warn() { printf "${YELLOW}!${NC} %s\n" "$*"; }
|
||||
info() { printf "${CYAN}→${NC} %s\n" "$*"; }
|
||||
die() { printf "${RED}✗${NC} %s\n" "$*" >&2; exit 1; }
|
||||
|
||||
cd "$(cd "$(dirname "$0")/.." && pwd)"
|
||||
|
||||
ENV_FILE="app/.env"
|
||||
|
||||
# ── 1. APP_KEY / .env ──────────────────────────────────────────────────────────
|
||||
info "Checking $ENV_FILE for APP_KEY…"
|
||||
key_exists() {
|
||||
[ -f "$ENV_FILE" ] && grep -qE '^\s*APP_KEY=\S+' "$ENV_FILE"
|
||||
}
|
||||
|
||||
if [ -f "$ENV_FILE" ] && key_exists; then
|
||||
ok "APP_KEY already present in $ENV_FILE — NOT overwriting it."
|
||||
warn "Keeping the existing key so encrypted credentials stay decryptable."
|
||||
elif [ -f "$ENV_FILE" ]; then
|
||||
warn "$ENV_FILE exists but has no APP_KEY — appending one (existing lines untouched)."
|
||||
printf '\nAPP_KEY=%s\n' "$(php -r 'echo base64_encode(random_bytes(32));')" >> "$ENV_FILE"
|
||||
chmod 600 "$ENV_FILE"
|
||||
ok "APP_KEY appended to $ENV_FILE."
|
||||
elif command -v php >/dev/null 2>&1; then
|
||||
printf 'APP_KEY=%s\n' "$(php -r 'echo base64_encode(random_bytes(32));')" > "$ENV_FILE"
|
||||
chmod 600 "$ENV_FILE"
|
||||
ok "Created $ENV_FILE with a new APP_KEY."
|
||||
else
|
||||
warn "PHP not found — skipping automatic .env creation."
|
||||
warn "Create $ENV_FILE manually with: APP_KEY=<base64-encoded 32 random bytes>"
|
||||
fi
|
||||
|
||||
# ── 2. Dependencies ─────────────────────────────────────────────────────────────
|
||||
info "Installing Composer dependencies…"
|
||||
command -v composer >/dev/null 2>&1 || die "composer not found on PATH. Install it first."
|
||||
composer install
|
||||
|
||||
info "Installing npm dependencies…"
|
||||
command -v npm >/dev/null 2>&1 || die "npm not found on PATH. Install it first."
|
||||
npm ci
|
||||
|
||||
# ── 3. Database ─────────────────────────────────────────────────────────────────
|
||||
info "Creating/updating the SQLite database…"
|
||||
command -v just >/dev/null 2>&1 || die "just not found on PATH. Install it first (or run scripts/migrate.sh)."
|
||||
just migrate
|
||||
|
||||
# ── 4. First admin password ─────────────────────────────────────────────────────
|
||||
DB="app/storage/xamxam.db"
|
||||
if [ -f "$DB" ] && command -v sqlite3 >/dev/null 2>&1; then
|
||||
HASH_LEN="$(sqlite3 "$DB" "SELECT length(value) FROM site_settings WHERE key='admin_password_hash';" 2>/dev/null || true)"
|
||||
if [ "$HASH_LEN" = "0" ] || [ -z "$HASH_LEN" ]; then
|
||||
warn "No admin password is set yet — /admin/ is currently UNAUTHENTICATED (open)."
|
||||
info "Set one now at http://127.0.0.1:8000/admin/account (or the production admin) to secure it."
|
||||
else
|
||||
ok "Admin password is already set."
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
printf "${GREEN}✓${NC} Provisioning complete. Start the dev server with: ${CYAN}just dev${NC}\n"
|
||||
echo " Public: http://127.0.0.1:8000/ Admin: http://127.0.0.1:8000/admin/"
|
||||
Reference in New Issue
Block a user