mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-07-15 02:15:08 +02:00
07e31eb5bc
* Pangolin: Bump to 1.20.0 and harden SQLite migrations Bump the default Pangolin version to 1.20.0 in both CT and install scripts. Update the CT upgrade path to validate required 1.20.0 schema objects, clear stale versionMigrations markers when needed, retry migrations once, and abort with a clear error if the schema is still incomplete to avoid a broken runtime. * extend migration check... * another try... * bump pangolin to PSQL * remove migration paths * remove old migrations * use create_backup and restore_backup * Block Pangolin SQLite upgrades Update the Pangolin CT upgrade path to fail fast when PostgreSQL is not installed. The script now explains that upgrades to Pangolin 1.20.0+ require PostgreSQL and that SQLite data cannot be migrated automatically. * fix env * Update pangolin.sh * Update pangolin-install.sh
264 lines
6.4 KiB
Bash
264 lines
6.4 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
# Copyright (c) 2021-2026 community-scripts ORG
|
|
# Author: Slaviša Arežina (tremor021)
|
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
|
# Source: https://pangolin.net/ | Github: https://github.com/fosrl/pangolin
|
|
|
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
|
color
|
|
verb_ip6
|
|
catch_errors
|
|
setting_up_container
|
|
network_check
|
|
update_os
|
|
|
|
msg_info "Installing Dependencies"
|
|
$STD apt install -y \
|
|
build-essential \
|
|
iptables
|
|
msg_ok "Installed Dependencies"
|
|
|
|
NODE_VERSION="24" setup_nodejs
|
|
PG_VERSION="17" setup_postgresql
|
|
PG_DB_NAME="pangolin" PG_DB_USER="pangolin" setup_postgresql_db
|
|
PANGOLIN_VERSION="${PANGOLIN_VERSION:-1.20.0}"
|
|
fetch_and_deploy_gh_release "pangolin" "fosrl/pangolin" "tarball" "$PANGOLIN_VERSION"
|
|
fetch_and_deploy_gh_release "gerbil" "fosrl/gerbil" "singlefile" "latest" "/usr/bin" "gerbil_linux_$(arch_resolve)"
|
|
fetch_and_deploy_gh_release "traefik" "traefik/traefik" "prebuild" "latest" "/usr/bin" "traefik_v*_linux_$(arch_resolve).tar.gz"
|
|
|
|
read -rp "${TAB3}Enter your Pangolin URL (ex: https://pangolin.example.com): " pango_url
|
|
[[ "$pango_url" != https://* && "$pango_url" != http://* ]] && pango_url="https://${pango_url}"
|
|
read -rp "${TAB3}Enter your email address: " pango_email
|
|
|
|
msg_info "Setup Pangolin"
|
|
SECRET_KEY=$(openssl rand -base64 48 | tr -dc 'A-Za-z0-9' | head -c 32)
|
|
BADGER_VERSION=$(get_latest_github_release "fosrl/badger" "false")
|
|
cd /opt/pangolin
|
|
mkdir -p /opt/pangolin/config/{traefik,db,letsencrypt,logs}
|
|
$STD npm ci
|
|
$STD npm run set:pg
|
|
$STD npm run set:oss
|
|
rm -rf server/private
|
|
DATABASE_URL="postgresql://pangolin:${PG_DB_PASS}@localhost:5432/pangolin" $STD npm run db:generate
|
|
$STD npm run build
|
|
$STD npm run build:cli
|
|
cp -R .next/standalone ./
|
|
cp -r server/migrations ./dist/init
|
|
|
|
cat <<EOF >/usr/local/bin/pangctl
|
|
#!/bin/sh
|
|
cd /opt/pangolin
|
|
./dist/cli.mjs "$@"
|
|
EOF
|
|
chmod +x /usr/local/bin/pangctl ./dist/cli.mjs
|
|
cp server/db/names.json ./dist/names.json
|
|
cp server/db/ios_models.json ./dist/ios_models.json
|
|
cp server/db/mac_models.json ./dist/mac_models.json
|
|
mkdir -p /var/config
|
|
|
|
cat <<EOF >/opt/pangolin/config/config.yml
|
|
app:
|
|
dashboard_url: "$pango_url"
|
|
|
|
domains:
|
|
domain1:
|
|
base_domain: "$pango_url"
|
|
cert_resolver: "letsencrypt"
|
|
|
|
server:
|
|
secret: "$SECRET_KEY"
|
|
|
|
gerbil:
|
|
base_endpoint: "${pango_url#https://}"
|
|
|
|
flags:
|
|
require_email_verification: false
|
|
disable_signup_without_invite: false
|
|
disable_user_create_org: false
|
|
|
|
postgres:
|
|
connection_string: "postgresql://pangolin:${PG_DB_PASS}@localhost:5432/pangolin"
|
|
EOF
|
|
|
|
cat <<EOF >/opt/pangolin/config/traefik/traefik_config.yml
|
|
api:
|
|
insecure: true
|
|
dashboard: true
|
|
|
|
providers:
|
|
http:
|
|
endpoint: "http://$LOCAL_IP: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: "$BADGER_VERSION"
|
|
|
|
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 <<EOF >/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#https://}\`)"
|
|
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#https://}\`) && !PathPrefix(\`/api/v1\`)"
|
|
service: next-service
|
|
entryPoints:
|
|
- websecure
|
|
tls:
|
|
certResolver: letsencrypt
|
|
|
|
# API router (handles /api/v1 paths)
|
|
api-router:
|
|
rule: "Host(\`${pango_url#https://}\`) && PathPrefix(\`/api/v1\`)"
|
|
service: api-service
|
|
entryPoints:
|
|
- websecure
|
|
tls:
|
|
certResolver: letsencrypt
|
|
|
|
# WebSocket router
|
|
ws-router:
|
|
rule: "Host(\`${pango_url#https://}\`)"
|
|
service: api-service
|
|
entryPoints:
|
|
- websecure
|
|
tls:
|
|
certResolver: letsencrypt
|
|
|
|
services:
|
|
next-service:
|
|
loadBalancer:
|
|
servers:
|
|
- url: "http://$LOCAL_IP:3002"
|
|
|
|
api-service:
|
|
loadBalancer:
|
|
servers:
|
|
- url: "http://$LOCAL_IP:3000"
|
|
EOF
|
|
export ENVIRONMENT=prod
|
|
$STD node dist/migrations.mjs
|
|
|
|
. /etc/os-release
|
|
if [ "$VERSION_CODENAME" = "trixie" ]; then
|
|
echo "net.ipv4.ip_forward=1" >>/etc/sysctl.d/sysctl.conf
|
|
$STD sysctl -p /etc/sysctl.d/sysctl.conf
|
|
else
|
|
echo "net.ipv4.ip_forward=1" >>/etc/sysctl.conf
|
|
$STD sysctl -p /etc/sysctl.conf
|
|
fi
|
|
msg_ok "Setup Pangolin"
|
|
|
|
msg_info "Creating Services"
|
|
cat <<EOF >/etc/systemd/system/pangolin.service
|
|
[Unit]
|
|
Description=Pangolin Service
|
|
After=network.target postgresql.service
|
|
Wants=postgresql.service
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=root
|
|
Environment=NODE_ENV=production
|
|
Environment=ENVIRONMENT=prod
|
|
WorkingDirectory=/opt/pangolin
|
|
ExecStartPre=/usr/bin/node dist/migrations.mjs
|
|
ExecStart=/usr/bin/node --enable-source-maps dist/server.mjs
|
|
Restart=always
|
|
RestartSec=10
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
systemctl enable -q --now pangolin
|
|
|
|
cat <<EOF >/etc/systemd/system/gerbil.service
|
|
[Unit]
|
|
Description=Gerbil Service
|
|
After=network.target
|
|
Requires=pangolin.service
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=root
|
|
ExecStart=/usr/bin/gerbil --reachableAt=http://$LOCAL_IP:3004 --generateAndSaveKeyTo=/var/config/key --remoteConfig=http://$LOCAL_IP:3001/api/v1/
|
|
Restart=always
|
|
RestartSec=10
|
|
|
|
[Install]
|
|
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
|
|
Wants=network-online.target
|
|
After=network-online.target
|
|
|
|
[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
|
|
customize
|
|
cleanup_lxc
|