Databases

Install PostgreSQL on Void Linux

Void Linux is one of those distributions that rewards you for understanding how your system works. No systemd, no hand-holding, just runit and XBPS doing exactly what you tell them. PostgreSQL fits right into that philosophy: a database engine that does one thing extremely well and stays out of your way.

Original content from computingforgeeks.com - post 165029

This guide walks through installing PostgreSQL 16 on Void Linux, initializing the database cluster, creating a runit service from scratch (Void doesn’t ship one), and locking down authentication. If you’re coming from Debian or RHEL, the biggest difference is the service management piece, which we’ll cover in detail. For PostgreSQL on RHEL-based systems, see PostgreSQL on Rocky Linux 10.

Tested March 2026 | Void Linux (glibc), PostgreSQL 16.10

Prerequisites

  • Void Linux (glibc variant, x86_64) with root or sudo access
  • XBPS package manager up to date
  • Tested on: Void Linux rolling (glibc), PostgreSQL 16.10

1. Install PostgreSQL

Void’s XBPS repository ships PostgreSQL 16.x. Install the server and client packages:

sudo xbps-install -Sy postgresql16 postgresql16-client

Confirm the installed version:

psql --version

You should see the version string confirming 16.x:

psql (PostgreSQL) 16.10

XBPS creates a postgres system user automatically during installation. Verify it exists:

id postgres

The output confirms the user and group:

uid=997(postgres) gid=997(postgres) groups=997(postgres)

2. Initialize the Database Cluster

PostgreSQL needs an initialized data directory before it can start. Create the directory and set ownership to the postgres user:

sudo mkdir -p /var/lib/postgresql/data
sudo chown postgres:postgres /var/lib/postgresql/data

Now initialize the cluster. This must run as the postgres user:

sudo -u postgres initdb -D /var/lib/postgresql/data

The initialization output shows the cluster being created with default settings:

The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.

The database cluster will be initialized with locale "en_US.UTF-8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".

Data page checksums are disabled.

fixing permissions on existing directory /var/lib/postgresql/data ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default "max_connections" ... 100
selecting default "shared_buffers" ... 128MB
selecting default "timezone" ... UTC
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok

initdb: warning: enabling "trust" authentication for local connections
initdb: hint: You can change this by editing pg_hba.conf or using the option -A,
or --auth-local and --auth-host, the next time you run initdb.

Success. You can now start the database server using:

    pg_ctl -D /var/lib/postgresql/data -l logfile start

Notice the warning about trust authentication. We’ll tighten that up after getting the service running.

3. Create a Runit Service

Void Linux uses runit for service management, and PostgreSQL doesn’t ship with a runit service file by default. You need to create one manually. This catches most people off guard when coming from distributions where systemctl enable postgresql just works.

Create the service directory structure:

sudo mkdir -p /etc/sv/postgresql/log

Create the main run script that starts PostgreSQL as the postgres user:

sudo vi /etc/sv/postgresql/run

Add the following content:

#!/bin/sh
exec chpst -u postgres postgres -D /var/lib/postgresql/data 2>&1

Make it executable:

sudo chmod +x /etc/sv/postgresql/run

Now create the log service. Runit expects a log/run script to capture output via svlogd:

sudo vi /etc/sv/postgresql/log/run

Add the logging script:

#!/bin/sh
exec svlogd -tt /var/log/postgresql

Make it executable and create the log directory:

sudo chmod +x /etc/sv/postgresql/log/run
sudo mkdir -p /var/log/postgresql

Enable the service by creating a symlink to /var/service/. Runit picks it up automatically within a few seconds:

sudo ln -s /etc/sv/postgresql /var/service/

Check the service status:

sudo sv status postgresql

A healthy service looks like this:

run: postgresql: (pid 1423) 5s; run: log: (pid 1420) 5s

If the status shows down, check the log at /var/log/postgresql/current for errors. Common causes include wrong permissions on the data directory or a missing postgres user.

4. Secure the Installation

The default initdb configuration uses trust authentication for local connections, which means any local user can connect as any database user without a password. Fix this by setting a password for the postgres superuser and switching to password-based authentication.

Connect to PostgreSQL and set the superuser password:

sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'StrongPassword123!';"

The response confirms the change:

ALTER ROLE

Now edit pg_hba.conf to enforce password authentication. Open the file:

sudo vi /var/lib/postgresql/data/pg_hba.conf

Find the lines near the bottom that control local connections and change trust to scram-sha-256:

# "local" is for Unix domain socket connections only
local   all             all                                     scram-sha-256
# IPv4 local connections:
host    all             all             127.0.0.1/32            scram-sha-256
# IPv6 local connections:
host    all             all             ::1/128                 scram-sha-256

Reload PostgreSQL to apply the changes without dropping existing connections:

sudo -u postgres pg_ctl reload -D /var/lib/postgresql/data

The reload confirmation:

server signaled

From now on, every connection requires a password. Test it:

psql -U postgres -h 127.0.0.1 -c "SELECT version();"

Enter the password you set earlier. The query output shows your running version:

                                                version
---------------------------------------------------------------------------------------------------------
 PostgreSQL 16.10 on x86_64-unknown-linux-gnu, compiled by gcc (GCC) 13.2.0, 64-bit
(1 row)

5. Create a Database and User

Production applications should never connect as the postgres superuser. Create a dedicated user and database for your application.

Connect as the superuser first:

psql -U postgres -h 127.0.0.1

Create a new user, database, and grant privileges. This is an interactive psql session:

CREATE USER appuser WITH PASSWORD 'AppUserPass456!';
CREATE DATABASE appdb OWNER appuser;
GRANT ALL PRIVILEGES ON DATABASE appdb TO appuser;
\q

Verify the new user can connect to the database:

psql -U appuser -h 127.0.0.1 -d appdb -c "\conninfo"

The connection info confirms the user and database:

You are connected to database "appdb" as user "appuser" on host "127.0.0.1" at port "5432".

6. Enable Remote Connections (Optional)

By default, PostgreSQL 16 listens only on localhost. If other machines on your network need to connect, you’ll need to change the listen address and add a firewall rule.

Open the main configuration file:

sudo vi /var/lib/postgresql/data/postgresql.conf

Find the listen_addresses line and change it to listen on all interfaces:

listen_addresses = '*'

Next, add a line to pg_hba.conf to allow connections from your network. Open the file:

sudo vi /var/lib/postgresql/data/pg_hba.conf

Add this line at the end, adjusting the subnet to match your network:

# Allow connections from local network
host    all             all             10.0.1.0/24             scram-sha-256

Restart PostgreSQL to apply the listen address change (a reload isn’t enough for listen_addresses):

sudo sv restart postgresql

Void Linux uses nftables for firewalling. Allow TCP port 5432:

sudo nft add rule inet filter input tcp dport 5432 accept

To make the firewall rule persistent across reboots, save the current ruleset:

sudo nft list ruleset | sudo tee /etc/nftables.conf

Verify PostgreSQL is listening on all interfaces:

ss -tlnp | grep 5432

The output should show 0.0.0.0:5432 instead of 127.0.0.1:5432:

LISTEN 0      244          0.0.0.0:5432       0.0.0.0:*    users:(("postgres",pid=1423,fd=6))

7. Basic psql Commands

Quick reference for the most common psql commands you’ll use daily. Connect with psql -U postgres -h 127.0.0.1 and run these from the psql prompt:

CommandDescription
\lList all databases
\dtList tables in the current database
\c dbnameConnect to a different database
\d tablenameDescribe a table (columns, types, indexes)
\duList all roles/users
SELECT version();Show the PostgreSQL server version
\timingToggle query execution time display
\xToggle expanded (vertical) output
\qExit psql

PostgreSQL on Void vs Other Distros

If you manage PostgreSQL across multiple distributions, these are the key differences to keep in mind:

ItemVoid LinuxDebian/UbuntuRHEL/Rocky 10
Package namepostgresql16postgresql-16postgresql16-server
Data directory/var/lib/postgresql/data/var/lib/postgresql/16/main/var/lib/pgsql/16/data
Config path/var/lib/postgresql/data//etc/postgresql/16/main//var/lib/pgsql/16/data/
Service managerrunit (manual setup)systemdsystemd
Start commandsv up postgresqlsystemctl start postgresqlsystemctl start postgresql-16
Auto-init on installNoYesNo (postgresql-setup --initdb)
Firewallnftablesufwfirewalld
SELinux/AppArmorNeitherAppArmor (usually permissive)SELinux enforcing

The biggest difference on Void is the manual service setup. On Debian, the package creates the cluster and starts the service automatically. On Void, you handle both yourself, which gives you full control over the data directory location and startup flags.

Tuning for Production

PostgreSQL’s default configuration is deliberately conservative. On a dedicated database server, you’ll want to adjust these settings in postgresql.conf. The values below assume a server with 4 GB of RAM.

sudo -u postgres vi /var/lib/postgresql/data/postgresql.conf

Key parameters to change:

# Memory (adjust proportionally to your RAM)
shared_buffers = 1GB              # 25% of total RAM
effective_cache_size = 3GB        # 75% of total RAM
work_mem = 16MB                   # per-operation sort memory
maintenance_work_mem = 256MB      # for VACUUM, CREATE INDEX

# WAL and checkpoints
wal_buffers = 64MB
checkpoint_completion_target = 0.9
max_wal_size = 2GB

# Connections
max_connections = 100             # lower this if using pgbouncer

After editing, reload the configuration without restarting:

sudo sv reload postgresql

Some parameters (like shared_buffers and max_connections) require a full restart to take effect. Check the PostgreSQL 16 documentation for which settings need a restart versus a reload. For a web application backend, pairing this with a LAMP or Nginx stack on the same Void Linux host works well for small to medium deployments.

Related Articles

Books Best Elasticsearch and ELK Stack Books for 2026 Databases How To Install MariaDB 10.9 on Debian 12/11/10 Databases Configure Custom PostgreSQL ports with SELinux Databases Install MongoDB 7.0 on Windows Server 2022|2019|2016

Leave a Comment

Press ESC to close