Hostityourself/infra/install.sh
Claude e80c3dc9a4
feat: add install.sh for fresh Raspberry Pi setup
Covers everything that was done manually on the Pi:
- apt packages: podman, aardvark-dns, sqlite3, git, uidmap, python3-pip
- podman-compose via pip (to ~/.local/bin)
- rclone (optional, prompted)
- .env creation from template with prompted values and generated passwords
- git upstream tracking for auto-update
- hands off to start.sh at the end

Safe to re-run — all steps are idempotent.

https://claude.ai/code/session_01FKCW3FDjNFj6jve4niMFXH
2026-03-27 13:52:28 +00:00

142 lines
6.1 KiB
Bash
Executable file

#!/usr/bin/env bash
# install.sh — one-time setup for a fresh Raspberry Pi.
#
# Run this once after cloning the repo:
# cd ~/Hostityourself && ./infra/install.sh
#
# What it does:
# 1. Installs system packages (podman, aardvark-dns, sqlite3, git, uidmap)
# 2. Installs podman-compose (via pip, into ~/.local/bin)
# 3. Installs rclone (for off-site backups — optional)
# 4. Creates .env from the template and prompts for required values
# 5. Runs infra/start.sh to build and launch the stack
#
# Safe to re-run — all steps are idempotent.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
log() { echo; echo "$*"; }
info() { echo " $*"; }
ok() { echo "$*"; }
echo "╔══════════════════════════════════════════╗"
echo "║ HostItYourself — installer ║"
echo "╚══════════════════════════════════════════╝"
# ── 1. System packages ─────────────────────────────────────────────────────────
log "Installing system packages…"
sudo apt-get update -qq
sudo apt-get install -y \
podman \
aardvark-dns \
sqlite3 \
git \
uidmap \
python3-pip \
python3-venv \
curl
ok "System packages installed."
# ── 2. podman-compose ──────────────────────────────────────────────────────────
log "Checking podman-compose…"
if command -v podman-compose &>/dev/null; then
ok "podman-compose already installed ($(podman-compose --version 2>&1 | head -1))."
else
info "Installing podman-compose via pip…"
pip3 install --user podman-compose
ok "podman-compose installed to ~/.local/bin"
fi
# Ensure ~/.local/bin is in PATH for this session and future logins.
if ! echo "$PATH" | grep -q "$HOME/.local/bin"; then
export PATH="$HOME/.local/bin:$PATH"
fi
PROFILE="$HOME/.bashrc"
if ! grep -q '\.local/bin' "$PROFILE" 2>/dev/null; then
echo 'export PATH="$HOME/.local/bin:$PATH"' >> "$PROFILE"
info "Added ~/.local/bin to PATH in $PROFILE"
fi
# ── 3. rclone (optional) ───────────────────────────────────────────────────────
log "rclone (used for off-site backups)…"
if command -v rclone &>/dev/null; then
ok "rclone already installed ($(rclone --version 2>&1 | head -1))."
else
read -r -p " Install rclone? [y/N] " _RCLONE
if [[ "${_RCLONE,,}" == "y" ]]; then
curl -fsSL https://rclone.org/install.sh | sudo bash
ok "rclone installed."
info "Configure a remote later with: rclone config"
info "Then set HIY_BACKUP_REMOTE in .env"
else
info "Skipped. Install later with: curl https://rclone.org/install.sh | sudo bash"
fi
fi
# ── 4. .env setup ──────────────────────────────────────────────────────────────
log "Setting up .env…"
ENV_FILE="$REPO_ROOT/.env"
ENV_EXAMPLE="$SCRIPT_DIR/.env.example"
if [ -f "$ENV_FILE" ]; then
ok ".env already exists — skipping (edit manually if needed)."
else
cp "$ENV_EXAMPLE" "$ENV_FILE"
info "Created .env from template. Filling in required values…"
echo
# Helper: prompt for a value and write it into .env.
set_env() {
local key="$1" prompt="$2" default="$3" secret="${4:-}"
local current
current=$(grep "^${key}=" "$ENV_FILE" | cut -d= -f2- || echo "")
if [ -z "$current" ] || [ "$current" = "changeme" ] || [ "$current" = "" ]; then
if [ -n "$secret" ]; then
read -r -s -p " ${prompt} [${default}]: " _VAL; echo
else
read -r -p " ${prompt} [${default}]: " _VAL
fi
_VAL="${_VAL:-$default}"
# Replace the line in .env (works on both macOS and Linux).
sed -i "s|^${key}=.*|${key}=${_VAL}|" "$ENV_FILE"
fi
}
set_env "DOMAIN_SUFFIX" "Your domain (e.g. example.com)" "yourdomain.com"
set_env "ACME_EMAIL" "Email for Let's Encrypt notices" ""
set_env "HIY_ADMIN_USER" "Dashboard admin username" "admin"
set_env "HIY_ADMIN_PASS" "Dashboard admin password" "$(openssl rand -hex 12)" "secret"
set_env "POSTGRES_PASSWORD" "Postgres admin password" "$(openssl rand -hex 16)" "secret"
set_env "FORGEJO_DB_PASSWORD" "Forgejo DB password" "$(openssl rand -hex 16)" "secret"
set_env "FORGEJO_DOMAIN" "Forgejo domain (e.g. git.example.com)" "git.yourdomain.com"
echo
ok ".env written to $ENV_FILE"
info "Review it with: cat $ENV_FILE"
fi
# ── 5. Git remote check ────────────────────────────────────────────────────────
log "Checking git remote…"
cd "$REPO_ROOT"
REMOTE_URL=$(git remote get-url origin 2>/dev/null || echo "")
if [ -n "$REMOTE_URL" ]; then
ok "Git remote: $REMOTE_URL"
else
info "No git remote configured — auto-update will not work."
info "Set one with: git remote add origin <url>"
fi
# Ensure the tracking branch is set so auto-update.sh can compare commits.
BRANCH=$(git rev-parse --abbrev-ref HEAD)
if ! git rev-parse --abbrev-ref --symbolic-full-name '@{u}' &>/dev/null; then
info "Setting upstream tracking branch…"
git branch --set-upstream-to="origin/$BRANCH" "$BRANCH" 2>/dev/null || true
fi
# ── 6. Launch the stack ────────────────────────────────────────────────────────
log "Running start.sh to build and launch the stack…"
echo
exec "$SCRIPT_DIR/start.sh"