README rewritten with the "ARGUS Enterprise Web Security Platform" positioning and full feature list. install.sh/update.sh now fetch deployment files from this Gitea repo (git-cloud.weboria.eu) instead of raw.githubusercontent.com, default install directory changed to /opt/argus, next-steps messaging aligned with the full onboarding journey (first-run wizard, proxy hosts, ANIS, policy center). Support link changed from GitHub Issues to the Weboria Support Portal. Deliberately NOT changed: docker-compose.yml's image: lines still pull from ghcr.io — Weboria's own private registry (registry.weboria.eu) resolves in DNS but has no registry service listening yet (confirmed via direct check), so switching now would break every real install. Both README and install.sh document this as a known, tracked gap rather than silently pointing at infrastructure that doesn't work. Same treatment for license-key validation during install — not implemented, since there's no licensing service to validate against yet.
167 lines
8.2 KiB
Bash
Executable File
167 lines
8.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# ARGUS Enterprise Web Security Platform — installer. Fetches the production
|
|
# compose stack, generates secrets, starts the platform, and prints your
|
|
# admin credentials.
|
|
#
|
|
# curl -fsSL https://git-cloud.weboria.eu/weboria/argus-installer/raw/branch/main/install.sh | bash
|
|
#
|
|
set -euo pipefail
|
|
|
|
REPO_RAW_BASE="https://git-cloud.weboria.eu/weboria/argus-installer/raw/branch/main"
|
|
INSTALL_DIR="${ARGUS_INSTALL_DIR:-/opt/argus}"
|
|
NETWORK_NAME="argus-network"
|
|
# The image registry is still ghcr.io (GitHub Container Registry) today —
|
|
# Weboria's own private registry (registry.weboria.eu) is provisioned but
|
|
# not yet serving images. docker-compose.yml's image: lines point at ghcr.io
|
|
# directly rather than a variable here, since that's the only registry that
|
|
# actually has published images right now; switching to registry.weboria.eu
|
|
# is a one-line change to those image: lines once it's live, not a rewrite.
|
|
|
|
# ── Output helpers ────────────────────────────────────────────────────────────
|
|
bold() { printf '\033[1m%s\033[0m\n' "$1"; }
|
|
info() { printf ' %s\n' "$1"; }
|
|
ok() { printf ' \033[32m✓\033[0m %s\n' "$1"; }
|
|
warn() { printf ' \033[33m!\033[0m %s\n' "$1"; }
|
|
fail() { printf ' \033[31m✗\033[0m %s\n' "$1" >&2; exit 1; }
|
|
|
|
bold "ARGUS Installer"
|
|
echo
|
|
|
|
# ── 1. OS detection (informational — Linux is the supported target) ──────────
|
|
OS="$(uname -s)"
|
|
case "$OS" in
|
|
Linux) ok "Detected Linux" ;;
|
|
Darwin) warn "Detected macOS — supported for local evaluation via Docker Desktop, not for production deployment." ;;
|
|
*) warn "Unrecognized OS ($OS) — proceeding, but only Linux is officially supported." ;;
|
|
esac
|
|
|
|
# ── 2. Docker / Compose availability ──────────────────────────────────────────
|
|
command -v docker >/dev/null 2>&1 || fail "Docker is not installed. Install Docker first: https://docs.docker.com/engine/install/"
|
|
docker info >/dev/null 2>&1 || fail "Docker is installed but not running (or this user lacks permission). Start Docker / add your user to the docker group, then re-run."
|
|
docker compose version >/dev/null 2>&1 || fail "Docker Compose v2 (the 'docker compose' plugin) is required. See https://docs.docker.com/compose/install/"
|
|
ok "Docker and Docker Compose are available"
|
|
|
|
# ── 3. Fetch deployment files ──────────────────────────────────────────────────
|
|
mkdir -p "$INSTALL_DIR/docker-socket-proxy"
|
|
cd "$INSTALL_DIR"
|
|
|
|
fetch() {
|
|
curl -fsSL "$REPO_RAW_BASE/$1" -o "$2" || fail "Failed to download $1"
|
|
}
|
|
|
|
fetch "docker-compose.yml" "docker-compose.yml"
|
|
fetch "docker-socket-proxy/haproxy.cfg.template" "docker-socket-proxy/haproxy.cfg.template"
|
|
for script in update.sh uninstall.sh healthcheck.sh backup.sh restore.sh; do
|
|
fetch "$script" "$script"
|
|
chmod +x "$script"
|
|
done
|
|
if [ ! -f .env ]; then
|
|
fetch ".env.example" ".env"
|
|
ok "Fetched deployment files into $INSTALL_DIR"
|
|
else
|
|
ok "Fetched compose file (kept your existing .env)"
|
|
fi
|
|
|
|
# ── 4. Generate secrets (first install only — never overwrite an existing .env) ──
|
|
if grep -q '^DB_PASSWORD=change-me-in-production' .env 2>/dev/null; then
|
|
DB_PASSWORD="$(openssl rand -base64 24 | tr -d '\n')"
|
|
sed -i.bak "s#^DB_PASSWORD=.*#DB_PASSWORD=${DB_PASSWORD}#" .env && rm -f .env.bak
|
|
ok "Generated a secure database password"
|
|
fi
|
|
|
|
# ── 5. Docker network ─────────────────────────────────────────────────────────
|
|
if docker network inspect "$NETWORK_NAME" >/dev/null 2>&1; then
|
|
ok "Docker network '$NETWORK_NAME' already exists"
|
|
else
|
|
docker network create "$NETWORK_NAME" >/dev/null
|
|
ok "Created Docker network '$NETWORK_NAME'"
|
|
fi
|
|
|
|
# ── 6. Pull and start ──────────────────────────────────────────────────────────
|
|
bold "Pulling images and starting ARGUS..."
|
|
docker compose pull
|
|
docker compose up -d
|
|
echo
|
|
|
|
# ── 7. Wait for the API to become healthy ─────────────────────────────────────
|
|
API_HOST_PORT="$(grep -oP '^API_HOST_PORT=\K.*' .env 2>/dev/null || true)"
|
|
API_HOST_PORT="${API_HOST_PORT:-9080}"
|
|
bold "Waiting for ARGUS to finish starting (this can take a few minutes on first boot)..."
|
|
READY=false
|
|
for _ in $(seq 1 90); do
|
|
if curl -fsS "http://127.0.0.1:${API_HOST_PORT}/health" >/dev/null 2>&1; then
|
|
READY=true
|
|
break
|
|
fi
|
|
sleep 5
|
|
done
|
|
if [ "$READY" != "true" ]; then
|
|
warn "ARGUS did not report healthy within 7.5 minutes."
|
|
warn "Check container status with: docker compose -f $INSTALL_DIR/docker-compose.yml ps"
|
|
warn "and logs with: docker compose -f $INSTALL_DIR/docker-compose.yml logs api"
|
|
exit 1
|
|
fi
|
|
ok "ARGUS is up"
|
|
|
|
# ── 8. Rotate the default admin credentials ───────────────────────────────────
|
|
ADMIN_USER="admin"
|
|
ADMIN_PASSWORD="Ax9!$(openssl rand -base64 24 | tr -dc 'A-Za-z0-9' | head -c 20)"
|
|
API_BASE="http://127.0.0.1:${API_HOST_PORT}/api/v1"
|
|
|
|
LOGIN_RESP="$(curl -fsS -X POST "${API_BASE}/auth/login" \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"username":"admin","password":"admin"}' 2>/dev/null || true)"
|
|
TOKEN="$(printf '%s' "${LOGIN_RESP}" | grep -oP '"token"\s*:\s*"\K[^"]+' || true)"
|
|
|
|
CREDS_ROTATED=false
|
|
if [ -n "$TOKEN" ]; then
|
|
CHANGE_RESP="$(curl -fsS -o /dev/null -w '%{http_code}' -X POST "${API_BASE}/auth/change-credentials" \
|
|
-H 'Content-Type: application/json' \
|
|
-H "Authorization: Bearer ${TOKEN}" \
|
|
-d "{\"current_password\":\"admin\",\"new_username\":\"${ADMIN_USER}\",\"new_password\":\"${ADMIN_PASSWORD}\",\"new_password_confirm\":\"${ADMIN_PASSWORD}\"}" 2>/dev/null || echo "000")"
|
|
if [ "$CHANGE_RESP" = "200" ]; then
|
|
CREDS_ROTATED=true
|
|
ok "Rotated the default admin password"
|
|
fi
|
|
fi
|
|
if [ "$CREDS_ROTATED" != "true" ]; then
|
|
warn "Could not auto-rotate admin credentials (already changed on a prior run?). Log in with your existing credentials, or admin/admin on a genuinely fresh install."
|
|
fi
|
|
|
|
# ── 9. Summary ─────────────────────────────────────────────────────────────────
|
|
UI_PORT="$(grep -oP '^UI_PORT=\K.*' .env 2>/dev/null || true)"
|
|
UI_PORT="${UI_PORT:-81}"
|
|
|
|
echo
|
|
bold "ARGUS Enterprise Web Security Platform has been successfully installed."
|
|
echo
|
|
info "Access URL: https://$(hostname -I 2>/dev/null | awk '{print $1}' || echo localhost):${UI_PORT} (accept the self-signed certificate)"
|
|
if [ "$CREDS_ROTATED" = "true" ]; then
|
|
info "Username: ${ADMIN_USER}"
|
|
info "Password: ${ADMIN_PASSWORD}"
|
|
warn "Save this password now — it is not stored anywhere and cannot be recovered."
|
|
else
|
|
info "Log in with your existing admin credentials."
|
|
fi
|
|
echo
|
|
bold "Next steps:"
|
|
info "1. Open the administration panel at the Access URL above."
|
|
if [ "$CREDS_ROTATED" != "true" ]; then
|
|
info "2. Complete the first-run setup wizard (regional settings, guided protection checklist)."
|
|
info "3. Change the initial administrator password if you haven't already."
|
|
else
|
|
info "2. Complete the first-run setup wizard — regional settings and a guided review of every"
|
|
info " protection module (your admin password was already rotated above)."
|
|
fi
|
|
info "4. Configure domains and reverse proxy hosts under Proxy Hosts."
|
|
info "5. Review the ANIS threat intelligence connection under Threat Intel — enabled by"
|
|
info " default against the public Community Edition hub, no license key required."
|
|
info "6. Review security policies in the Security Policy Center."
|
|
echo
|
|
info "Configuration: ${INSTALL_DIR}/.env and ${INSTALL_DIR}/docker-compose.yml"
|
|
info "Upgrade: cd ${INSTALL_DIR} && docker compose pull && docker compose up -d"
|
|
info "Backup: cd ${INSTALL_DIR} && ./backup.sh"
|
|
info "Docs/support: see README.md in this directory"
|
|
echo
|