diff --git a/infra/install.sh b/infra/install.sh new file mode 100755 index 0000000..5033afd --- /dev/null +++ b/infra/install.sh @@ -0,0 +1,142 @@ +#!/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 " +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"