From 1ba79a3d8de1f97e8cc1d3cedfbe291bf691ff84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Slavi=C5=A1a=20Are=C5=BEina?= <58952836+tremor021@users.noreply.github.com> Date: Fri, 7 Nov 2025 14:59:34 +0100 Subject: [PATCH] Pangolin: Add Traefik proxy (#8952) * Add Traefik * Update * Update --- ct/pangolin.sh | 92 +++++++++--------- frontend/public/json/pangolin.json | 2 +- install/pangolin-install.sh | 147 ++++++++++++++++++++++++++--- 3 files changed, 180 insertions(+), 61 deletions(-) diff --git a/ct/pangolin.sh b/ct/pangolin.sh index faa10e818..70add1fb0 100644 --- a/ct/pangolin.sh +++ b/ct/pangolin.sh @@ -21,52 +21,52 @@ color catch_errors function update_script() { - header_info - check_container_storage - check_container_resources - if [[ ! -d /opt/pangolin ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - - if check_for_gh_release "pangolin" "fosrl/pangolin"; then - msg_info "Stopping Service" - systemctl stop pangolin - systemctl stop gerbil - msg_info "Service stopped" - - msg_info "Creating backup" - tar -czf /opt/pangolin_config_backup.tar.gz -C /opt/pangolin config - msg_ok "Created backup" - - CLEAN_INSTALL=1 fetch_and_deploy_gh_release "pangolin" "fosrl/pangolin" "tarball" - CLEAN_INSTALL=1 fetch_and_deploy_gh_release "gerbil" "fosrl/gerbil" "singlefile" "latest" "/usr/bin" "gerbil_linux_amd64" - - msg_info "Updating Pangolin" - cd /opt/pangolin - $STD npm ci - $STD npm run set:sqlite - $STD npm run set:oss - rm -rf server/private - $STD npm run build:sqlite - $STD npm run build:cli - cp -R .next/standalone ./ - chmod +x ./dist/cli.mjs - cp server/db/names.json ./dist/names.json - msg_ok "Updated Pangolin" - - msg_info "Restoring config" - tar -xzf /opt/pangolin_config_backup.tar.gz -C /opt/pangolin --overwrite - rm -f /opt/pangolin_config_backup.tar.gz - msg_ok "Restored config" - - msg_info "Starting Services" - systemctl start pangolin - systemctl start gerbil - msg_ok "Started Services" - msg_ok "Updated successfully!" - fi + header_info + check_container_storage + check_container_resources + if [[ ! -d /opt/pangolin ]]; then + msg_error "No ${APP} Installation Found!" exit + fi + + if check_for_gh_release "pangolin" "fosrl/pangolin"; then + msg_info "Stopping Service" + systemctl stop pangolin + systemctl stop gerbil + msg_info "Service stopped" + + msg_info "Creating backup" + tar -czf /opt/pangolin_config_backup.tar.gz -C /opt/pangolin config + msg_ok "Created backup" + + CLEAN_INSTALL=1 fetch_and_deploy_gh_release "pangolin" "fosrl/pangolin" "tarball" + CLEAN_INSTALL=1 fetch_and_deploy_gh_release "gerbil" "fosrl/gerbil" "singlefile" "latest" "/usr/bin" "gerbil_linux_amd64" + + msg_info "Updating Pangolin" + cd /opt/pangolin + $STD npm ci + $STD npm run set:sqlite + $STD npm run set:oss + rm -rf server/private + $STD npm run build:sqlite + $STD npm run build:cli + cp -R .next/standalone ./ + chmod +x ./dist/cli.mjs + cp server/db/names.json ./dist/names.json + msg_ok "Updated Pangolin" + + msg_info "Restoring config" + tar -xzf /opt/pangolin_config_backup.tar.gz -C /opt/pangolin --overwrite + rm -f /opt/pangolin_config_backup.tar.gz + msg_ok "Restored config" + + msg_info "Starting Services" + systemctl start pangolin + systemctl start gerbil + msg_ok "Started Services" + msg_ok "Updated successfully!" + fi + exit } start @@ -76,4 +76,4 @@ description msg_ok "Completed Successfully!\n" echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" echo -e "${INFO}${YW} Access it using the following URL:${CL}" -echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3002${CL}" +echo -e "${TAB}${GATEWAY}${BGN}https://${CL}" diff --git a/frontend/public/json/pangolin.json b/frontend/public/json/pangolin.json index 8cd3c13b2..a153c8250 100644 --- a/frontend/public/json/pangolin.json +++ b/frontend/public/json/pangolin.json @@ -8,7 +8,7 @@ "type": "ct", "updateable": true, "privileged": false, - "interface_port": 3002, + "interface_port": 443, "documentation": "https://docs.pangolin.net/", "config_path": "/opt/pangolin/config/config.yml", "website": "https://pangolin.net/", diff --git a/install/pangolin-install.sh b/install/pangolin-install.sh index d0557963c..8581e2f6c 100644 --- a/install/pangolin-install.sh +++ b/install/pangolin-install.sh @@ -22,11 +22,16 @@ msg_ok "Installed Dependencies" NODE_VERSION="22" setup_nodejs fetch_and_deploy_gh_release "pangolin" "fosrl/pangolin" "tarball" fetch_and_deploy_gh_release "gerbil" "fosrl/gerbil" "singlefile" "latest" "/usr/bin" "gerbil_linux_amd64" +fetch_and_deploy_gh_release "traefik" "traefik/traefik" "prebuild" "latest" "/usr/bin" "traefik_v*_linux_amd64.tar.gz" + +read -rp "${TAB3}Enter your Pangolin URL (ex: https://pangolin.example.com): " pango_url +read -rp "${TAB3}Enter your email address: " pango_email msg_info "Setup Pangolin" IP_ADDR=$(hostname -I | awk '{print $1}') SECRET_KEY=$(openssl rand -base64 48 | tr -dc 'A-Za-z0-9' | head -c 32) cd /opt/pangolin +mkdir -p /opt/pangolin/config/{traefik,db,letsencrypt,logs} $STD npm ci $STD npm run set:sqlite $STD npm run set:oss @@ -46,30 +51,129 @@ mkdir -p /var/config cat </opt/pangolin/config/config.yml app: - dashboard_url: http://$IP_ADDR:3002 - log_level: debug + dashboard_url: "$pango_url" domains: domain1: - base_domain: example.com + base_domain: "$pango_url" + cert_resolver: "letsencrypt" server: - secret: $SECRET_KEY + secret: "$SECRET_KEY" gerbil: - base_endpoint: example.com - -orgs: - block_size: 24 - subnet_group: 100.90.137.0/20 + base_endpoint: "$pango_url" flags: require_email_verification: false - disable_signup_without_invite: true - disable_user_create_org: true - allow_raw_resources: true - enable_integration_api: true - enable_clients: true + disable_signup_without_invite: false + disable_user_create_org: false +EOF + +cat </opt/pangolin/config/traefik/traefik_config.yml +api: + insecure: true + dashboard: true + +providers: + http: + endpoint: "http://$IP_ADDR:3001/api/v1/traefik-config" + pollInterval: "5s" + file: + filename: "/opt/pangolin/config/traefik/dynamic_config.yml" + +experimental: + plugins: + badger: + moduleName: "github.com/fosrl/badger" + version: "v1.2.0" + +log: + level: "INFO" + format: "common" + +certificatesResolvers: + letsencrypt: + acme: + httpChallenge: + entryPoint: web + email: $pango_email + storage: "/opt/pangolin/config/letsencrypt/acme.json" + caServer: "https://acme-v02.api.letsencrypt.org/directory" + +entryPoints: + web: + address: ":80" + websecure: + address: ":443" + transport: + respondingTimeouts: + readTimeout: "30m" + http: + tls: + certResolver: "letsencrypt" + +serversTransport: + insecureSkipVerify: true + +ping: + entryPoint: "web" +EOF + +cat </opt/pangolin/config/traefik/dynamic_config.yml +http: + middlewares: + redirect-to-https: + redirectScheme: + scheme: https + + routers: + # HTTP to HTTPS redirect router + main-app-router-redirect: + rule: "Host(\`$pango_url\`)" + service: next-service + entryPoints: + - web + middlewares: + - redirect-to-https + + # Next.js router (handles everything except API and WebSocket paths) + next-router: + rule: "Host(\`$pango_url\`) && !PathPrefix(\`/api/v1\`)" + service: next-service + entryPoints: + - websecure + tls: + certResolver: letsencrypt + + # API router (handles /api/v1 paths) + api-router: + rule: "Host(\`$pango_url\`) && PathPrefix(\`/api/v1\`)" + service: api-service + entryPoints: + - websecure + tls: + certResolver: letsencrypt + + # WebSocket router + ws-router: + rule: "Host(\`$pango_url\`)" + service: api-service + entryPoints: + - websecure + tls: + certResolver: letsencrypt + + services: + next-service: + loadBalancer: + servers: + - url: "http://$IP_ADDR:3002" + + api-service: + loadBalancer: + servers: + - url: "http://$IP_ADDR:3000" EOF $STD npm run db:sqlite:generate $STD npm run db:sqlite:push @@ -122,6 +226,21 @@ RestartSec=10 WantedBy=multi-user.target EOF systemctl enable -q --now gerbil + +cat <<'EOF' >/etc/systemd/system/traefik.service +[Unit] +Description=Traefik is an open-source Edge Router that makes publishing your services a fun and easy experience + +[Service] +Type=notify +ExecStart=/usr/bin/traefik --configFile=/opt/pangolin/config/traefik/traefik_config.yml +Restart=on-failure +ExecReload=/bin/kill -USR1 \$MAINPID + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now traefik msg_ok "Created Services" motd_ssh