mirror of
https://github.com/fosrl/docs-v2.git
synced 2026-02-08 05:56:45 +00:00
553 lines
21 KiB
Plaintext
553 lines
21 KiB
Plaintext
---
|
|
title: "Blueprints"
|
|
icon: "file-code"
|
|
description: "Pangolin Blueprints are declarative configurations that allow you to define your resources and their settings in a structured format"
|
|
---
|
|
|
|
Blueprints provide a way to define your Pangolin resources and their configurations in a structured, declarative format. This allows for easier management, version control, and automation of your resource setups.
|
|
|
|
<iframe
|
|
className="w-full aspect-video rounded-xl"
|
|
src="https://www.youtube.com/embed/lMauwwitSAE?si=k9-TUoandoffMrzV"
|
|
title="YouTube video player"
|
|
frameBorder="0"
|
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
|
allowFullScreen
|
|
></iframe>
|
|
|
|
## Overview
|
|
|
|
Pangolin supports two blueprint formats:
|
|
1. **YAML Configuration Files**: Standalone configuration files
|
|
2. **Docker Labels**: Configuration embedded in Docker Compose files
|
|
|
|
<Note type="info">
|
|
Some features in this documentation are marked with **(EE)**, indicating they are available only in the Enterprise Edition of Pangolin.
|
|
</Note>
|
|
|
|
## YAML Configuration Format
|
|
|
|
YAML config can be applied using Docker labels, API, from a Newt site, or in the UI. _Application through a CLI tool is planned._
|
|
|
|
<Card title="CLI YAML">
|
|
|
|
You can apply blueprints directly through the Pangolin CLI.
|
|
|
|
```bash
|
|
pangolin apply blueprint --file /path/to/blueprint.yaml
|
|
```
|
|
|
|
</Card>
|
|
|
|
<Card title="UI YAML">
|
|
|
|
You can also apply blueprints directly in the Pangolin UI. Navigate to **Settings > Blueprints** and paste your YAML configuration into the provided text area.
|
|
|
|
<Frame>
|
|
<img src="/images/create_blueprint.png" width="400" centered/>
|
|
</Frame>
|
|
|
|
</Card>
|
|
|
|
<Card title="Newt YAML">
|
|
|
|
Newt automatically discovers and applies blueprints defined in YAML format when passing the `--blueprint-file` argument. For example
|
|
|
|
```bash
|
|
newt --blueprint-file /path/to/blueprint.yaml <other-args>
|
|
```
|
|
|
|
</Card>
|
|
|
|
<Card title="API YAML">
|
|
|
|
You can also apply blueprints directly through the Pangolin API with an API key. [Take a look at the API documentation for more details.](https://api.pangolin.net/v1/docs/#/Organization/put_org__orgId__blueprint)
|
|
|
|
PUT to `/org/{orgId}/blueprint` with a base64 encodes JSON body like the following:
|
|
|
|
```json
|
|
{
|
|
"blueprint": "base64-encoded-json-content"
|
|
}
|
|
```
|
|
|
|
[See this python example](https://github.com/fosrl/pangolin/blob/dev/blueprint.py)
|
|
|
|
</Card>
|
|
|
|
### Public Resources
|
|
|
|
Public resources are used to expose HTTP, TCP, or UDP services through Pangolin. Below is an example configuration for public resources:
|
|
|
|
```yaml
|
|
public-resources:
|
|
resource-nice-id-uno:
|
|
name: this is a http resource
|
|
protocol: http
|
|
full-domain: uno.example.com
|
|
host-header: example.com
|
|
tls-server-name: example.com
|
|
headers:
|
|
- name: X-Example-Header
|
|
value: example-value
|
|
- name: X-Another-Header
|
|
value: another-value
|
|
rules:
|
|
- action: allow
|
|
match: ip
|
|
value: 1.1.1.1
|
|
priority: 1
|
|
- action: deny
|
|
match: cidr
|
|
value: 2.2.2.2/32
|
|
priority: 2
|
|
- action: allow
|
|
match: asn
|
|
value: AS13335
|
|
priority: 3
|
|
- action: pass
|
|
match: path
|
|
value: /admin
|
|
targets:
|
|
- site: lively-yosemite-toad
|
|
hostname: localhost
|
|
method: http
|
|
port: 8000
|
|
- site: slim-alpine-chipmunk
|
|
hostname: localhost
|
|
path: /admin
|
|
path-match: exact
|
|
method: https
|
|
port: 8001
|
|
resource-nice-id-dos:
|
|
name: this is a raw resource
|
|
protocol: tcp
|
|
proxy-port: 3000
|
|
targets:
|
|
- site: lively-yosemite-toad
|
|
hostname: localhost
|
|
port: 3000
|
|
```
|
|
|
|
### Authentication Configuration
|
|
|
|
<Note>
|
|
Authentication is off by default. You can enable it by adding the relevant fields in the `auth` section as shown in the example below.
|
|
</Note>
|
|
|
|
```yaml
|
|
public-resources:
|
|
secure-resource:
|
|
name: Secured Resource
|
|
protocol: http
|
|
full-domain: secure.example.com
|
|
auth:
|
|
pincode: 123456
|
|
password: your-secure-password
|
|
basic-auth:
|
|
user: asdfa
|
|
password: sadf
|
|
sso-enabled: true
|
|
sso-roles:
|
|
- Member
|
|
- Admin
|
|
sso-users:
|
|
- user@example.com
|
|
whitelist-users:
|
|
- admin@example.com
|
|
```
|
|
|
|
### Targets-Only Resources
|
|
|
|
You can define simplified resources that contain only target configurations. This is useful for adding targets to existing resources or for simple configurations:
|
|
|
|
```yaml
|
|
public-resources:
|
|
additional-targets:
|
|
targets:
|
|
- site: another-site
|
|
hostname: backend-server
|
|
method: https
|
|
port: 8443
|
|
- site: another-site
|
|
hostname: backup-server
|
|
method: http
|
|
port: 8080
|
|
```
|
|
|
|
<Note>
|
|
When using targets-only resources, the `name` and `protocol` fields are not required. All other resource-level validations are skipped for these simplified configurations.
|
|
</Note>
|
|
|
|
### Maintenance Page Configuration **(EE)**
|
|
|
|
<Note type="warning">
|
|
This is an Enterprise Edition (EE) feature only. It allows you to display a maintenance page for a public resource when it's under maintenance or when targets are unhealthy.
|
|
</Note>
|
|
|
|
```yaml
|
|
public-resources:
|
|
production-app:
|
|
name: Production Application
|
|
protocol: http
|
|
full-domain: app.example.com
|
|
maintenance:
|
|
enabled: true
|
|
type: forced
|
|
title: Scheduled Maintenance
|
|
message: We are performing system upgrades to improve performance. The service will be back online shortly.
|
|
estimated-time: 2 hours
|
|
targets:
|
|
- site: my-site
|
|
hostname: app-server
|
|
method: https
|
|
port: 443
|
|
```
|
|
|
|
**Maintenance Types:**
|
|
- **`forced`**: Always displays the maintenance page regardless of target health status
|
|
- **`automatic`**: Displays the maintenance page only when all targets are unhealthy or the sites are offline
|
|
|
|
### Private Resources
|
|
|
|
Private resources define proxied resources accessible when connected via an client:
|
|
|
|
```yaml
|
|
private-resources:
|
|
private-resource-nice-id-uno:
|
|
name: SSH Server
|
|
mode: host
|
|
destination: 192.168.1.100
|
|
site: lively-yosemite-toad
|
|
tcp-ports: "22,3389"
|
|
udp-ports: "*"
|
|
disable-icmp: false
|
|
roles:
|
|
- Developer
|
|
- DevOps
|
|
users:
|
|
- user@example.com
|
|
machines:
|
|
- machine-id-1
|
|
- machine-id-2
|
|
private-resource-nice-id-duo:
|
|
name: Internal Network
|
|
mode: cidr
|
|
destination: 10.0.0.0/24
|
|
site: lively-yosemite-toad
|
|
tcp-ports: "80,443,8000-9000"
|
|
udp-ports: "53,123"
|
|
disable-icmp: true
|
|
users:
|
|
- admin@example.com
|
|
```
|
|
|
|
## Docker Labels Format
|
|
|
|
For containerized applications, you can define blueprints using Docker labels.
|
|
|
|
<Note>
|
|
Blueprints will **continuously apply** from changes in the docker stack, newt restarting, or when viewing the resource in the dashboard.
|
|
</Note>
|
|
|
|
### Enabling Docker Socket Access
|
|
|
|
To use Docker labels, enable the Docker socket when running Newt:
|
|
|
|
```bash
|
|
newt --docker-socket /var/run/docker.sock <other-args>
|
|
```
|
|
|
|
or using the environment variable:
|
|
|
|
```bash
|
|
DOCKER_SOCKET=/var/run/docker.sock
|
|
```
|
|
|
|
### Docker Compose Example
|
|
|
|
<Note>
|
|
The compose file will be the source of truth, any edits through the resources dashboard will be **overwritten** by the blueprint labels defined in the compose stack.
|
|
</Note>
|
|
|
|
```yaml
|
|
services:
|
|
newt:
|
|
image: fosrl/newt
|
|
container_name: newt
|
|
restart: unless-stopped
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
environment:
|
|
- PANGOLIN_ENDPOINT=https://app.pangolin.net
|
|
- NEWT_ID=h1rbsgku89wf9z3
|
|
- NEWT_SECRET=z7g54mbcwkglpx1aau9gb8mzcccoof2fdbs97keoakg2pp5z
|
|
- DOCKER_SOCKET=/var/run/docker.sock
|
|
|
|
nginx1:
|
|
image: nginxdemos/hello
|
|
container_name: nginx1
|
|
labels:
|
|
# Public Resource Configuration
|
|
- pangolin.public-resources.nginx.name=nginx
|
|
- pangolin.public-resources.nginx.full-domain=nginx.fosrl.io
|
|
- pangolin.public-resources.nginx.protocol=http
|
|
- pangolin.public-resources.nginx.headers[0].name=X-Example-Header
|
|
- pangolin.public-resources.nginx.headers[0].value=example-value
|
|
# Target Configuration - the port and hostname will be auto-detected
|
|
- pangolin.public-resources.nginx.targets[0].method=http
|
|
- pangolin.public-resources.nginx.targets[0].path=/path
|
|
- pangolin.public-resources.nginx.targets[0].path-match=prefix
|
|
|
|
nginx2:
|
|
image: nginxdemos/hello
|
|
container_name: nginx2
|
|
labels:
|
|
# Additional target for the same resource where the port and hostname are explicit
|
|
- pangolin.public-resources.nginx.targets[1].method=http
|
|
- pangolin.public-resources.nginx.targets[1].hostname=nginx2
|
|
- pangolin.public-resources.nginx.targets[1].port=80
|
|
|
|
networks:
|
|
default:
|
|
name: pangolin_default
|
|
```
|
|
|
|
This will create a resource that looks like the following:
|
|
|
|
<Frame caption="Pangolin UI showing Docker Compose blueprint example">
|
|
<img src="/images/docker-compose-blueprint-example.png" alt="Example resource"/>
|
|
</Frame>
|
|
|
|
### Docker Labels Considerations
|
|
|
|
<Card title="Automatic Discovery">
|
|
When hostname and internal port are not explicitly defined in labels, Pangolin will automatically detect them from the container configuration.
|
|
</Card>
|
|
|
|
<Card title="Site Assignment">
|
|
If no site is specified in the labels, the resource will be assigned to the Newt site that discovered the container.
|
|
</Card>
|
|
|
|
<Card title="Configuration Merging">
|
|
Configuration across different containers is automatically merged to form complete resource definitions. This allows you to distribute targets across multiple containers while maintaining a single logical resource.
|
|
</Card>
|
|
|
|
## Configuration Properties
|
|
|
|
### Public Resources
|
|
|
|
| Property | Type | Required | Description | Constraints |
|
|
|----------|------|----------|-------------|-------------|
|
|
| `name` | string | Conditional | Human-readable name for the resource | Required unless targets-only resource |
|
|
| `protocol` | string | Conditional | Protocol type (`http`, `tcp`, or `udp`) | Required unless targets-only resource |
|
|
| `full-domain` | string | HTTP only | Full domain name for HTTP resources | Required for HTTP protocol, must be unique |
|
|
| `proxy-port` | number | TCP/UDP only | Port for raw TCP/UDP resources | Required for TCP/UDP, 1-65535, must be unique within public-resources |
|
|
| `ssl` | boolean | No | Enable SSL/TLS for the resource | - |
|
|
| `enabled` | boolean | No | Whether the resource is enabled | Defaults to `true` |
|
|
| `host-header` | string | No | Custom Host header for requests | - |
|
|
| `tls-server-name` | string | No | SNI name for TLS connections | - |
|
|
| `headers` | array | No | Custom headers to add to requests | Each header requires `name` and `value` (min 1 char each) |
|
|
| `rules` | array | No | Access control rules | See Rules section below |
|
|
| `auth` | object | HTTP only | Authentication configuration | See Authentication section below |
|
|
| `maintenance` | object | No | Maintenance page configuration **(EE)** | Enterprise Edition only. See Maintenance Configuration section below |
|
|
| `targets` | array | Yes | Target endpoints for the resource | See Targets section below |
|
|
|
|
### Target Configuration
|
|
|
|
| Property | Type | Required | Description | Constraints |
|
|
|----------|------|----------|-------------|-------------|
|
|
| `site` | string | No | Site identifier where the target is located | - |
|
|
| `hostname` | string | Yes | Target hostname or IP address | - |
|
|
| `port` | number | Yes | Port on the target system | 1-65535 |
|
|
| `method` | string | HTTP only | Protocol method (`http`, `https`, or `h2c`) | Required for HTTP protocol targets |
|
|
| `enabled` | boolean | No | Whether the target is enabled | Defaults to `true` |
|
|
| `internal-port` | number | No | Internal port mapping | 1-65535 |
|
|
| `path` | string | HTTP only | Path prefix, exact path, or regex pattern | - |
|
|
| `path-match` | string | HTTP only | Path matching type (`prefix`, `exact`, or `regex`) | - |
|
|
| `rewrite-path` | string | No | Path to rewrite the request to | - |
|
|
| `rewrite-match` | string | No | Rewrite matching type (`exact`, `prefix`, `regex`, or `stripPrefix`) | - |
|
|
| `priority` | number | No | Target priority for load balancing | 1-1000, defaults to 100 |
|
|
| `healthcheck` | object | No | Health check configuration for the target | See Health Check Configuration below |
|
|
|
|
### Health Check Configuration
|
|
|
|
Health checks can be configured for individual targets to monitor their availability. Add a `healthcheck` object to any target:
|
|
|
|
```yaml
|
|
public-resources:
|
|
monitored-service:
|
|
name: Monitored Service
|
|
protocol: http
|
|
full-domain: service.example.com
|
|
targets:
|
|
- site: my-site
|
|
hostname: backend-server
|
|
method: https
|
|
port: 8443
|
|
healthcheck:
|
|
hostname: backend-server
|
|
port: 8443
|
|
enabled: true
|
|
path: /health
|
|
interval: 30
|
|
timeout: 5
|
|
method: GET
|
|
status: 200
|
|
headers:
|
|
- name: X-Health-Check
|
|
value: true
|
|
```
|
|
|
|
| Property | Type | Required | Description | Constraints |
|
|
|----------|------|----------|-------------|-------------|
|
|
| `hostname` | string | Yes | Hostname for health check | - |
|
|
| `port` | number | Yes | Port for health check | 1-65535 |
|
|
| `enabled` | boolean | No | Whether health check is enabled | Defaults to `true` |
|
|
| `path` | string | No | Path to check | - |
|
|
| `scheme` | string | No | Protocol scheme for the health check | - |
|
|
| `mode` | string | No | Health check mode | Defaults to `http` |
|
|
| `interval` | number | No | Seconds between health checks | Defaults to 30 |
|
|
| `unhealthy-interval` | number | No | Seconds between checks when unhealthy | Defaults to 30 |
|
|
| `timeout` | number | No | Timeout in seconds | Defaults to 5 |
|
|
| `headers` | array | No | Headers to send with health check | Array of objects with `name` and `value` |
|
|
| `follow-redirects` | boolean | No | Whether to follow redirects | Defaults to `true` |
|
|
| `method` | string | No | HTTP method for health check | Defaults to `GET` |
|
|
| `status` | number | No | Expected HTTP status code | - |
|
|
|
|
### Authentication Configuration
|
|
|
|
Not allowed on TCP/UDP resources.
|
|
|
|
| Property | Type | Required | Description | Constraints |
|
|
|----------|------|----------|-------------|-------------|
|
|
| `pincode` | number | No | 6-digit PIN for access | Must be exactly 6 digits |
|
|
| `password` | string | No | Password for access | - |
|
|
| `basic-auth` | object | No | Basic authentication configuration | Requires `user` and `password` fields |
|
|
| `sso-enabled` | boolean | No | Enable SSO authentication | Defaults to `false` |
|
|
| `sso-roles` | array | No | Allowed SSO roles | Cannot include "Admin" role |
|
|
| `sso-users` | array | No | Allowed SSO usernames | Must be valid usernames |
|
|
| `whitelist-users` | array | No | Whitelisted user emails | Must be valid email addresses |
|
|
| `auto-login-idp` | number | No | Automatic login identity provider ID | Must be a positive integer |
|
|
|
|
### Maintenance Configuration **(EE)**
|
|
|
|
<Note type="warning">
|
|
This is an Enterprise Edition (EE) feature only. It allows you to display a maintenance page for a public resource.
|
|
</Note>
|
|
|
|
The `maintenance` object can be added to any public resource to display a maintenance page to users:
|
|
|
|
```yaml
|
|
public-resources:
|
|
my-service:
|
|
name: My Service
|
|
protocol: http
|
|
full-domain: service.example.com
|
|
maintenance:
|
|
enabled: true
|
|
type: automatic
|
|
title: Scheduled Maintenance
|
|
message: We are performing scheduled maintenance. Service will resume shortly.
|
|
estimated-time: 2 hours
|
|
targets:
|
|
- site: my-site
|
|
hostname: backend-server
|
|
method: https
|
|
port: 8443
|
|
```
|
|
|
|
| Property | Type | Required | Description | Constraints |
|
|
|----------|------|----------|-------------|-------------|
|
|
| `enabled` | boolean | No | Whether the maintenance page is enabled | Defaults to `false` |
|
|
| `type` | string | No | Maintenance type (`forced` or `automatic`) | `forced` always shows maintenance page; `automatic` shows only when all targets are unhealthy or sites offline |
|
|
| `title` | string | No | Title text for the maintenance page | Maximum 255 characters, can be null |
|
|
| `message` | string | No | Message text explaining the maintenance | Maximum 2000 characters, can be null |
|
|
| `estimated-time` | string | No | Estimated time for maintenance completion | Maximum 100 characters, can be null |
|
|
|
|
**Maintenance Types:**
|
|
- **`forced`**: Always displays the maintenance page regardless of target health status
|
|
- **`automatic`**: Displays the maintenance page only when all targets are unhealthy
|
|
|
|
### Rules Configuration
|
|
|
|
| Property | Type | Required | Description | Constraints |
|
|
|----------|------|----------|-------------|-------------|
|
|
| `action` | string | Yes | Rule action (`allow`, `deny`, or `pass`) | - |
|
|
| `match` | string | Yes | Match type (`cidr`, `path`, `ip`, `country`, or `asn`) | - |
|
|
| `value` | string | Yes | Value to match against | Format depends on match type. For `ip`: valid IPv4/IPv6 address. For `cidr`: valid CIDR notation. For `country`: 2-letter country code or `ALL`. For `asn`: `AS<number>` format or `ALL` |
|
|
| `priority` | number | No | Rule priority for evaluation order | Integer value, lower numbers evaluated first |
|
|
|
|
### Private Resources
|
|
|
|
These are resources used with Pangolin clients (e.g., SSH, RDP).
|
|
|
|
| Property | Type | Required | Description | Constraints |
|
|
|----------|------|----------|-------------|-------------|
|
|
| `name` | string | Yes | Human-readable name for the resource | 1-255 characters |
|
|
| `mode` | string | Yes | Resource mode (`host` or `cidr`) | - |
|
|
| `destination` | string | Yes | Target IP address, hostname, or CIDR block | For `host` mode: IP address or domain. For `cidr` mode: valid CIDR notation |
|
|
| `site` | string | Yes | Site identifier where the resource is located | - |
|
|
| `tcp-ports` | string | No | TCP port ranges to allow | Port range string (e.g., `"80,443,8000-9000"`), defaults to `"*"` (all ports) |
|
|
| `udp-ports` | string | No | UDP port ranges to allow | Port range string (e.g., `"53,123,5000-6000"`), defaults to `"*"` (all ports) |
|
|
| `disable-icmp` | boolean | No | Disable ICMP (ping) for this resource | Defaults to `false` |
|
|
| `alias` | string | No | Fully qualified domain name alias | Must be a valid FQDN (e.g., example.com). Required when destination is a domain in `host` mode |
|
|
| `roles` | array | No | Allowed SSO roles | Cannot include "Admin" role |
|
|
| `users` | array | No | Allowed user emails | Must be valid email addresses |
|
|
| `machines` | array | No | Allowed machine identifiers | Array of strings |
|
|
|
|
## Validation Rules and Constraints
|
|
|
|
### Resource-Level Validations
|
|
|
|
1. **Targets-Only Resources**: A resource can contain only the `targets` field, in which case `name` and `protocol` are not required.
|
|
|
|
2. **Protocol-Specific Requirements**:
|
|
- **HTTP Protocol**: Must have `full-domain` and all targets must have `method` field
|
|
- **TCP/UDP Protocol**: Must have `proxy-port` and targets must NOT have `method` field
|
|
- **TCP/UDP Protocol**: Cannot have `auth` configuration
|
|
|
|
3. **Alias Uniqueness**: `alias` values must be unique across all private resources within the same blueprint and in the org
|
|
|
|
4. **Domain Uniqueness**: `full-domain` values must be unique across all public resources
|
|
|
|
5. **Proxy Port Uniqueness**: `proxy-port` values must be unique per protocol within public resources (e.g., TCP port 3000 and UDP port 3000 can coexist)
|
|
|
|
6. **Target Method Requirements**: When protocol is `http`, all non-null targets must specify a `method`
|
|
|
|
## Common Validation Errors
|
|
|
|
When working with blueprints, you may encounter these validation errors:
|
|
|
|
### "Admin role cannot be included in sso-roles"
|
|
The `Admin` role is reserved and cannot be included in the `sso-roles` array for authentication configuration.
|
|
|
|
### "Duplicate 'full-domain' values found"
|
|
Each `full-domain` must be unique across all public resources. If you need multiple resources for the same domain, use different subdomains or paths.
|
|
|
|
### "Duplicate 'proxy-port' values found in public-resources"
|
|
Port numbers in `proxy-port` must be unique per protocol within public-resources (e.g., you can't have two TCP resources using port 3000, but TCP port 3000 and UDP port 3000 can coexist).
|
|
|
|
### "When protocol is 'http', all targets must have a 'method' field"
|
|
All targets in HTTP proxy resources must specify whether they use `http`, `https`, or `h2c`.
|
|
|
|
### "When protocol is 'tcp' or 'udp', targets must not have a 'method' field"
|
|
TCP and UDP targets should not include the `method` field as it's only applicable to HTTP resources.
|
|
|
|
### "When protocol is 'tcp' or 'udp', 'auth' must not be provided"
|
|
Authentication is only supported for HTTP resources, not TCP or UDP.
|
|
|
|
### "Resource must either be targets-only or have both 'name' and 'protocol' fields"
|
|
Resources must either contain only the `targets` field (targets-only) or include both `name` and `protocol` for complete resource definitions.
|
|
|
|
### "Duplicate 'alias' values found in private-resources"
|
|
Alias values in private resources must be unique within the blueprint.
|
|
|
|
### "Destination must be a valid IP address or valid domain AND alias is required"
|
|
For private resources in `host` mode, the destination must be a valid IP address or domain. When using a domain, an `alias` field is required.
|
|
### "Destination must be a valid CIDR notation for cidr mode"
|
|
For private resources in `cidr` mode, the destination must be a valid CIDR notation (e.g., 10.0.0.0/24).
|
|
|
|
### "Admin role cannot be included in roles"
|
|
The `Admin` role is reserved and cannot be included in the `roles` array for private resource configuration.
|