fix rsync permissions: setup-server.sh with setgid dirs, exclude .claude/.pi

This commit is contained in:
Pontoporeia
2026-03-02 15:32:44 +01:00
parent 52978aa658
commit e4b2205eac
4 changed files with 183 additions and 25 deletions

100
scripts/setup-server.sh Executable file
View File

@@ -0,0 +1,100 @@
#!/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"