| .. | ||
| defaults | ||
| handlers | ||
| tasks | ||
| templates | ||
| vars | ||
| README.md | ||
PostgreSQL Role
This Ansible role installs and configures PostgreSQL for local use only. It provides a shared PostgreSQL instance that multiple services can use with isolated databases and users.
Features
- Installs PostgreSQL
- Local-only access (localhost)
- Configurable performance settings
- Each service manages its own database/user (see below)
Requirements
- Systemd-based Linux distribution
- Root/sudo access
- Python
psycopg2package (for database operations from service roles)
Role Variables
See defaults/main.yml for all available variables and their default values.
Key Configuration Requirements
Required Password
The postgres_admin_password variable must be set in your inventory (min 12 characters). The role will fail if not set.
Container Access
For containers to access PostgreSQL, set postgres_bind to include the Podman gateway:
postgres_bind: "127.0.0.1,{{ podman_subnet_gateway }}"
Dependencies
None.
Example Playbook
---
- hosts: servers
become: true
roles:
- role: postgres
- role: immich # Will create its own database
- role: nextcloud # Will create its own database
Database Isolation Strategy
This role follows a decentralized database management pattern:
1. PostgreSQL Role Responsibility
- Install and configure PostgreSQL
- Manage global performance settings
- Ensure the service is running
2. Service Role Responsibility
Each service role (immich, nextcloud, etc.) manages its own:
- Database creation
- User creation
- Password management
- Schema migrations
3. Security & Isolation
Database Isolation:
- Each service gets its own database
- Example:
immich,nextcloud,gitea
User Isolation:
- Each service gets its own PostgreSQL user
- Users can only access their own database
- Example:
immich→immichdatabase only
Authentication:
- Each user has a unique password
- Passwords stored in service role variables (use Ansible Vault for production)
Connection Methods
From Containers
If your service runs in a container (Docker/Podman), you need to configure PostgreSQL to listen on the Podman bridge gateway:
Step 1: Configure PostgreSQL in inventory
# inventory/host_vars/yourserver.yml
postgres_bind: "127.0.0.1,{{ podman_subnet_gateway }}"
postgres_firewall_allowed_sources:
- 127.0.0.0/8
- "{{ podman_subnet }}"
Step 2: Use host.containers.internal in containers
# docker-compose.yml
services:
myservice:
extra_hosts:
- "host.containers.internal:host-gateway"
environment:
DB_HOSTNAME: host.containers.internal
DB_PORT: 5432
What this does:
- PostgreSQL listens on
127.0.0.1(localhost) and10.88.0.1(Podman gateway) - UFW firewall allows connections from localhost and Podman subnet
pg_hba.confautomatically configured to allow Podman subnethost.containers.internalresolves to the gateway IP inside containers
From System Services
Services running directly on the host can connect to localhost:5432 without any special configuration.
Security Best Practices
1. Use Ansible Vault for Passwords
# Create encrypted variables
ansible-vault encrypt_string 'my_secure_password' --name 'immich_db_password'
Add to your inventory or vars:
immich_db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
...encrypted...
2. Unique Passwords per Service
Never reuse passwords between services:
immich_db_password: unique_password_1
nextcloud_db_password: unique_password_2
gitea_db_password: unique_password_3
3. Minimal Privileges
The pattern above ensures users have:
- ✅ Access to their database only
- ❌ No superuser privileges
- ❌ Cannot create databases
- ❌ Cannot create roles
- ❌ Cannot access other databases
4. Controlled Access
PostgreSQL default configuration:
- Listens on
localhostonly by default - To allow container access, set
postgres_bindto include Podman gateway - UFW firewall rules automatically configured for allowed sources
pg_hba.confautomatically configured for Podman subnet when enabled- No remote network access by default
Troubleshooting
Check PostgreSQL status
systemctl status postgresql
Connect to PostgreSQL
sudo -u postgres psql
List databases
\l
List users and permissions
\du
Test connection from service
# From localhost
psql -h localhost -U immich -d immich
# From Podman gateway (if configured)
psql -h 10.88.0.1 -U immich -d immich
# Check listen addresses
sudo -u postgres psql -c "SHOW listen_addresses;"
# Check firewall rules
sudo ufw status | grep 5432
# Check pg_hba.conf
sudo grep -v "^#" /var/lib/postgres/data/pg_hba.conf | grep -v "^$"
View logs
journalctl -u postgresql -f
Performance Tuning
Adjust variables based on your hardware:
For systems with 4GB RAM:
postgres_shared_buffers: 1GB
postgres_effective_cache_size: 3GB
For systems with 16GB RAM:
postgres_shared_buffers: 4GB
postgres_effective_cache_size: 12GB
Rule of thumb:
shared_buffers: 25% of total RAMeffective_cache_size: 50-75% of total RAM
Backup Recommendations
Consider implementing:
- pg_dump for logical backups
- WAL archiving for point-in-time recovery
- Automated backup scripts via cron
Example backup script for a service:
pg_dump -h localhost -U immich immich > /backup/immich_$(date +%Y%m%d).sql
License
MIT
Author Information
Created for managing shared PostgreSQL instances in NAS/homelab environments.