Get Started
Module:
Pigsty allows you to download, install, load, and create PostgreSQL extensions declaratively with the PGSQL
module.
Out of the Box
Pigsty abstracts away the complexity of extension management, allowing you to declare your extensions in the config inventory:
For example, the following configuration snippet declares a PostgreSQL cluster that downloads, installs, dynamically loads, and enables 3 extensions:
all:
children:
pg-meta:
hosts: {10.10.10.10: { pg_seq: 1, pg_role: primary }}
vars:
pg_cluster: pg-meta
pg_databases: {name: meta, extensions: [ postgis, timescaledb, vector ]} # Enable 3 extensions (using extension names)
pg_libs: 'timescaledb, pg_stat_statements, auto_explain' # Load 3 extensions (last 2 are built-in)
pg_extensions: [ pgsql-main, postgis pgvector timescaledb ] # Install 3 additional extensions
repo_extra_packages: [ postgis, timescaledb, vector ] # Download 3 extension packages
When you run the ./install.yml
playbook, these 3 extension packages will be downloaded to the local repo,
and the newly created PostgreSQL cluster pg-meta
will automatically install, load, and enable these specified extensions.
Concept
Using extensions in a PostgreSQL cluster involves 4 essential operations: download, install, load, and enable:
-
How to download extensions:
repo_extra_packages
By default, Pigsty’s online installation only downloads three extensions for the current PostgreSQL major version (
pg_repack
,wal2json
,pgvector
).To download extra extensions, add them to
repo_extra_packages
. use the extension package alias and category alias for batch download. -
Which extensions to install:
pg_extensions
Pigsty’s configuration templates include a comprehensive list of available extensions. Simply add the extensions you want to install to
pg_extensions
.To install additional extensions after cluster creation, configure the extensions and run
./pgsql.yml -t pg_extension
. -
Which extensions to load:
pg_libs
Some extensions using PostgreSQL hook functions must be dynamically loaded and require a database restart to take effect. Add these extensions to
pg_libs
.For existing clusters, modify the cluster config by changing the
shared_preload_libraries
parameter and restart the database. -
Which extensions to create:
pg_databases.extensions
Most extensions require executing the
CREATE EXTENSION
DDL statement after installation to be enabled in a specific database.You can execute this DDL manually or specify extensions to enable in
pg_databases.extensions
, which will be automatically enabled during cluster initialization.
Package Alias
When loading and enabling extensions, we use “extension names” (ext
),
while for downloading and installing, we use “extension package names” (pkg
or alias
).
For example, the vector database extension’s name ext
is vector
, while its pkg
is pgvector
.
flowchart LR ext[( EXTNAME )] -- "n:1" --> pkg[( PKGNAME )] pkg[( PKGNAME )] -- "1:n" --> packages[( RPM/DEB )]
The extension alias is an abstraction layer added by Pigsty to address package name differences across OS distros.
In most cases, extension names (ext
) and package names (pkg
) are identical. However, one extension pkg
may contain multiple ext
extension objects.
For example, the postgis
package includes postgis
and 6+ extensions.
Additionally, some extension names ext
conflict with OS packages (lkie acl
, vector
), so you must use the extension package name (pkg
) for downloading and installation.
In Pigsty, you can use extension package names (pkg
) in parameters like repo_extra_packages
, pg_packages
, and pg_extensions
.
To install the postgis
extension, you can use:
pkg
alias provided by Pigsty, which will translate to actual RPM/DEB package names based on active PG version and OS.- Real package names with
$v
placeholders, automatically replaced with the value ofpg_version
. - Original OS RPM/DEB package names with
*
wildcards or specified each directly
postgis # Extension alias, auto-translated to appropriate package name
postgis35_$v* # RPM package name pattern with PG version placeholder
postgis35_15* # Direct RPM package name
postgresql-$v-postgis-3* # DEB package name pattern with PG version placeholder
postgresql-14-postgis-3* # Direct DEB package name
Extension-to-package mappings are available on the Extension List page. Each extension package corresponds to different RPM/DEB packages depending on OS and PostgreSQL version combinations.
We recommend using Pigsty’s standardized extension alias (pkg
) for installation.
Pigsty translates these names into appropriate package names for your specific OS/PG combination, eliminating the need to manage these differences manually.
There are slight variations in available extensions across operating systems and architectures. For authoritative references, check these configuration files:
- EL8 : x86_64 , aarch64
- EL9 : x86_64 , aarch64
- D12 : x86_64 , aarch64
- U22 : x86_64 , aarch64
- U24 : x86_64 , aarch64
Pigsty strives to align PostgreSQL extensions between EL and Debian operating systems, but some extensions remain difficult to port or haven’t yet been ported. See the RPM Extensions List and DEB Extensions List for more information.
Complex Example
Here’s a concrete example: the app/supa
configuration template used to build Supabase:
Supabase is an “open source Firebase alternative” built on PostgreSQL that heavily uses extensions. The following snippet defines the extensions needed by Supabase:
all:
children:
# pg-meta, the underlying postgres database for supabase
pg-meta:
hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }
vars:
pg_cluster: pg-meta
pg_users:
# supabase roles: anon, authenticated, dashboard_user
- { name: anon ,login: false }
- { name: authenticated ,login: false }
- { name: dashboard_user ,login: false ,replication: true ,createdb: true ,createrole: true }
- { name: service_role ,login: false ,bypassrls: true }
# supabase users: please use the same password
- { name: supabase_admin ,password: 'DBUser.Supa' ,pgbouncer: true ,inherit: true ,roles: [ dbrole_admin ] ,superuser: true ,replication: true ,createdb: true ,createrole: true ,bypassrls: true }
- { name: authenticator ,password: 'DBUser.Supa' ,pgbouncer: true ,inherit: false ,roles: [ dbrole_admin, authenticated ,anon ,service_role ] }
- { name: supabase_auth_admin ,password: 'DBUser.Supa' ,pgbouncer: true ,inherit: false ,roles: [ dbrole_admin ] ,createrole: true }
- { name: supabase_storage_admin ,password: 'DBUser.Supa' ,pgbouncer: true ,inherit: false ,roles: [ dbrole_admin, authenticated ,anon ,service_role ] ,createrole: true }
- { name: supabase_functions_admin ,password: 'DBUser.Supa' ,pgbouncer: true ,inherit: false ,roles: [ dbrole_admin ] ,createrole: true }
- { name: supabase_replication_admin ,password: 'DBUser.Supa' ,replication: true ,roles: [ dbrole_admin ]}
- { name: supabase_read_only_user ,password: 'DBUser.Supa' ,bypassrls: true ,roles: [ dbrole_readonly, pg_read_all_data ] }
pg_databases:
- name: postgres
baseline: supabase.sql
owner: supabase_admin
comment: supabase postgres database
schemas: [ extensions ,auth ,realtime ,storage ,graphql_public ,supabase_functions ,_analytics ,_realtime ]
extensions: # Extensions to enable in the postgres database
- { name: pgcrypto ,schema: extensions } # Encryption functions
- { name: pg_net ,schema: extensions } # Asynchronous HTTP
- { name: pgjwt ,schema: extensions } # JSON Web Token API for PostgreSQL
- { name: uuid-ossp ,schema: extensions } # Generate universally unique identifiers (UUIDs)
- { name: pgsodium } # Modern cryptography for PostgreSQL
- { name: supabase_vault } # Supabase Vault extension
- { name: pg_graphql } # GraphQL support
- { name: pg_jsonschema } # JSON schema validation
- { name: wrappers } # Collection of foreign data wrappers
- { name: http } # Web page retrieval within the database
- { name: pg_cron } # Job scheduler for PostgreSQL
- { name: timescaledb } # Time-series data support
- { name: pg_tle } # Trusted Language Extensions for PostgreSQL
- { name: vector } # Vector similarity search
- { name: pgmq } # Lightweight message queue
# supabase required extensions for loading
pg_libs: 'timescaledb, plpgsql, plpgsql_check, pg_cron, pg_net, pg_stat_statements, auto_explain, pg_tle, plan_filter'
pg_parameters:
cron.database_name: postgres
pgsodium.enable_event_trigger: off
pg_hba_rules: # supabase hba rules, require access from docker network
- { user: all ,db: postgres ,addr: intra ,auth: pwd ,title: 'allow supabase access from intranet' }
- { user: all ,db: postgres ,addr: 172.17.0.0/16 ,auth: pwd ,title: 'allow access from local docker network' }
node_crontab: [ '00 01 * * * postgres /pg/bin/pg-backup full' ] # make a full backup every 1am
vars: # Global parameter configuration
pg_version: 17
repo_modules: node,pgsql,infra,docker
repo_packages: [node-bootstrap, infra-package, infra-addons, node-package1, node-package2, pgsql-utility, docker ]
repo_extra_packages: [pg17-core ,pg17-time ,pg17-gis ,pg17-rag ,pg17-fts ,pg17-olap ,pg17-feat ,pg17-lang ,pg17-type ,pg17-util ,pg17-func ,pg17-admin ,pg17-stat ,pg17-sec ,pg17-fdw ,pg17-sim ,pg17-etl ]
pg_extensions: [pg17-time ,pg17-gis ,pg17-rag ,pg17-fts ,pg17-feat ,pg17-lang ,pg17-type ,pg17-util ,pg17-func ,pg17-admin ,pg17-stat ,pg17-sec ,pg17-fdw ,pg17-sim ,pg17-etl ] #,pg17-olap]
In this example, we declare a PostgreSQL cluster named pg-meta
with the following extension configuration:
repo_extra_packages
: Batch download all available extensions by 16 major categoriespg_extensions
: Install all extension packages except forpg17-olap
pg_libs
: Dynamically load the extensions required by Supabasepg_parameters
: Set configuration parameters needed by extensions (e.g.,pgsodium
andpg_cron
)pg_databases.extensions
: Specify which extensions to enable and in which schema
The baseline: supabase.sql
includes additional SQL migration logic for custom extension configuration.
By simply executing ./install.yml
, users get a fully configured PostgreSQL cluster with all the extensions Supabase requires, ready to use out of the box!
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.