#!/usr/bin/env bash # # add-vhost.sh — Add an Apache virtual host on Ubuntu 24.04 # # Hybrid: pass args to skip prompts, omit them to be asked. # # sudo ./add-vhost.sh # fully interactive # sudo ./add-vhost.sh example.com # domain set, rest prompted # sudo ./add-vhost.sh example.com /var/www/ex # domain + root set # # Non-interactive (CI / scripted) — set env vars, prompts auto-skip: # sudo DOMAIN=example.com MAKE_DB=yes RUN_TLS=yes ./add-vhost.sh # set -euo pipefail PHP_VER="8.3" log() { printf '\n\033[1;32m==> %s\033[0m\n' "$*"; } warn() { printf '\033[1;33m!! %s\033[0m\n' "$*"; } die() { printf '\033[1;31mXX %s\033[0m\n' "$*" >&2; exit 1; } [[ $EUID -eq 0 ]] || die "Run as root: sudo bash $0" # Prompt only if stdin is a terminal; else rely on env/args (non-interactive). interactive() { [[ -t 0 ]]; } # ask VAR "Question" "default" — sets VAR from env, else arg-passed, else prompt, else default ask() { local __var="$1" __q="$2" __def="${3:-}" __cur="${!1:-}" [[ -n "$__cur" ]] && return # already set (env or earlier arg) if interactive; then local __ans read -rp "$__q${__def:+ [$__def]}: " __ans printf -v "$__var" '%s' "${__ans:-$__def}" else printf -v "$__var" '%s' "$__def" fi } ask_yn() { # ask_yn VAR "Question" default(yes/no) local __var="$1" __q="$2" __def="${3:-no}" __cur="${!1:-}" [[ -n "$__cur" ]] && return if interactive; then local __ans read -rp "$__q [$( [[ $__def == yes ]] && echo Y/n || echo y/N )]: " __ans __ans="${__ans:-$__def}" case "$__ans" in [Yy]*) printf -v "$__var" yes;; *) printf -v "$__var" no;; esac else printf -v "$__var" '%s' "$__def" fi } #───────────────────────────────────────────────────────────────────────────── # Gather inputs: positional args win, then env, then prompt #───────────────────────────────────────────────────────────────────────────── DOMAIN="${DOMAIN:-${1:-}}" WEB_ROOT="${WEB_ROOT:-${2:-}}" ask DOMAIN "Domain (e.g. example.com)" [[ -n "$DOMAIN" ]] || die "Domain required" # Basic sanity: letters/digits/dots/hyphens only [[ "$DOMAIN" =~ ^[A-Za-z0-9.-]+$ ]] || die "Invalid domain: $DOMAIN" ask WEB_ROOT "Web root" "/var/www/${DOMAIN}" ask ADMIN_EMAIL "Admin email (for TLS)" "admin@${DOMAIN}" ask_yn MAKE_DB "Create matching MySQL database + user?" no ask_yn RUN_TLS "Request Let's Encrypt TLS now (DNS must point here)?" no VHOST_FILE="/etc/apache2/sites-available/${DOMAIN}.conf" #───────────────────────────────────────────────────────────────────────────── log "Web root: ${WEB_ROOT}" #───────────────────────────────────────────────────────────────────────────── mkdir -p "$WEB_ROOT" if [[ ! -f "${WEB_ROOT}/index.html" && -z "$(ls -A "$WEB_ROOT" 2>/dev/null)" ]]; then echo "