Files
appfactory-tools/scripts/generate-caddyfile.sh
T

207 lines
4.3 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
CONFIG_FILE="/opt/appfactory/config/appfactory.env"
if [ -f "$CONFIG_FILE" ]; then
set -a
# shellcheck disable=SC1090
source "$CONFIG_FILE"
set +a
fi
APPFACTORY_DIR="${APPFACTORY_DIR:-/opt/appfactory}"
CATALOG_FILE="$APPFACTORY_DIR/apps/catalog.yml"
CADDY_FILE="$APPFACTORY_DIR/gateway/Caddyfile"
APPFACTORY_ENABLE_HTTPS="${APPFACTORY_ENABLE_HTTPS:-false}"
APPFACTORY_PORTAL_DOMAIN="${APPFACTORY_PORTAL_DOMAIN:-}"
APPFACTORY_GITEA_DOMAIN="${APPFACTORY_GITEA_DOMAIN:-}"
APPFACTORY_REGISTRY_DOMAIN="${APPFACTORY_REGISTRY_DOMAIN:-}"
mkdir -p "$(dirname "$CADDY_FILE")"
mkdir -p "$APPFACTORY_DIR/gateway/static"
write_site_header() {
local site="$1"
if [ "$APPFACTORY_ENABLE_HTTPS" = "true" ]; then
cat >> "$CADDY_FILE" <<EOF_CADDY
$site {
EOF_CADDY
else
cat >> "$CADDY_FILE" <<EOF_CADDY
http://$site {
EOF_CADDY
fi
}
write_app_routes() {
local target_file="$1"
if [ ! -f "$CATALOG_FILE" ]; then
return 0
fi
python3 - "$CATALOG_FILE" "$target_file" <<'PY'
import sys
catalog_file = sys.argv[1]
caddy_file = sys.argv[2]
apps = []
current = None
with open(catalog_file, "r", encoding="utf-8") as f:
for raw in f:
stripped = raw.strip()
if stripped.startswith("- id:"):
if current:
apps.append(current)
current = {"id": stripped.split(":", 1)[1].strip().strip('"')}
elif current and ":" in stripped:
key, value = stripped.split(":", 1)
current[key.strip()] = value.strip().strip('"')
if current:
apps.append(current)
with open(caddy_file, "a", encoding="utf-8") as f:
for app in apps:
app_id = app.get("id")
port = app.get("container_port") or app.get("port") or "8000"
if not app_id:
continue
f.write(f" handle_path /apps/{app_id}/* {{\n")
f.write(f" reverse_proxy {app_id}:{port}\n")
f.write(" }\n\n")
PY
}
write_portal_routes() {
local target_file="$1"
cat >> "$target_file" <<'EOF_ROUTES'
handle /health {
respond "AppFactory OK" 200
}
handle / {
redir /portal 302
}
handle /portal {
reverse_proxy appfactory-portal:9100
}
handle /portal/* {
uri strip_prefix /portal
reverse_proxy appfactory-portal:9100
}
handle /apps {
root * /srv/static
rewrite * /apps.html
file_server
}
EOF_ROUTES
write_app_routes "$target_file"
cat >> "$target_file" <<'EOF_ROUTES'
handle_path /webhook/* {
reverse_proxy appfactory-webhook:9000
}
handle_path /registry/* {
reverse_proxy appfactory-registry:5000
}
handle {
redir /portal 302
}
EOF_ROUTES
}
write_http_only_caddyfile() {
cat > "$CADDY_FILE" <<'EOF_CADDY'
:80 {
EOF_CADDY
write_portal_routes "$CADDY_FILE"
cat >> "$CADDY_FILE" <<'EOF_CADDY'
}
EOF_CADDY
}
write_domain_caddyfile() {
: > "$CADDY_FILE"
if [ -n "$APPFACTORY_PORTAL_DOMAIN" ]; then
write_site_header "$APPFACTORY_PORTAL_DOMAIN"
write_portal_routes "$CADDY_FILE"
cat >> "$CADDY_FILE" <<'EOF_CADDY'
}
EOF_CADDY
fi
if [ -n "$APPFACTORY_GITEA_DOMAIN" ]; then
write_site_header "$APPFACTORY_GITEA_DOMAIN"
cat >> "$CADDY_FILE" <<'EOF_CADDY'
handle /health {
respond "Gitea gateway OK" 200
}
handle {
reverse_proxy appfactory-gitea:3000
}
}
EOF_CADDY
fi
if [ -n "$APPFACTORY_REGISTRY_DOMAIN" ]; then
write_site_header "$APPFACTORY_REGISTRY_DOMAIN"
cat >> "$CADDY_FILE" <<'EOF_CADDY'
handle /health {
respond "Registry gateway OK" 200
}
handle /v2/* {
reverse_proxy appfactory-registry:5000
}
handle {
reverse_proxy appfactory-registry:5000
}
}
EOF_CADDY
fi
if [ ! -s "$CADDY_FILE" ]; then
write_http_only_caddyfile
fi
}
if [ -n "$APPFACTORY_PORTAL_DOMAIN" ] || [ -n "$APPFACTORY_GITEA_DOMAIN" ] || [ -n "$APPFACTORY_REGISTRY_DOMAIN" ]; then
write_domain_caddyfile
else
write_http_only_caddyfile
fi
echo "Generated: $CADDY_FILE"
if docker inspect appfactory-caddy >/dev/null 2>&1; then
docker exec appfactory-caddy caddy validate --config /etc/caddy/Caddyfile
docker exec appfactory-caddy caddy reload --config /etc/caddy/Caddyfile
else
echo "WARN: appfactory-caddy container not found, skipping validate/reload"
fi