Pangolin on Your VPS Series
    Part 2 of 6

    VPS Provisioning, DNS, Firewall & Installation

    Server hardening, Docker install, DNS records, UFW firewall, and the interactive Pangolin installer from start to finish.

    30 minutes
    1 KVM VPS

    VPS Provisioning

    Log into your RamNode control panel and create a new KVM VPS:

    • OS: Ubuntu 22.04 LTS or 24.04 LTS (most tested, longest support)
    • Starter (1 vCPU, 1 GB): Adequate for personal use with a handful of services
    • Standard (1–2 vCPU, 2 GB): Comfortable for small teams (~25 users), multiple sites
    • Storage: 20 GB is more than enough — Pangolin uses SQLite by default

    Note your VPS's public IPv4 address for DNS configuration.

    Initial Server Hardening

    Update the system
    ssh root@<your-vps-ip>
    apt update && apt upgrade -y
    Create a non-root user
    adduser pangolin
    usermod -aG sudo pangolin
    rsync --archive --chown=pangolin:pangolin ~/.ssh /home/pangolin
    Harden SSH — edit /etc/ssh/sshd_config
    PermitRootLogin no
    PasswordAuthentication no
    PubkeyAuthentication yes
    Restart SSH
    systemctl restart sshd

    Open a second terminal and verify you can log in as the new user before closing your root session.

    Install Docker

    Install Docker Engine
    curl -fsSL https://get.docker.com | sh
    usermod -aG docker pangolin

    Log out and back in, then verify: docker run hello-world

    DNS Configuration

    Pangolin validates DNS before continuing. Set up these records:

    TypeNameValue
    Ayourdomain.com<your-vps-ip>
    Apangolin.yourdomain.com<your-vps-ip>
    A*.yourdomain.com<your-vps-ip>

    Cloudflare Users

    Set proxy status to DNS only (gray cloud) during initial setup. Let's Encrypt needs to reach your VPS directly. You can switch to proxied after certs are provisioned.

    Verify DNS propagation
    dig +short pangolin.yourdomain.com
    # Should return your VPS IP

    Firewall Configuration

    PortProtocolPurpose
    22TCPSSH
    80TCPHTTP / Let's Encrypt
    443TCPHTTPS (all resources)
    51820UDPWireGuard (Newt tunnels)
    21820UDPWireGuard (Pangolin clients)
    Configure UFW
    ufw allow 22/tcp
    ufw allow 80/tcp
    ufw allow 443/tcp
    ufw allow 51820/udp
    ufw allow 21820/udp
    ufw enable
    ufw status

    If your RamNode plan has a network-level firewall in the control panel, configure the same rules there too.

    Installing Pangolin

    Download and run the installer
    su - pangolin
    mkdir -p ~/pangolin && cd ~/pangolin
    curl -fsSL https://static.pangolin.net/get-installer.sh | bash
    sudo ./installer

    Installer Walkthrough

    • Edition: Community Edition (unless you have a commercial license)
    • Base Domain: Your root domain without subdomain prefix (e.g. yourdomain.com)
    • Dashboard Domain: Accept default (pangolin.yourdomain.com) or customize
    • Let's Encrypt Email: A real email — becomes your initial admin login
    • Install Gerbil: Yes — needed for WireGuard tunneling
    • Enable SMTP: Optional — skip for now, configure later
    • Install CrowdSec: Optional — covered in Part 6

    The installer pulls three Docker images (pangolin, gerbil, traefik), generates docker-compose.yml, and starts the stack in 2–5 minutes.

    Post-Installation Setup

    Verify containers are running
    cd ~/pangolin
    docker compose ps

    You should see three containers in the running state: pangolin, gerbil, and traefik.

    Common Issues

    • Let's Encrypt errors in Traefik logs: DNS hasn't propagated yet, or port 80 is blocked. Traefik retries automatically.
    • Gerbil exits immediately: Port conflict on 51820 UDP, or WireGuard kernel module isn't available (OpenVZ instead of KVM).
    • Pangolin database errors: Check file permissions in the config directory.

    Complete Initial Setup

    Navigate to https://pangolin.yourdomain.com/auth/initial-setup. Set your admin password and create your first organization.

    Directory Structure

    Pangolin installation layout
    ~/pangolin/
    ├── docker-compose.yml       # Container definitions
    ├── installer                # The installer binary (keep for updates)
    ├── config/
    │   ├── pangolin/
    │   │   └── config.yml       # Main Pangolin configuration
    │   ├── gerbil/
    │   │   └── config.yml       # Gerbil WireGuard configuration
    │   └── traefik/
    │       ├── traefik.yml      # Traefik static configuration
    │       └── dynamic/         # Dynamic routing rules (managed by Pangolin)
    └── data/
        └── pangolin/
            └── db.sqlite3       # Pangolin database (back this up)

    Auto-Start Configuration

    Verify restart policy and Docker auto-start
    grep restart ~/pangolin/docker-compose.yml
    # Should show: restart: unless-stopped
    
    sudo systemctl is-enabled docker
    # Should output: enabled
    
    # If not enabled:
    sudo systemctl enable docker
    Test with a reboot
    sudo reboot
    # After reboot:
    docker compose -f ~/pangolin/docker-compose.yml ps