--- kind: compose metadata: icon: provider: selfh id: pangolin name: Pangolin description: 'Self-hosted reverse proxy server that securely exposes private resources on distributed networks through encrypted WireGuard tunnels. Pangolin enables access from anywhere without opening ports, using a custom user-space WireGuard client (Newt) for secure connectivity. Features include automatic tunnel management, integrated CrowdSec security, and support for both PostgreSQL and SQLite databases. ## References * **Project:** https://github.com/fosrl/pangolin * **Documentation:** https://github.com/fosrl/pangolin/blob/main/README.md * **Docker Hub:** https://hub.docker.com/r/fosrl/pangolin ' version: latest author: Christian Lempa date: '2025-11-13' tags: - traefik - swarm - proxy - wireguard draft: true next_steps: '### 1. Configure Database {% if postgres_enabled -%} Make sure PostgreSQL is running and accessible at: * Connection string: {{ postgres_connection_string }} {% else -%} Pangolin will use SQLite database stored in the data volume. {% endif -%} ### 2. Deploy the Service {% if swarm_enabled -%} Deploy to Docker Swarm: ```bash docker stack deploy -c compose.yaml pangolin ``` {% else -%} Start Pangolin using Docker Compose: ```bash docker compose up -d ``` {% endif -%} ### 3. Access the Web Interface {% if traefik_enabled -%} * Navigate to: **https://{{ traefik_host }}.{{ traefik_domain }}** {% else -%} * Navigate to: **http://localhost:{{ ports_http }}** {% endif -%} ### 4. Configure WireGuard Clients * Use the Pangolin web interface to create and manage WireGuard tunnels * Deploy Newt client on remote machines to establish secure connections ' schema: '1.2' spec: general: vars: service_name: default: pangolin container_name: default: pangolin container_hostname: default: pangolin restart_policy: type: enum options: - unless-stopped - always - on-failure - 'no' default: unless-stopped required: true traefik: vars: traefik_host: default: pangolin traefik_network: default: traefik type: str required: true traefik_domain: default: home.arpa type: str required: true traefik_enabled: type: bool default: false description: Enable Traefik integration traefik_tls: vars: traefik_tls_certresolver: type: str default: cloudflare required: true traefik_tls_enabled: type: bool default: false description: Enable Traefik TLS network: vars: network_name: default: pangolin_network network_macvlan_ipv4_address: type: str default: 192.168.1.253 needs: - network_mode=macvlan required: true network_macvlan_parent_interface: type: str default: eth0 needs: - network_mode=macvlan required: true network_macvlan_subnet: type: str default: 192.168.1.0/24 needs: - network_mode=macvlan required: true network_macvlan_gateway: type: str default: 192.168.1.1 needs: - network_mode=macvlan required: true network_external: type: bool default: false description: Whether the network is external network_mode: type: str default: bridge description: The network mode for the container ports: vars: ports_http: description: External HTTP port (web interface) type: int default: 8080 needs: - traefik_enabled=false - network_mode=bridge volume: vars: volume_mount_path: default: /mnt/storage/pangolin volume_nfs_server: type: str default: 192.168.1.1 needs: - volume_mode=nfs required: true volume_nfs_path: type: str default: /export needs: - volume_mode=nfs required: true volume_nfs_options: type: str default: rw,nolock,soft needs: - volume_mode=nfs required: true volume_mode: type: enum options: - local - mount - nfs default: local description: The volume mode resources: vars: resources_enabled: type: bool default: false resources_cpu_limit: type: str default: 1.0 required: true resources_cpu_reservation: type: str default: 0.25 needs: - swarm_enabled=true required: true resources_memory_limit: type: str default: 1G required: true resources_memory_reservation: type: str default: 512M needs: - swarm_enabled=true required: true postgres: title: PostgreSQL Configuration toggle: postgres_enabled needs: null vars: postgres_enabled: type: bool default: false description: Use PostgreSQL database (SQLite is default) postgres_connection_string: type: str default: postgresql://postgres:postgres@localhost:5432 description: PostgreSQL connection string needs: postgres_enabled=true environment: title: Environment Variables toggle: environment_enabled needs: null vars: environment_enabled: type: bool default: false description: Configure additional environment variables environment_crowdsec_enabled: type: bool default: false description: Enable CrowdSec integration needs: environment_enabled=true environment_log_level: type: enum default: info options: - debug - info - warn - error description: Log level needs: environment_enabled=true swarm: vars: swarm_enabled: type: bool default: false description: Enable Docker Swarm mode swarm_placement_host: type: str default: '' description: The placement host swarm_placement_mode: type: str default: replicated description: The placement mode swarm_replicas: type: int default: 1 description: The number of replicas