Deploy Pangolin manually using Podman Quadlets (rootless) without the automated installer
Try free on Pangolin Cloud
Fastest way to get started with Pangolin using the hosted control plane. No credit card required.
This guide walks through a manual deployment using the same file layout the installer generates from install/config/* in the Pangolin source tree. Use it if you want the installer’s defaults, but you want to create and maintain the files yourself.This guide assumes you already have a Linux server with Podman installed and has been tested on Debian 13.5 with Podman version 5.4.2.
UDP ports 51820 and 21820 open if you are using tunneling
If you do not want tunneling, see Without Tunneling. In that mode you will skip the gerbil service and expose Traefik directly.
base domain is the parent domain you will attach resources to, such as example.com. dashboard hostname is the specific hostname for the Pangolin UI and API, such as pangolin.example.com.
The following files are created later by the running services or added only when you enable optional features:
config/db/db.sqlite is created by Pangolin on first startup.
config/key is created by Gerbil when tunneling is enabled.
config/GeoLite2-Country.mmdb is optional and only needed for geo-blocking. It is not downloaded by the running services in a manual install; download it manually before enabling geo-blocking.
mkdir -p ~/.config/containers/systemd # only needed if this is the first time you're running rootless Podman containerscd ~/.config/containers/systemdmkdir -p config/db config/letsencrypt config/traefik/logs
[Unit]Description=Pangolin PodWants=network-online.targetAfter=network-online.target[Pod]PodName=servicesNetwork=pastaPublishPort=51820:51820/udpPublishPort=21820:21820/udpPublishPort=443:443# Uncomment the line below if you enable HTTP/3 in Traefik.# PublishPort=443:443/udpPublishPort=80:80[Service]Restart=always[Install]WantedBy=default.target
This is the installer’s default community layout with Gerbil enabled. If you want to pin releases instead of using latest, replace the image tags with the versions you intend to run.
2
Create config/traefik/traefik_config.yml
This file configures Traefik’s providers, Badger plugin, Let’s Encrypt resolver, entry points, logs, and health check endpoint.
Traefik stores Let’s Encrypt certificates at /letsencrypt/acme.json inside the container. The container file mounts that path from ./config/letsencrypt, so Traefik will create config/letsencrypt/acme.json when it needs certificate storage.
3
Create config/traefik/dynamic_config.yml
This file defines the routers, middleware, and services that send dashboard, API, and WebSocket traffic to Pangolin.
This file contains Pangolin’s application settings, dashboard domain, base domain, CORS origin, and server secret.
config/config.yml
# To see all available options, please visit the docs:# https://docs.pangolin.net/gerbil: start_port: 51820 base_endpoint: "pangolin.example.com" # REPLACE WITH YOUR DASHBOARD DOMAINapp: dashboard_url: "https://pangolin.example.com" # REPLACE WITH YOUR DASHBOARD DOMAIN log_level: "info" telemetry: anonymous_usage: truedomains: domain1: base_domain: "example.com" # REPLACE WITH YOUR BASE DOMAINserver: secret: "replace-with-a-long-random-secret" # REPLACE WITH SECURE SECRET cors: origins: ["https://pangolin.example.com"] # REPLACE WITH YOUR DASHBOARD DOMAIN methods: ["GET", "POST", "PUT", "DELETE", "PATCH"] allowed_headers: ["X-CSRF-Token", "Content-Type"] credentials: falseflags: require_email_verification: false disable_signup_without_invite: true disable_user_create_org: false allow_raw_resources: true
Replace these values before starting the stack:
pangolin.example.com with your dashboard hostname
example.com with your base domain
replace-with-a-long-random-secret with a strong random secret
admin@example.com in traefik_config.yml with your Let’s Encrypt email
Generate a secret with:
openssl rand -hex 32
Do not reuse a weak or short server.secret. If you need to rotate it later, use pangctl rotate-server-secret. See the container CLI tool guide.
Please note you will need to run podman exec ... instead of docker exec ....
If the setup page does not load, confirm your DNS record points to the server and ports 80 and 443 are reachable.
If you cannot complete first-time signup, check podman logs pangolin and copy the setup token printed by Pangolin.
If certificates are not issued, confirm admin@example.com was replaced and that nothing else is already bound to ports 80 or 443 (or whatever alternate ports you selected on the host).
If pangolin never becomes healthy, inspect podman logs -f pangolin.
If tunneling does not work, inspect podman logs -f gerbil and confirm UDP ports 51820 and 21820 are open.
If Traefik serves the wrong host, re-check every pangolin.example.com replacement in both Traefik files and config/config.yml.