This is the multi-page printable view of this section. .
Administration
- 1: Nginx Management
- 2: Software Repository
- 3: Domain Management
- 4: Module Management
- 5: CA and Certificates
- 6: Grafana High Availability: Using PostgreSQL Backend
This section covers daily administration and operations for Pigsty deployments.
1 - Nginx Management
Pigsty installs Nginx on INFRA nodes as the entry point for all web services. It listens on standard ports 80/443.
In Pigsty, you can configure Nginx to provide various services through inventory:
- Expose web interfaces for monitoring components like Grafana, VictoriaMetrics (VMUI), Alertmanager, and VictoriaLogs
- Serve static files (software repos, documentation sites, websites, etc.)
- Proxy custom application services (internal apps, database management UIs, Docker application interfaces, etc.)
- Automatically issue self-signed HTTPS certificates, or use Certbot to obtain free Let’s Encrypt certificates
- Expose services through a single port using different subdomains for unified access
Basic Configuration
Customize Nginx behavior via infra_portal parameter:
infra_portal is a dictionary where each key defines a service and the value is the service configuration.
Pigsty generates Nginx configuration files only for services with a defined domain.
home: Special default server for homepage and built-in monitoring component reverse proxies- Proxy services: Specify upstream service address via
endpointfor reverse proxy - Static services: Specify local directory via
pathfor static file serving
Server Parameters
Basic Parameters
| Parameter | Description |
|---|---|
domain | Optional proxy domain |
endpoint | Upstream service address (IP:PORT or socket) |
path | Local directory for static content |
scheme | Protocol type (http/https), default http |
domains | Additional domain list (aliases) |
SSL/TLS Options
| Parameter | Description |
|---|---|
certbot | Enable Let’s Encrypt cert management, value is cert name |
cert | Custom certificate file path |
key | Custom private key file path |
enforce_https | Force HTTPS redirect (301) |
Advanced Settings
| Parameter | Description |
|---|---|
config | Custom Nginx config snippet |
index | Enable directory listing (for static) |
log | Custom log file name |
websocket | Enable WebSocket support |
auth | Enable Basic Auth |
realm | Basic Auth prompt message |
Configuration Examples
Reverse Proxy Services
Static Files and Directory Listing
Custom SSL Certificate
Using Let’s Encrypt Certificates
Force HTTPS Redirect
Custom Config Snippet
Management Commands
Domain Resolution
Three ways to resolve domains to Pigsty servers:
- Public domains: Configure via DNS provider
- Internal DNS server: Configure internal DNS resolution
- Local hosts file: Modify
/etc/hosts
For local development, add to /etc/hosts:
Pigsty includes dnsmasq service, configurable via dns_records parameter for internal DNS resolution.
HTTPS Configuration
Configure HTTPS via nginx_sslmode parameter:
| Mode | Description |
|---|---|
disable | Listen HTTP only (nginx_port) |
enable | Also listen HTTPS (nginx_ssl_port), default self-signed cert |
enforce | Force redirect to HTTPS, all port 80 requests get 301 redirect |
For self-signed certificates, several access options:
- Trust the self-signed CA in browser (download at
http://<ip>/ca.crt) - Use browser security bypass (type “thisisunsafe” in Chrome)
- Configure proper CA-signed certs or Let’s Encrypt for production
Certbot Certificates
Pigsty supports using Certbot to request free Let’s Encrypt certificates.
Enable Certbot
- Add
certbotparameter to services ininfra_portal, specifying cert name - Configure
certbot_emailwith a valid email - Set
certbot_signtotruefor auto-signing during deployment
Manual Certificate Signing
Or run the scripts directly on the server:
For more info, see Certbot: Request and Renew HTTPS Certificates
Default Homepage
Pigsty’s default home server provides these built-in routes:
| Path | Description |
|---|---|
/ | Homepage navigation |
/ui/ | Grafana monitoring dashboards |
/vmetrics/ | VictoriaMetrics VMUI |
/vlogs/ | VictoriaLogs log query |
/vtraces/ | VictoriaTraces tracing |
/vmalert/ | VMAlert alerting rules |
/alertmgr/ | AlertManager alert management |
/blackbox/ | Blackbox Exporter |
/pev | PostgreSQL Explain visualization |
/haproxy/<cluster>/ | HAProxy admin interface (if any) |
These routes provide one entry point for all monitoring components. You do not need to configure multiple domains.
Best Practices
- Use domain names instead of IP:PORT for service access
- Properly configure DNS resolution or hosts file
- Enable WebSocket for real-time apps (e.g., Grafana, Jupyter)
- Enable HTTPS for production
- Use meaningful subdomains to organize services
- Monitor Let’s Encrypt certificate expiration
- Use
configparameter for custom Nginx configurations
Full Example
Here’s the Nginx configuration used by Pigsty’s public demo site demo.pigsty.io:
2 - Software Repository
Pigsty’s REPO role downloads required packages and creates a local YUM/APT repository under /www/pigsty. Nginx can serve this repository.
The current package candidate is SOW 0.3.0. SOW generates metadata for both repository types. The source no longer calls createrepo_c, modifyrepo_c, or dpkg-scanpackages separately.
Quick Start
Add packages to repo_packages or repo_extra_packages, then run:
If /www/pigsty/repo_complete already exists, the default repo_build skips the build. To force a rebuild, override it explicitly:
To rebuild metadata for packages already present without downloading new ones:
SOW Prerequisites
Both repo_create and cache_create require sow on the target node. A fresh online build automatically adds infra to the effective repo_modules list. It installs SOW from the Pigsty INFRA upstream repository.
Offline bundles and local repositories created before this change may not contain SOW. Before you rebuild from old media, refresh the bundle or local repository. Alternatively, install the current SOW 0.3.0 candidate from Pigsty INFRA. Do not assume that older environments can still fall back to createrepo_c.
On a fresh installation, the role checks whether /www exists. If absent, it creates /data/nginx and points /www to it. It preserves existing directories and symlinks.
Build Flow
| Task | Purpose |
|---|---|
repo_check | Check repo_complete to determine whether the local repository is complete |
repo_prepare | Configure and use an existing repository |
repo_dir | Create /www/pigsty and ACME directories |
repo_upstream | Back up and add upstream YUM or APT definitions |
repo_url_pkg | Download packages from direct URLs |
repo_cache | Run yum makecache or apt update |
repo_boot_pkg | Install sow and the RPM platform’s dnf-utils / yum-utils |
repo_pkg | Download packages and dependencies |
repo_create | Run SOW to clean and atomically publish repository metadata |
repo_use | Write the local Pigsty repository definition on the current host |
repo_nginx | Start a temporary Nginx when no service is already running |
The command executed by repo_create is:
--pigsty removes unneeded packages and packages likely to cause conflicts. It atomically publishes the result only after all metadata is complete. A typical layout is:
repo_complete contains SHA-256 checksums. Do not treat it as an empty marker. Its presence means SOW completed publication of local repository metadata. It does not prove that remote mirrors, signed repositories, or offline bundles have been synchronized.
DNF Module Streams
Pigsty no longer fabricates modules.yaml / ModuleMD metadata for the aggregated local repository. System upstream repositories retain native DNF module filtering. Only an upstream repository that truly needs to replace an EL module stream should set meta explicitly:
The aggregated local repository uses module_hotfixes=1. This prevents system module streams from hiding local PostgreSQL packages. It does not generate artificial ModuleMD metadata.
Package Aliases
The default repo_packages uses these alias groups:
node-bootstrap includes Ansible, Python dependencies, SOW, and SSH tools. infra-package includes Nginx, etcd, HAProxy, Victoria exporters, Redis/Valkey, Silo, mcli, SOW, and Pig. Exact names vary by operating-system mapping. Use roles/node_id/vars/<os>.<arch>.yml as the authoritative source.
Common Commands
3 - Domain Management
Use domain names instead of IP addresses to access Pigsty’s various web services.
Quick Start
Add the following static resolution records to /etc/hosts:
Replace IP address with your actual Pigsty node’s IP.
Why Use Domain Names
- Easier to remember than IP addresses
- Flexible pointing to different IPs
- Unified service management through Nginx
- Support for HTTPS encryption
- Prevent ISP hijacking in some regions
- Allow access to internally bound services via proxy
DNS Mechanism
DNS Protocol: Resolves domain names to IP addresses. Multiple domains can point to same IP.
HTTP Protocol: The Host header routes requests to different sites on the same port (80/443).
Default Domains
Pigsty predefines the following default domains:
| Domain | Service | Port | Purpose |
|---|---|---|---|
i.pigsty | Nginx | 80/443 | Default homepage, local repo, unified entry |
m.pigsty | Silo | 9001 | Object storage console |
By default, access Grafana, VictoriaMetrics, and Alertmanager under i.pigsty. Their paths are /ui/, /vmetrics/, and /alertmgr/, respectively. To use dedicated domains such as g.pigsty, p.pigsty, and a.pigsty, configure them explicitly in infra_portal and dns_records.
Resolution Methods
Local Static Resolution
Add entries to /etc/hosts on the client machine:
Add content:
Internal Dynamic Resolution
Pigsty includes dnsmasq as an internal DNS server. Configure managed nodes to use INFRA node as DNS server:
Configure domain records resolved by dnsmasq via dns_records:
Public Domain Names
Purchase a domain and add DNS A record pointing to public IP:
- Purchase domain from registrar (e.g.,
example.com) - Configure A record pointing to server public IP
- Use real domain in
infra_portal
Built-in DNS Service
Pigsty runs dnsmasq on INFRA nodes as a DNS server.
Related Parameters
| Parameter | Default | Description |
|---|---|---|
dns_enabled | true | Enable DNS service |
dns_port | 53 | DNS listen port |
dns_records | See below | Default DNS records |
Default DNS records:
Dynamic DNS Registration
Pigsty automatically registers DNS records for PostgreSQL clusters and instances:
- Instance-level DNS:
<pg_instance>points to instance IP (e.g.,pg-meta-1) - Cluster-level DNS:
<pg_cluster>points to primary IP or VIP (e.g.,pg-meta)
Cluster-level DNS target controlled by pg_dns_target:
| Value | Description |
|---|---|
auto | Auto-select: use VIP if available, else primary IP |
primary | Always point to primary IP |
vip | Always point to VIP (requires VIP enabled) |
none | Don’t register cluster DNS |
<ip> | Specify fixed IP address |
Add suffix to cluster DNS via pg_dns_suffix.
Node DNS Configuration
Pigsty manages DNS configuration on managed nodes.
Static hosts Records
Configure static /etc/hosts records via node_etc_hosts:
DNS Server Configuration
| Parameter | Default | Description |
|---|---|---|
node_dns_method | add | DNS config method |
node_dns_servers | ['${admin_ip}'] | DNS server list |
node_dns_options | See below | resolv.conf options |
node_dns_method options:
| Value | Description |
|---|---|
add | Prepend to existing DNS server list |
overwrite | Completely overwrite DNS config |
none | Don’t modify DNS config |
Default DNS options:
HTTPS Certificates
Pigsty uses self-signed certificates by default. Options include:
- Ignore warnings, use HTTP
- Trust self-signed CA certificate (download at
http://<ip>/ca.crt) - Use real CA or get free public domain certs via Certbot
See CA and Certificates documentation for details.
Extended Domains
Pigsty reserves the following domains for various application services:
| Domain | Purpose |
|---|---|
adm.pigsty | PgAdmin interface |
ddl.pigsty | Bytebase DDL management |
cli.pigsty | PgWeb CLI interface |
api.pigsty | PostgREST API service |
lab.pigsty | Jupyter environment |
git.pigsty | Gitea Git service |
wiki.pigsty | Wiki.js docs |
noco.pigsty | NocoDB |
supa.pigsty | Supabase |
dify.pigsty | Dify AI |
odoo.pigsty | Odoo ERP |
mm.pigsty | Mattermost |
Using these domains requires configuring corresponding services in infra_portal.
Management Commands
4 - Module Management
Use this guide for daily INFRA administration. It covers installation, removal, scaling, and component maintenance.
Install INFRA Module
Use the infra.yml playbook to install the INFRA module on the infra group:
Uninstall INFRA Module
Use the infra-rm.yml playbook to uninstall the INFRA module from the infra group:
This playbook has no deletion safeguard. Full execution removes infra_data, nginx_data, nginx_home (default: /www), and /var/lib/grafana.
If you only need to stop services or deregister targets, use -t service or -t deregister. Read the complete removal scope and back up required data before running it.
Scale Out INFRA Module
Assign infra_seq to new nodes and add them to the infra group in the inventory:
Use the -l limit option to execute the playbook on the new node only:
Manage Local Repository
Local repository management tasks:
Complete subtask list:
Manage Nginx
Nginx management tasks:
Request HTTPS certificate:
Manage Infrastructure Components
Management commands for various infrastructure components:
Common maintenance commands:
Manage Grafana Passwords
Grafana uses two password parameters. grafana_admin_password defaults to the public value pigsty. grafana_view_password defaults to DBUser.Viewer.
| Parameter | Rendered configuration |
|---|---|
grafana_admin_password | /etc/grafana/grafana.ini and /infra/env/pigsty |
grafana_view_password | /etc/grafana/provisioning/datasources/pigsty.yml |
Change the public defaults before production. After initialization, a change to grafana_admin_password in the inventory does not reset the live Grafana account password. Change it through Grafana or a supported administration interface. Keep the inventory consistent and regenerate the environment when needed:
grafana_view_password is the password used by the default PostgreSQL metadb data source as dbuser_view. If the database role password changes, update both the declared value and the Grafana data source. A change on only one side breaks the dashboard connection.
5 - CA and Certificates
Pigsty maintains a self-signed Certificate Authority (CA) on the admin node by default. It signs certificates for PostgreSQL, Patroni, etcd, Silo, Nginx, and other internal services. Public Nginx entries can use Certbot/Let’s Encrypt certificates configured through infra_portal.
files/pki/ca/ca.key is the trust-root private key for the entire deployment. Never print, commit, upload, or transmit it over an unprotected channel. Back it up with ca.crt. Encrypt the backup and tightly restrict read access.
Self-Signed CA
The ca stage of infra.yml creates or reuses the CA locally on the admin node running Ansible. It does not create the CA on a remote Infra node. The default layout is:
The core defaults match the v4.5.0 roles:
| Parameter | Default | Meaning |
|---|---|---|
ca_create | true | Allow creation when ca.key is missing |
ca_cn | pigsty-ca | Common Name of the CA certificate |
cert_validity | 7300d | Default internal service/client validity (20 years) |
nginx_cert_validity | 397d | Nginx self-signed HTTPS certificate validity |
The role hard-codes the CA certificate lifetime to 36500d (about 100 years). These long-lived certificates serve a controlled internal trust domain. Public browsers do not trust them by default. Clients must explicitly trust ca.crt. Public endpoints should use a publicly trusted CA.
Initialize the local CA stage:
Running ./infra.yml -t ca may create a missing key or certificate and therefore changes PKI state. Confirm the admin node, configuration, and existing CA backup first.
Use an External CA
To reuse an enterprise CA:
- Set
ca_create: falseinpigsty.yml. - Place a matching
files/pki/ca/ca.keyandfiles/pki/ca/ca.crtpair on the admin node. - Set permissions and verify that the public-key digests match.
ca_create: false prevents generation of a new private key only when ca.key is missing. If the key exists and ca.crt is missing, the role still creates a new self-signed CA certificate from the key. Always restore the pair together instead of relying on certificate regeneration.
Before running the CA stage, verify the files that will be used, the existing CA backup, and the admin node.
Back Up and Restore the CA
Retain at least:
files/pki/ca/ca.keyandca.crt- CA state such as
ca.srl,index.txt, and CRL files if issuance/revocation management uses them - backup time, the CA certificate SHA-256 fingerprint, and restoration instructions
Encrypt the backup and store it on controlled offline media or in a secrets-management system. Do not keep an unencrypted tar archive.
First, restore it to an isolated temporary directory. Before replacement, verify the file count, types, permissions, public-key match, and certificate fingerprint.
Loss of ca.key does not immediately prevent verification of existing certificates. Verification still works if clients trust ca.crt and the certificates remain valid and unrevoked.
You can no longer issue, renew, or revoke certificates with the original CA. Recovery usually requires a new CA, reissuance of every certificate, and deployment of a new trust chain.
Issue Certificates with cert.yml
cert.yml runs locally on the admin node and issues generic certificates with the Pigsty CA. Pass cn explicitly instead of relying on the generic script default:
Default outputs:
| Parameter | Default | Meaning |
|---|---|---|
cn | pigsty | Common Name; set explicitly in real use |
san | [DNS:localhost, IP:127.0.0.1] | Subject Alternative Names |
org | pigsty | Organization |
unit | pigsty | Organizational Unit |
expire | 7300d | Validity |
key | files/pki/misc/<cn>.key | Private-key output path |
crt | files/pki/misc/<cn>.crt | Certificate output path |
Advanced examples:
Verify the certificate without displaying or copying private-key content:
For PostgreSQL client certificates, cn must match the database role expected by HBA/cert authentication. Install the certificate, key, and root certificate on the client. Set the private key permissions to 0600. With sslmode=verify-full, the connection hostname must appear in the server certificate SAN.
Trust the CA Certificate
Distribute only the public ca.crt. Never distribute ca.key. Verify its SHA-256 fingerprint through a separate trusted channel before installation.
Debian / Ubuntu
RHEL / Rocky / AlmaLinux
macOS
Windows (Administrator PowerShell)
Infra Nginx normally exposes the public CA certificate at http://<infra_ip>/ca.crt. Verify the fingerprint after download. HTTP transport alone does not prove certificate authenticity.
Nginx and Let’s Encrypt
Each infra_portal entry can name a certbot certificate. Pigsty’s /etc/nginx/sign-cert uses Certbot webroot mode. It groups domain and domains entries that share a certificate name. Then /etc/nginx/link-cert links the resulting certificate into Nginx.
Prerequisites:
- Public DNS A/AAAA records resolve to the intended Infra node.
- Port 80 is publicly reachable for HTTP-01, and Nginx serves the ACME webroot.
certbot_emailis valid and the Certbot package is installed.- Portal domains, additional domains, and certificate names are exact.
Update the Nginx configuration and issue certificates:
In v4.5.0, the nginx_certbot task has ignore_errors: true. A playbook that continues or reports overall success does not prove certificate issuance. Inspect Certbot state, certificate files, Nginx configuration, and a real TLS handshake.
Renewal scheduling depends on the Certbot package for the operating system. Do not add a duplicate cron job before checking existing timers and cron configuration:
After Certbot replaces certificates on disk, Nginx still needs a reload to use them. Configure a renewal deploy hook, such as systemctl reload nginx, or an equivalent managed process. Verify that it works. Treat automatic renewal as proven only after a real or staging renewal exercise.
Troubleshooting and Acceptance
| Symptom | Check |
|---|---|
| Browser rejects an internal cert | Correct ca.crt, SAN hostname, and system time |
verify-full fails | Connection hostname, SAN, chain, and root certificate |
| Certbot HTTP-01 fails | DNS, port 80, ACME webroot, proxy/CDN, and rate limits |
| Playbook succeeds but old cert remains | Ignored nginx_certbot errors, link-cert, and Nginx reload |
| Permission denied | Private key 0600 (deployed Nginx key is 0640 root:nginx) |
| Trust breaks after CA rotation | Roll out client trust, then service certs, then reload services |
For final acceptance, verify each result separately:
- The certificate content and SANs are correct.
- Chain validation succeeds.
- The service has loaded the new certificate.
- Target clients trust the certificate.
- Renewal is configured and passes a dry run.
A generated file or successful playbook alone does not prove these results.
6 - Grafana High Availability: Using PostgreSQL Backend
You can use PostgreSQL as Grafana’s backend database.
This tutorial explains the Pigsty deployment system through these tasks:
- How to create a new database cluster
- How to create new business users in an existing cluster
- How to create new business databases in an existing cluster
- How to access databases created by Pigsty
- How to manage Grafana dashboards
- How to manage PostgreSQL datasources in Grafana
- How to upgrade Grafana database in one step
TL;DR
Create Database Cluster
You can define a grafana database on pg-meta. You can also create a dedicated pg-grafana cluster on new nodes.
Define Cluster
To create a new dedicated cluster pg-grafana on machines 10.10.10.11 and 10.10.10.12, use this config:
Create Cluster
Use this command to create the pg-grafana cluster: pgsql.yml.
This command is the Ansible Playbook pgsql.yml for creating database clusters.
Cluster initialization automatically creates the users and databases in pg_users and pg_databases. After cluster creation, any of these connection strings provides database access without DNS:
Pigsty defaults to a single meta node. The following steps use its existing pg-meta cluster for the Grafana user and database. They do not use the pg-grafana cluster created above.
Create Grafana Business User
Create the user before the database. A database with an owner depends on that user.
Define User
To create user dbuser_grafana on the pg-meta cluster, first add this user definition to pg-meta’s cluster definition:
Location: all.children.pg-meta.vars.pg_users
If you define a different password here, replace the corresponding parameter in subsequent steps
Create User
Use this command to create the dbuser_grafana user (either works):
This actually calls the Ansible Playbook pgsql-user.yml to create the user:
The dbrole_admin role has permission to execute DDL changes in the database, which is exactly what Grafana needs.
Create Grafana Business Database
Define Database
Creating a business database follows the same pattern as users. First add the new database grafana definition to pg-meta’s cluster definition.
Location: all.children.pg-meta.vars.pg_databases
Create Database
Use this command to create the grafana database (either works):
This actually calls the Ansible Playbook pgsql-db.yml to create the database:
Use Grafana Business Database
Verify Connection String Reachability
You can access the database using different services or access methods, for example:
Here, we’ll use the Default service that directly accesses the primary through load balancer.
First verify the connection string is reachable and has DDL execution permissions:
Directly Modify Grafana Config
To make Grafana use a Postgres datasource, edit /etc/grafana/grafana.ini and modify the config:
Change the default config to:
Then restart Grafana:
Activity in the new grafana database indicates that Grafana now uses PostgreSQL as its main backend.
The original Grafana dashboards and datasources are absent from this new backend. Import the dashboards and Postgres datasources again.
Manage Grafana Dashboards
As admin user, navigate to the files/grafana directory under the Pigsty directory and run grafana.py init to reload Pigsty dashboards.
Execution result:
The script detects the environment defined in ~/pigsty during installation. It gets Grafana access information and replaces dashboard URL placeholders (*.pigsty) with actual domains.
Use grafana.py clean to delete target dashboards. Use grafana.py load to load all dashboards from the current directory. When Pigsty dashboards change, use these two commands to upgrade all dashboards.
Manage Postgres Datasources
Pigsty registers PostgreSQL datasources in Grafana when pgsql.yml creates a cluster or pgsql-db.yml creates a business database. You can directly access target database instances through Grafana using the default monitoring user. Most pgcat application features depend on this.
To register Postgres databases, use the register_grafana task in pgsql.yml:
One-Step Grafana Upgrade
Change the Pigsty configuration to switch the Grafana backend database in one step. Edit the grafana_pgurl parameter in pigsty.yml:
Then re-run the grafana task from infra.yml to complete the Grafana upgrade: