#!/bin/bash # One-time server setup for Post-ERG # Run this before the first deploy (or after a permission reset). # # Usage: ssh posterg "sudo bash /tmp/setup-server.sh" # Or: just setup-server # # What it does: # 1. Creates /var/www/posterg with correct ownership and permissions # 2. Ensures the deploy user is in the posterg group # 3. Sets sticky group bit (setgid) on all directories so new files # inherit the posterg group — required for rsync --chown to work set -e # ── Config ──────────────────────────────────────────────────────────────────── # DEPLOY_USER is passed explicitly by the justfile (read from ~/.ssh/config via # `ssh -G posterg`). Falls back to $SUDO_USER if run manually with sudo. DEPLOY_USER="${DEPLOY_USER:-${SUDO_USER}}" [ -n "$DEPLOY_USER" ] || die "DEPLOY_USER is not set. Pass it explicitly: sudo DEPLOY_USER=youruser bash $0" APP_DIR="/var/www/posterg" APP_GROUP="posterg" WEB_USER="www-data" # ───────────────────────────────────────────────────────────────────────────── RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' ok() { echo -e "${GREEN}✓${NC} $*"; } warn() { echo -e "${YELLOW}!${NC} $*"; } die() { echo -e "${RED}✗${NC} $*" >&2; exit 1; } [ "$EUID" -eq 0 ] || die "Run as root (sudo)" echo "🔧 Post-ERG Server Setup" echo "========================" echo "" # ── 1. Create posterg group ─────────────────────────────────────────────────── if ! getent group "$APP_GROUP" >/dev/null; then groupadd "$APP_GROUP" ok "Created group: $APP_GROUP" else ok "Group already exists: $APP_GROUP" fi # ── 2. Add deploy user and web user to group ────────────────────────────────── for user in "$DEPLOY_USER" "$WEB_USER"; do if id "$user" &>/dev/null; then if ! id -nG "$user" | grep -qw "$APP_GROUP"; then usermod -aG "$APP_GROUP" "$user" ok "Added $user to $APP_GROUP" else ok "$user already in $APP_GROUP" fi else warn "User $user not found — skipping" fi done # ── 3. Create app directory ─────────────────────────────────────────────────── mkdir -p "$APP_DIR" ok "Ensured $APP_DIR exists" # ── 4. Set ownership ────────────────────────────────────────────────────────── chown -R "$WEB_USER:$APP_GROUP" "$APP_DIR" ok "Ownership: $WEB_USER:$APP_GROUP on $APP_DIR" # ── 5. Set directory permissions with setgid ────────────────────────────────── # 2775 = rwxrwsr-x # - owner (www-data) and group (posterg) can read/write/execute # - setgid bit ensures new files/dirs inherit the posterg group # - this is what allows rsync --chown=www-data:posterg to succeed find "$APP_DIR" -type d -exec chmod 2775 {} \; ok "Directories: 2775 (setgid) on $APP_DIR/**" # ── 6. Set file permissions ─────────────────────────────────────────────────── find "$APP_DIR" -type f -exec chmod 664 {} \; ok "Files: 664 on $APP_DIR/**" # ── 7. Tighten storage ─────────────────────────────────────────────────────── if [ -d "$APP_DIR/storage" ]; then chmod 2775 "$APP_DIR/storage" find "$APP_DIR/storage" -name "*.db" -exec chmod 660 {} \; ok "Storage: 2775, databases: 660" fi echo "" echo -e "${GREEN}✓ Setup complete.${NC}" echo "" echo "Next steps:" echo " 1. Log out and back in as '$DEPLOY_USER' so group membership takes effect" echo " (or run: newgrp $APP_GROUP)" echo " 2. Run: just deploy" echo "" warn "If this is a fresh server, also run after first deploy:" echo " just deploy-db # push initial database" echo " just deploy-nginx # apply nginx config"