From fd7398be9f84b79c70009a18894d1c3af6f07fd6 Mon Sep 17 00:00:00 2001 From: xtcnet Date: Thu, 19 Mar 2026 12:56:05 +0700 Subject: [PATCH] Refactor installer menus and update project paths --- AI_CONTEXT.md | 2 +- README.md | 38 ++-- docker/Dockerfile | 8 +- install.sh | 534 +++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 508 insertions(+), 74 deletions(-) diff --git a/AI_CONTEXT.md b/AI_CONTEXT.md index 8e59c6b..95da08f 100644 --- a/AI_CONTEXT.md +++ b/AI_CONTEXT.md @@ -10,7 +10,7 @@ WireGuard management module and some project-specific admin features. Canonical repository: -- `https://src.d3v.ac/xtcnet/D3V-Server` +- `https://src.d3v.ac/d3v/D3V-Server` Treat that repository as the source of truth for this project. If another upstream is mentioned, assume it is a historical ancestor or reference, diff --git a/README.md b/README.md index d8b5cec..1df2e23 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -# D3V-NPMWG — xGat3 + WireGuard VPN +# D3V Gateway — Reverse Proxy + WireGuard VPN -A powerful, all-in-one Docker container that combines **xGat3** (reverse proxy with SSL) and **WireGuard VPN** management in a single web interface. +A lightweight all-in-one Docker deployment that combines reverse proxy management with SSL and **WireGuard VPN** in a single web interface. ## Features -### xGat3 +### Gateway - Reverse proxy management with SSL (Let's Encrypt) - Proxy hosts, redirection hosts, streams, and 404 hosts - Access control lists and audit logging @@ -29,24 +29,30 @@ A powerful, all-in-one Docker container that combines **xGat3** (reverse proxy w ## Quick Start ```bash -curl -sSL https://src.d3v.ac/xtcnet/D3V-Server/raw/branch/master/install.sh -o install.sh +curl -sSL https://src.d3v.ac/d3v/D3V-Server/raw/branch/master/install.sh -o install.sh chmod +x install.sh sudo ./install.sh ``` -**Menu options:** -- `1` Install D3V-NPMWG -- `2` Uninstall D3V-NPMWG -- `3` Uninstall D3V-NPMWG + Docker (Purge) +**Main menu:** +- `1` Gateway +- `2` Blog +- `3` Forgejo +- `4` Status / Logs / Health Check +- `5` Exit + +**Gateway submenu:** +- `1` Install Gateway +- `2` Uninstall Gateway +- `3` Uninstall Gateway + Docker (Purge) - `4` Reset Admin Password -- `5` Update D3V-NPMWG +- `5` Update Gateway - `6` Manage Custom Stream Ports - `7` Toggle Admin Port 81 (Block/Unblock) -- `8` Forgejo → Install / Uninstall / Update / Install Runner / Uninstall Runner You can also run commands directly: ```bash -sudo ./install.sh {install|uninstall|purge|reset|update|manage-ports|toggle-port|forgejo} +sudo ./install.sh {gateway|gateway-install|gateway-uninstall|gateway-purge|gateway-reset|gateway-update|manage-ports|toggle-port|blog|blog-install|blog-update|blog-uninstall|forgejo|runner-update|ops} ``` --- @@ -56,7 +62,7 @@ sudo ./install.sh {install|uninstall|purge|reset|update|manage-ports|toggle-port ```yaml services: d3v-npmwg: - image: src.d3v.ac/xtcnet/d3v-server:latest + image: src.d3v.ac/d3v/d3v-server:latest container_name: d3v-npmwg restart: unless-stopped cap_add: @@ -107,16 +113,16 @@ services: ## Building from Source ```bash -git clone https://src.d3v.ac/xtcnet/D3V-Server.git +git clone https://src.d3v.ac/d3v/D3V-Server.git cd D3V-Server cd frontend && yarn install && yarn locale-compile && yarn build && cd .. -docker build -t d3v-npmwg -f docker/Dockerfile . +docker build -t d3v-gateway -f docker/Dockerfile . ``` ### CI/CD -Pushes to `master` that touch `backend/`, `frontend/`, or `docker/` automatically build and push the Docker image to `src.d3v.ac/xtcnet/d3v-server:latest` via Forgejo Actions. +Pushes to `master` that touch `backend/`, `frontend/`, or `docker/` automatically build and push the Docker image to `src.d3v.ac/d3v/d3v-server:latest` via Forgejo Actions. --- @@ -129,7 +135,7 @@ Pushes to `master` that touch `backend/`, `frontend/`, or `docker/` automaticall ## Credits -- [xGat3](https://github.com/NginxProxyManager/nginx-proxy-manager) — Original proxy manager +- [Nginx Proxy Manager](https://github.com/NginxProxyManager/nginx-proxy-manager) — Original proxy manager - [wg-easy](https://github.com/wg-easy/wg-easy) — WireGuard management inspiration ## License diff --git a/docker/Dockerfile b/docker/Dockerfile index a0badc3..7c5f13c 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -76,7 +76,7 @@ ENTRYPOINT [ "/init" ] LABEL org.label-schema.schema-version="1.0" \ org.label-schema.license="MIT" \ - org.label-schema.name="d3v-npmwg" \ - org.label-schema.description="xGat3 : xGat3 + WireGuard VPN Manager" \ - org.label-schema.url="https://github.com/xtcnet/D3V-NPMWG" \ - org.label-schema.cmd="docker run --rm -ti --cap-add=NET_ADMIN --cap-add=SYS_MODULE d3v-npmwg:latest" + org.label-schema.name="d3v-gateway" \ + org.label-schema.description="D3V Gateway: Reverse Proxy + WireGuard VPN Manager" \ + org.label-schema.url="https://src.d3v.ac/d3v/D3V-Server" \ + org.label-schema.cmd="docker run --rm -ti --cap-add=NET_ADMIN --cap-add=SYS_MODULE src.d3v.ac/d3v/d3v-server:latest" diff --git a/install.sh b/install.sh index 3433555..54b6b97 100644 --- a/install.sh +++ b/install.sh @@ -2,15 +2,20 @@ set -e # ============================================================ -# D3V-NPMWG Installer for Ubuntu/Debian -# xGat3 + WireGuard VPN -# https://src.d3v.ac/xtcnet/D3V-Server +# D3V Gateway Installer for Ubuntu/Debian +# Reverse Proxy + WireGuard VPN +# https://src.d3v.ac/d3v/D3V-Server # ============================================================ INSTALL_DIR="/opt/d3v-npmwg" COMPOSE_FILE="${INSTALL_DIR}/docker-compose.yml" CONTAINER_NAME="d3v-npmwg" -IMAGE_NAME="src.d3v.ac/xtcnet/d3v-server:latest" +IMAGE_NAME="src.d3v.ac/d3v/d3v-server:latest" + +BLOG_INSTALL_DIR="/opt/blog" +BLOG_COMPOSE_FILE="${BLOG_INSTALL_DIR}/docker-compose.yml" +BLOG_CONTAINER_NAME="d3v-blog" +BLOG_IMAGE="nginx:alpine" FORGEJO_INSTALL_DIR="/opt/forgejo" FORGEJO_COMPOSE_FILE="${FORGEJO_INSTALL_DIR}/docker-compose.yml" @@ -39,7 +44,7 @@ log_err() { echo -e "${RED}[✗]${NC} $1"; } separator() { echo -e "${GREEN}=================================================================${NC}"; } self_update() { - local remote_url="https://src.d3v.ac/xtcnet/D3V-Server/raw/branch/master/install.sh" + local remote_url="https://src.d3v.ac/d3v/D3V-Server/raw/branch/master/install.sh" local tmp tmp=$(mktemp) || return if curl -fsSL -m 10 "$remote_url" -o "$tmp" 2>/dev/null; then @@ -255,19 +260,19 @@ ensure_docker_network() { } # ----------------------------------------------------------- -# 2. Install D3V-NPMWG +# 2. Install Gateway # ----------------------------------------------------------- do_install() { require_root if [ -d "$INSTALL_DIR" ]; then - log_warn "D3V-NPMWG is already installed at ${INSTALL_DIR}." + log_warn "Gateway is already installed at ${INSTALL_DIR}." log_warn "Use the Update option to pull the latest image, or Uninstall first." return fi separator - echo -e "${BOLD} D3V-NPMWG Installation${NC}" + echo -e "${BOLD} Gateway Installation${NC}" separator echo "" @@ -338,7 +343,7 @@ do_install() { if docker ps --format '{{.Names}}' | grep -q "$CONTAINER_NAME"; then echo "" separator - echo -e "${GREEN}${BOLD} D3V-NPMWG INSTALLED SUCCESSFULLY!${NC}" + echo -e "${GREEN}${BOLD} GATEWAY INSTALLED SUCCESSFULLY!${NC}" separator echo -e " ${CYAN}Web Admin UI${NC} : ${BOLD}http://${wg_host}:81${NC}" echo -e " ${CYAN}HTTP Proxy${NC} : port 80" @@ -354,17 +359,17 @@ do_install() { } # ----------------------------------------------------------- -# 3. Uninstall D3V-NPMWG +# 3. Uninstall Gateway # ----------------------------------------------------------- do_uninstall() { require_root if [ ! -d "$INSTALL_DIR" ]; then - log_warn "D3V-NPMWG is not installed at ${INSTALL_DIR}." + log_warn "Gateway is not installed at ${INSTALL_DIR}." return fi - log_warn "This will stop and remove D3V-NPMWG and ALL its data." + log_warn "This will stop and remove Gateway and ALL its data." read -rp "$(echo -e "${RED}Are you sure? (y/N): ${NC}")" confirm if [[ ! "$confirm" =~ ^[yY]$ ]]; then echo "Cancelled." @@ -379,7 +384,7 @@ do_uninstall() { log_step "Removing ${INSTALL_DIR}..." rm -rf "$INSTALL_DIR" - log_ok "D3V-NPMWG uninstalled." + log_ok "Gateway uninstalled." } # ----------------------------------------------------------- @@ -448,13 +453,13 @@ do_reset_password() { } # ----------------------------------------------------------- -# 6. Update D3V-NPMWG +# 6. Update Gateway # ----------------------------------------------------------- do_update() { require_root if [ ! -d "$INSTALL_DIR" ]; then - log_err "D3V-NPMWG is not installed. Install it first." + log_err "Gateway is not installed. Install it first." return fi @@ -481,7 +486,7 @@ do_update() { log_step "Recreating containers..." $dc up -d - log_ok "D3V-NPMWG updated." + log_ok "Gateway updated." log_step "Cleaning old images..." docker image prune -f > /dev/null 2>&1 @@ -573,7 +578,207 @@ do_toggle_port_81() { } # ----------------------------------------------------------- -# Forgejo — Install / Uninstall / Update +# Blog - Install / Uninstall +# ----------------------------------------------------------- +do_blog_install() { + require_root + + if [ -d "$BLOG_INSTALL_DIR" ]; then + log_warn "Blog is already installed at ${BLOG_INSTALL_DIR}." + log_warn "Uninstall it first if you want to recreate it." + return + fi + + separator + echo -e "${BOLD} Hugo Blog Static Host Installation${NC}" + separator + echo "" + + install_deps + echo "" + + ensure_docker_network + + log_step "Creating ${BLOG_INSTALL_DIR}..." + mkdir -p "${BLOG_INSTALL_DIR}/public" + log_ok "Directory created." + + if [ ! -f "${BLOG_INSTALL_DIR}/public/index.html" ]; then + log_step "Creating placeholder blog homepage..." + cat > "${BLOG_INSTALL_DIR}/public/index.html" < + + + + + Blog is ready + + + +

Hugo blog host is installed

+

This container is ready to serve your generated Hugo site.

+

Deploy your blog build output into /opt/blog/public.

+

Then create a Proxy Host in Nginx Proxy Manager pointing to ${BLOG_CONTAINER_NAME} on port 80.

+ + +HTML + log_ok "Placeholder page created." + fi + + log_step "Generating blog docker-compose.yml..." + cat > "$BLOG_COMPOSE_FILE" </dev/null || true + cd / + + log_step "Removing ${BLOG_INSTALL_DIR}..." + rm -rf "$BLOG_INSTALL_DIR" + log_ok "Blog uninstalled." +} + +do_blog_update() { + require_root + + if [ ! -d "$BLOG_INSTALL_DIR" ]; then + log_err "Blog is not installed. Install it first." + return + fi + + separator + echo -e "${BOLD} Hugo Blog Static Host Update${NC}" + separator + echo "" + + install_deps + ensure_docker_network + + local dc + dc=$(get_compose_cmd) + cd "$BLOG_INSTALL_DIR" || return + + log_step "Pulling latest blog image..." + $dc pull + log_ok "Image pulled." + + log_step "Recreating blog container..." + $dc up -d + log_ok "Blog updated." + + log_step "Cleaning old images..." + docker image prune -f > /dev/null 2>&1 + log_ok "Done." +} + +show_blog_menu() { + while true; do + echo "" + separator + echo -e "${BOLD} Blog Manager${NC}" + separator + echo " 1) Install Blog" + echo " 2) Update Blog" + echo " 3) Uninstall Blog" + echo " 4) Back" + separator + read -rp " Select [1-4]: " choice + echo "" + case "$choice" in + 1) do_blog_install ;; + 2) do_blog_update ;; + 3) do_blog_uninstall ;; + 4) return ;; + *) log_err "Invalid option." ;; + esac + done +} + +# ----------------------------------------------------------- +# Forgejo - Install / Uninstall / Update # ----------------------------------------------------------- do_forgejo_install() { require_root @@ -594,17 +799,17 @@ do_forgejo_install() { ensure_docker_network - # Ensure D3V-NPMWG is on d3v-net (runtime + persistent in compose) + # Ensure Gateway is on d3v-net (runtime + persistent in compose) if [ -f "$COMPOSE_FILE" ]; then if ! grep -q "d3v-net" "$COMPOSE_FILE"; then - log_step "Updating D3V-NPMWG compose to join '${DOCKER_NETWORK}'..." + log_step "Updating Gateway compose to join '${DOCKER_NETWORK}'..." local current_wg_host="" current_wg_host=$(grep -E 'WG_HOST:' "$COMPOSE_FILE" | awk -F'"' '{print $2}') [ -z "$current_wg_host" ] && current_wg_host=$(detect_public_ip) cd "$INSTALL_DIR" generate_docker_compose "$current_wg_host" $(get_compose_cmd) up -d --no-recreate 2>/dev/null || true - log_ok "D3V-NPMWG compose updated." + log_ok "Gateway compose updated." fi # Connect running container immediately (no restart needed) if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then @@ -858,6 +1063,60 @@ do_forgejo_runner_install() { separator } +do_forgejo_runner_update() { + require_root + + if ! docker ps -a --format '{{.Names}}' | grep -q "^${FORGEJO_RUNNER_CONTAINER}$"; then + log_err "Forgejo Runner is not installed." + return + fi + + log_step "Reading current Forgejo Runner configuration..." + local runner_env + runner_env=$(docker inspect -f '{{range .Config.Env}}{{println .}}{{end}}' "${FORGEJO_RUNNER_CONTAINER}" 2>/dev/null || true) + + local forgejo_url + local runner_token + local runner_name + local runner_labels + forgejo_url=$(echo "$runner_env" | grep '^GITEA_INSTANCE_URL=' | head -n1 | cut -d= -f2-) + runner_token=$(echo "$runner_env" | grep '^GITEA_RUNNER_REGISTRATION_TOKEN=' | head -n1 | cut -d= -f2-) + runner_name=$(echo "$runner_env" | grep '^GITEA_RUNNER_NAME=' | head -n1 | cut -d= -f2-) + runner_labels=$(echo "$runner_env" | grep '^GITEA_RUNNER_LABELS=' | head -n1 | cut -d= -f2-) + + if [ -z "$forgejo_url" ] || [ -z "$runner_token" ]; then + log_err "Could not read the existing Forgejo Runner configuration." + log_err "Uninstall and install the runner again to re-register it." + return + fi + + runner_name="${runner_name:-$(hostname)-runner}" + runner_labels="${runner_labels:-ubuntu-latest:docker://catthehacker/ubuntu:act-22.04,ubuntu-22.04:docker://catthehacker/ubuntu:act-22.04}" + + log_step "Pulling latest Forgejo Runner image..." + docker pull "${FORGEJO_RUNNER_IMAGE}" + log_ok "Image pulled." + + log_step "Recreating Forgejo Runner container..." + docker stop "${FORGEJO_RUNNER_CONTAINER}" 2>/dev/null || true + docker rm "${FORGEJO_RUNNER_CONTAINER}" 2>/dev/null || true + + mkdir -p "$FORGEJO_RUNNER_DIR" + + docker run -d \ + --name "${FORGEJO_RUNNER_CONTAINER}" \ + --restart unless-stopped \ + -e GITEA_INSTANCE_URL="${forgejo_url}" \ + -e GITEA_RUNNER_REGISTRATION_TOKEN="${runner_token}" \ + -e GITEA_RUNNER_NAME="${runner_name}" \ + -e GITEA_RUNNER_LABELS="${runner_labels}" \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v "${FORGEJO_RUNNER_DIR}:/data" \ + "${FORGEJO_RUNNER_IMAGE}" > /dev/null + + log_ok "Forgejo Runner updated." +} + do_forgejo_runner_uninstall() { require_root @@ -889,18 +1148,176 @@ show_forgejo_menu() { echo " 2) Uninstall Forgejo" echo " 3) Update Forgejo" echo " 4) Install Runner" - echo " 5) Uninstall Runner" - echo " 6) Back" + echo " 5) Update Runner" + echo " 6) Uninstall Runner" + echo " 7) Back" separator - read -rp " Select [1-6]: " choice + read -rp " Select [1-7]: " choice echo "" case "$choice" in 1) do_forgejo_install ;; 2) do_forgejo_uninstall ;; 3) do_forgejo_update ;; 4) do_forgejo_runner_install ;; - 5) do_forgejo_runner_uninstall ;; - 6) return ;; + 5) do_forgejo_runner_update ;; + 6) do_forgejo_runner_uninstall ;; + 7) return ;; + *) log_err "Invalid option." ;; + esac + done +} + +# ----------------------------------------------------------- +# Gateway Manager Menu +# ----------------------------------------------------------- +show_gateway_menu() { + while true; do + echo "" + separator + echo -e "${BOLD} Gateway Manager${NC}" + separator + echo " 1) Install Gateway" + echo " 2) Uninstall Gateway" + echo " 3) Uninstall Gateway + Docker (Purge)" + echo " 4) Reset Admin Password" + echo " 5) Update Gateway" + echo " 6) Manage Custom Stream Ports" + echo " 7) Toggle Admin Port 81 (Block/Unblock)" + echo " 8) Back" + separator + read -rp " Select [1-8]: " choice + echo "" + case "$choice" in + 1) do_install ;; + 2) do_uninstall ;; + 3) do_purge ;; + 4) do_reset_password ;; + 5) do_update ;; + 6) do_manage_ports ;; + 7) do_toggle_port_81 ;; + 8) return ;; + *) log_err "Invalid option." ;; + esac + done +} + +# ----------------------------------------------------------- +# Status / Logs / Health Check +# ----------------------------------------------------------- +show_container_status() { + local label="$1" + local name="$2" + + separator + echo -e "${BOLD} ${label} Status${NC}" + separator + if docker ps -a --format '{{.Names}}' | grep -q "^${name}$"; then + docker ps -a --filter "name=^${name}$" --format "table {{.Names}}\t{{.Status}}\t{{.Image}}\t{{.Ports}}" + else + log_warn "${label} container is not installed." + fi +} + +show_service_logs() { + local label="$1" + local name="$2" + + separator + echo -e "${BOLD} ${label} Logs (last 60 lines)${NC}" + separator + if docker ps -a --format '{{.Names}}' | grep -q "^${name}$"; then + docker logs --tail 60 "$name" 2>&1 || true + else + log_warn "${label} container is not installed." + fi +} + +run_health_checks() { + separator + echo -e "${BOLD} Health Check Summary${NC}" + separator + + log_step "Docker daemon" + if docker info > /dev/null 2>&1; then + log_ok "Docker daemon is running." + else + log_err "Docker daemon is not reachable." + fi + + log_step "Shared Docker network (${DOCKER_NETWORK})" + if docker network ls --format '{{.Name}}' | grep -q "^${DOCKER_NETWORK}$"; then + log_ok "Network ${DOCKER_NETWORK} exists." + else + log_warn "Network ${DOCKER_NETWORK} does not exist." + fi + + log_step "Gateway container" + if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then + log_ok "Gateway is running." + elif docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then + log_warn "Gateway exists but is not running." + else + log_warn "Gateway is not installed." + fi + + log_step "Blog container" + if docker ps --format '{{.Names}}' | grep -q "^${BLOG_CONTAINER_NAME}$"; then + log_ok "Blog is running." + elif docker ps -a --format '{{.Names}}' | grep -q "^${BLOG_CONTAINER_NAME}$"; then + log_warn "Blog exists but is not running." + else + log_warn "Blog is not installed." + fi + + log_step "Forgejo container" + if docker ps --format '{{.Names}}' | grep -q "^${FORGEJO_CONTAINER_NAME}$"; then + log_ok "Forgejo is running." + elif docker ps -a --format '{{.Names}}' | grep -q "^${FORGEJO_CONTAINER_NAME}$"; then + log_warn "Forgejo exists but is not running." + else + log_warn "Forgejo is not installed." + fi + + log_step "Forgejo Runner container" + if docker ps --format '{{.Names}}' | grep -q "^${FORGEJO_RUNNER_CONTAINER}$"; then + log_ok "Forgejo Runner is running." + elif docker ps -a --format '{{.Names}}' | grep -q "^${FORGEJO_RUNNER_CONTAINER}$"; then + log_warn "Forgejo Runner exists but is not running." + else + log_warn "Forgejo Runner is not installed." + fi +} + +show_operations_menu() { + while true; do + echo "" + separator + echo -e "${BOLD} Status / Logs / Health Check${NC}" + separator + echo " 1) Gateway Status" + echo " 2) Blog Status" + echo " 3) Forgejo Status" + echo " 4) Runner Status" + echo " 5) Gateway Logs" + echo " 6) Blog Logs" + echo " 7) Forgejo Logs" + echo " 8) Runner Logs" + echo " 9) Health Check Summary" + echo " 10) Back" + separator + read -rp " Select [1-10]: " choice + echo "" + case "$choice" in + 1) show_container_status "Gateway" "$CONTAINER_NAME" ;; + 2) show_container_status "Blog" "$BLOG_CONTAINER_NAME" ;; + 3) show_container_status "Forgejo" "$FORGEJO_CONTAINER_NAME" ;; + 4) show_container_status "Forgejo Runner" "$FORGEJO_RUNNER_CONTAINER" ;; + 5) show_service_logs "Gateway" "$CONTAINER_NAME" ;; + 6) show_service_logs "Blog" "$BLOG_CONTAINER_NAME" ;; + 7) show_service_logs "Forgejo" "$FORGEJO_CONTAINER_NAME" ;; + 8) show_service_logs "Forgejo Runner" "$FORGEJO_RUNNER_CONTAINER" ;; + 9) run_health_checks ;; + 10) return ;; *) log_err "Invalid option." ;; esac done @@ -913,30 +1330,22 @@ show_menu() { while true; do echo "" separator - echo -e "${BOLD} D3V-NPMWG Installation Manager${NC}" + echo -e "${BOLD} Server Installation Manager${NC}" separator - echo " 1) Install D3V-NPMWG" - echo " 2) Uninstall D3V-NPMWG" - echo " 3) Uninstall D3V-NPMWG + Docker (Purge)" - echo " 4) Reset Admin Password" - echo " 5) Update D3V-NPMWG" - echo " 6) Manage Custom Stream Ports" - echo " 7) Toggle Admin Port 81 (Block/Unblock)" - echo " 8) Forgejo" - echo " 9) Exit" + echo " 1) Gateway" + echo " 2) Blog" + echo " 3) Forgejo" + echo " 4) Status / Logs / Health Check" + echo " 5) Exit" separator - read -rp " Select [1-9]: " choice + read -rp " Select [1-5]: " choice echo "" case "$choice" in - 1) do_install ;; - 2) do_uninstall ;; - 3) do_purge ;; - 4) do_reset_password ;; - 5) do_update ;; - 6) do_manage_ports ;; - 7) do_toggle_port_81 ;; - 8) show_forgejo_menu ;; - 9) echo "Bye!"; exit 0 ;; + 1) show_gateway_menu ;; + 2) show_blog_menu ;; + 3) show_forgejo_menu ;; + 4) show_operations_menu ;; + 5) echo "Bye!"; exit 0 ;; *) log_err "Invalid option." ;; esac done @@ -946,14 +1355,26 @@ show_help() { echo "Usage: $0 [command]" echo "" echo "Commands:" - echo " install Install D3V-NPMWG and dependencies" - echo " uninstall Remove D3V-NPMWG (keeps Docker)" - echo " purge Remove D3V-NPMWG AND Docker" + echo " install Install Gateway and dependencies" + echo " uninstall Remove Gateway (keeps Docker)" + echo " purge Remove Gateway AND Docker" echo " reset Reset web admin password" echo " update Pull latest image and restart" echo " manage-ports Add or remove custom exposed Stream TCP/UDP ports" echo " toggle-port Block or unblock external access to Admin UI (Port 81) using iptables" + echo " gateway Open Gateway submenu" + echo " gateway-install Install Gateway and dependencies" + echo " gateway-uninstall Remove Gateway (keeps Docker)" + echo " gateway-purge Remove Gateway AND Docker" + echo " gateway-reset Reset Gateway admin password" + echo " gateway-update Pull latest Gateway image and restart" + echo " blog Open Blog submenu (install/update/uninstall)" + echo " blog-install Install lightweight static blog hosting for Hugo" + echo " blog-update Update lightweight static blog hosting" + echo " blog-uninstall Remove lightweight static blog hosting" echo " forgejo Open Forgejo submenu (install/uninstall/update)" + echo " runner-update Update Forgejo Runner while keeping its configuration" + echo " ops Open Status / Logs / Health Check submenu" echo " help Show this help" echo "" echo "Run without arguments to open the interactive menu." @@ -968,14 +1389,21 @@ if [ "$#" -eq 0 ]; then show_menu else case "$1" in - install) do_install ;; - uninstall) do_uninstall ;; - purge) do_purge ;; - reset) do_reset_password ;; - update) do_update ;; + install|gateway-install) do_install ;; + uninstall|gateway-uninstall) do_uninstall ;; + purge|gateway-purge) do_purge ;; + reset|gateway-reset) do_reset_password ;; + update|gateway-update) do_update ;; manage-ports) do_manage_ports ;; toggle-port) do_toggle_port_81 ;; + gateway) show_gateway_menu ;; + blog) show_blog_menu ;; + blog-install) do_blog_install ;; + blog-update) do_blog_update ;; + blog-uninstall) do_blog_uninstall ;; forgejo) show_forgejo_menu ;; + runner-update) do_forgejo_runner_update ;; + ops) show_operations_menu ;; help|-h|--help) show_help ;; *) log_err "Unknown command: $1"