Files
TA-Deployment-Broker/install.sh
T
2026-07-28 21:11:54 -05:00

162 lines
5.6 KiB
Bash
Executable File

#!/usr/bin/env bash
set -Eeuo pipefail
DEPLOY_ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
cd "$DEPLOY_ROOT"
fail() {
printf 'ERROR: %s\n' "$*" >&2
exit 1
}
prompt_default() {
local prompt="$1"
local fallback="$2"
local value
printf '%s [%s]: ' "$prompt" "$fallback" >&2
read -r value
printf '%s' "${value:-$fallback}"
}
valid_hostname() {
[[ "$1" =~ ^[A-Za-z0-9]([A-Za-z0-9.-]*[A-Za-z0-9])?$ &&
"$1" != *..* ]]
}
valid_port() {
[[ "$1" =~ ^[0-9]+$ ]] && (( 10#$1 >= 1 && 10#$1 <= 65535 ))
}
[[ $# -eq 0 ]] || fail "usage: ./install.sh"
[[ ! -e .env ]] ||
fail ".env already exists; use ./manage.sh instead of overwriting this deployment"
for required_file in \
compose.yaml \
compose.http.yaml \
compose.tls.yaml \
deploy/nginx/templates/http.conf.template \
deploy/nginx/templates/tls.conf.template; do
[[ -f "$required_file" ]] ||
fail "repository file is missing or not a regular file: ${required_file}"
done
for command_name in docker openssl; do
command -v "$command_name" >/dev/null 2>&1 ||
fail "$command_name is required"
done
docker compose version >/dev/null 2>&1 ||
fail "Docker Compose v2 is required"
docker info >/dev/null 2>&1 ||
fail "the Docker daemon is unavailable or this user cannot access it"
printf '\nTAPM Deployment Access installer\n'
printf 'This creates the initial environment and starts Git behind Nginx.\n'
printf 'The broker starts only after its Git OAuth and package credentials are configured.\n\n'
broker_domain="$(prompt_default 'Broker hostname' 'tapm.example.com')"
gitea_domain="$(prompt_default 'Git hostname' 'git.example.com')"
valid_hostname "$broker_domain" || fail "invalid broker hostname"
valid_hostname "$gitea_domain" || fail "invalid Git hostname"
[[ "$broker_domain" != "$gitea_domain" ]] ||
fail "broker and Git hostnames must be different"
http_port="$(prompt_default 'VM port mapped to Nginx HTTP port 80' '8680')"
https_port="$(prompt_default 'VM port mapped to Nginx HTTPS port 443' '8643')"
valid_port "$http_port" || fail "invalid HTTP port"
valid_port "$https_port" || fail "invalid HTTPS port"
[[ "$http_port" != "$https_port" ]] || fail "HTTP and HTTPS ports must differ"
ssl_mode="$(prompt_default 'SSL mode (none, letsencrypt, or custom)' 'none')"
case "$ssl_mode" in
none)
public_scheme=http
public_port_suffix=":${http_port}"
letsencrypt_email=''
certificate_dir="./config/letsencrypt/live/${broker_domain}"
;;
letsencrypt)
public_scheme=https
public_port_suffix=''
printf 'Let'\''s Encrypt account email: '
read -r letsencrypt_email
[[ "$letsencrypt_email" == *@* ]] || fail "a valid email is required"
certificate_dir="./config/letsencrypt/live/${broker_domain}"
;;
custom)
public_scheme=https
public_port_suffix=''
letsencrypt_email=''
certificate_dir='./config/ssl'
;;
*)
fail "SSL mode must be none, letsencrypt, or custom"
;;
esac
cookie_secret="$(openssl rand -base64 48)"
umask 077
{
printf 'BROKER_DOMAIN=%s\n' "$broker_domain"
printf 'GITEA_DOMAIN=%s\n' "$gitea_domain"
printf 'GITEA_PUBLIC_URL=%s://%s%s/\n' "$public_scheme" "$gitea_domain" "$public_port_suffix"
printf 'LETSENCRYPT_EMAIL=%s\n' "$letsencrypt_email"
printf 'HTTP_PORT=%s\n' "$http_port"
printf 'HTTPS_PORT=%s\n\n' "$https_port"
printf 'BROKER_DIRECT_PORT=8080\n'
printf 'GITEA_DIRECT_PORT=3000\n'
printf 'GITEA_DIRECT_ROOT_URL=http://localhost:3000/\n\n'
printf 'SSL_MODE=%s\n' "$ssl_mode"
printf 'SSL_CERTIFICATE_DIR=%s\n' "$certificate_dir"
printf 'SSL_CERTIFICATE_FILE=fullchain.pem\n'
printf 'SSL_CERTIFICATE_KEY_FILE=privkey.pem\n\n'
printf 'TAPM_DATABASE_DSN=file:/data/tapm.db?_pragma=busy_timeout(5000)&_pragma=foreign_keys(1)&_pragma=journal_mode(WAL)\n'
printf 'TAPM_PUBLIC_URL=%s://%s%s\n' "$public_scheme" "$broker_domain" "$public_port_suffix"
printf 'TAPM_GITEA_URL=%s://%s%s\n' "$public_scheme" "$gitea_domain" "$public_port_suffix"
printf 'TAPM_GITEA_INTERNAL_URL=http://gitea:3000\n'
printf 'TAPM_GITEA_CLIENT_ID=\n'
printf 'TAPM_GITEA_CLIENT_SECRET=\n'
printf 'TAPM_GITEA_PACKAGE_OWNER=TAI\n'
printf 'TAPM_GITEA_PACKAGE_USERNAME=\n'
printf 'TAPM_GITEA_PACKAGE_TOKEN=\n'
printf 'TAPM_GITEA_PACKAGE_WRITE_USERNAME=\n'
printf 'TAPM_GITEA_PACKAGE_WRITE_TOKEN=\n'
printf 'TAPM_ALLOWED_GITEA_USERS=taiadmin\n'
printf 'TAPM_COOKIE_SECRET=%s\n' "$cookie_secret"
printf 'TAPM_DEFAULT_DURATION=7d\n'
printf 'TAPM_DEFAULT_HOST_LIMIT=3\n'
printf 'TAPM_MAX_HOST_LIMIT=25\n'
printf 'TAPM_MAX_UPLOAD_BYTES=1073741824\n'
printf 'TAPM_TRUST_PROXY_HEADERS=true\n'
printf 'TAPM_DISPLAY_TIME_ZONE=America/Chicago\n'
} >.env
chmod 600 .env
printf '\nInitial configuration saved to %s/.env.\n' "$DEPLOY_ROOT"
if [[ "$ssl_mode" == "custom" ]]; then
printf 'Place the certificate and key in config/ssl, then run ./manage.sh bootstrap.\n'
printf 'Git has not been started yet.\n'
exit 0
fi
"${DEPLOY_ROOT}/manage.sh" bootstrap
printf '\nInitial Git deployment is running.\n'
printf 'Git URL: %s://%s%s\n' "$public_scheme" "$gitea_domain" "$public_port_suffix"
if [[ "$ssl_mode" == "none" ]]; then
printf 'This is HTTP-only testing mode. Do not expose it publicly.\n'
printf 'Make both hostnames resolve to this VM or its test-forwarding address.\n'
fi
printf '\nNext steps:\n'
printf ' 1. Run ./manage.sh create-admin\n'
printf ' 2. Sign in to Git and create the organization, package users/tokens,\n'
printf ' and OAuth application documented in docs/deployment.md.\n'
printf ' 3. Run ./manage.sh configure-broker\n'
printf ' 4. Run ./manage.sh start\n'
if [[ "$ssl_mode" == "none" ]]; then
printf ' 5. Later, after DNS and public 80/443 forwarding are ready, run:\n'
printf ' ./manage.sh set-ssl letsencrypt\n'
printf ' ./manage.sh bootstrap\n'
printf ' ./manage.sh start\n'
fi