#!/usr/bin/env bash SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" ENV_FILE="${REPO_ROOT}/.env" ENV_EXAMPLE_FILE="${REPO_ROOT}/.env.example" COMPOSE_FILE="${REPO_ROOT}/docker-compose.yml" log() { printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" } die() { printf 'ERROR: %s\n' "$*" >&2 exit 1 } require_cmd() { command -v "$1" >/dev/null 2>&1 || die "Required command not found: $1" } create_env_if_missing() { if [[ ! -f "${ENV_FILE}" ]]; then log "No .env found; creating .env from template" cp "${ENV_EXAMPLE_FILE}" "${ENV_FILE}" fi } load_env() { [[ -f "${ENV_EXAMPLE_FILE}" ]] || die "Missing template: ${ENV_EXAMPLE_FILE}" create_env_if_missing set -a source "${ENV_FILE}" set +a : "${GITEA_BASE_PATH:?GITEA_BASE_PATH is required in .env}" : "${GITEA_HTTP_PORT:?GITEA_HTTP_PORT is required in .env}" : "${GITEA_SSH_PORT:?GITEA_SSH_PORT is required in .env}" : "${GITEA_DOMAIN:?GITEA_DOMAIN is required in .env}" } compose() { docker compose --env-file "${ENV_FILE}" -f "${COMPOSE_FILE}" "$@" } wait_for_gitea_health() { local retries=45 local delay=4 local url="http://localhost:${GITEA_HTTP_PORT}/api/healthz" log "Waiting for Gitea health endpoint: ${url}" for ((i=1; i<=retries; i++)); do if curl -fsS "${url}" >/dev/null 2>&1; then log "Gitea health check passed" return 0 fi sleep "${delay}" done die "Gitea did not become healthy in time" } ufw_active() { command -v ufw >/dev/null 2>&1 || return 1 sudo ufw status | grep -q '^Status: active' } apply_firewall_rules() { local open_public_web="${1:-false}" if ufw_active; then log "Applying UFW rules for Gitea ports" sudo ufw allow "${GITEA_HTTP_PORT}/tcp" comment 'Gitea HTTP' sudo ufw allow "${GITEA_SSH_PORT}/tcp" comment 'Gitea SSH' if [[ "${open_public_web}" == "true" ]]; then log "Applying UFW rules for public reverse proxy ports" sudo ufw allow 80/tcp comment 'Gitea TLS HTTP-01' sudo ufw allow 443/tcp comment 'Gitea TLS HTTPS' fi else log "UFW not active; skipping firewall rule setup" fi } remove_firewall_rules() { local close_public_web="${1:-false}" if ufw_active; then log "Removing UFW rules for Gitea ports" sudo ufw --force delete allow "${GITEA_HTTP_PORT}/tcp" || true sudo ufw --force delete allow "${GITEA_SSH_PORT}/tcp" || true if [[ "${close_public_web}" == "true" ]]; then log "Removing UFW rules for public reverse proxy ports" sudo ufw --force delete allow 80/tcp || true sudo ufw --force delete allow 443/tcp || true fi else log "UFW not active; skipping firewall rule removal" fi }