# PgAdmin - PostgreSQL Web Administration ## Overview PgAdmin 4 is a web-based administration and management tool for PostgreSQL. It is deployed on **Portia** alongside the shared PostgreSQL instance, providing a graphical interface for database management, query execution, and server monitoring across both PostgreSQL deployments (Portia and Titania). **Host:** portia.incus **Role:** database **Container Port:** 80 (Apache / pgAdmin4 web app) **External Access:** https://pgadmin.ouranos.helu.ca/ (via HAProxy on Titania, proxied through host port 25555) ## Architecture ``` ┌──────────┐ ┌────────────┐ ┌──────────────────────────────────┐ │ Client │─────▶│ HAProxy │─────▶│ Portia │ │ │ │ (Titania) │ │ │ │ │ │ :443 │ │ :25555 ──▶ :80 (Apache) │ └──────────┘ └────────────┘ │ │ │ │ ┌────▼─────┐ │ │ │ PgAdmin4 │ │ │ │ (web) │ │ │ └────┬─────┘ │ │ │ │ │ ┌────────▼────────┐ │ │ │ PostgreSQL 17 │ │ │ │ (localhost) │ │ │ └─────────────────┘ │ └──────────┬─────────────────────┘ │ SSL ▼ ┌─────────────────────┐ │ PostgreSQL 17 (SSL) │ │ (Titania) │ └─────────────────────┘ ``` PgAdmin connects to: - **Portia's PostgreSQL** — locally via `localhost:5432` (no SSL) - **Titania's PostgreSQL** — over the Incus network via SSL, using the fetched certificate stored at `/var/lib/pgadmin/certs/titania-postgres-ca.crt` ## Terraform Resources ### Host Definition PgAdmin runs on Portia, defined in `terraform/containers.tf`: | Attribute | Value | |-----------|-------| | Image | noble | | Role | database | | Security Nesting | false | | Proxy Devices | `25555 → 80` (Apache/PgAdmin web UI) | The Incus proxy device maps host port 25555 to Apache on port 80 inside the container, where PgAdmin4 is served as a WSGI application. ## Ansible Deployment ### Playbook ```bash cd ansible ansible-playbook pgadmin/deploy.yml ``` ### Files | File | Purpose | |------|---------| | `pgadmin/deploy.yml` | PgAdmin installation and SSL cert distribution | ### Deployment Steps 1. **Add PgAdmin repository** — Official pgAdmin4 APT repository with GPG key 2. **Install PgAdmin** — `pgadmin4-web` package (includes Apache configuration) 3. **Create certs directory** — `/var/lib/pgadmin/certs/` owned by `www-data` 4. **Fetch Titania SSL certificate** — Retrieves the self-signed PostgreSQL SSL cert from Titania 5. **Distribute certificate** — Copies to `/var/lib/pgadmin/certs/titania-postgres-ca.crt` for SSL connections ### ⚠️ Manual Post-Deployment Step Required After running the playbook, you **must** SSH into Portia and run the PgAdmin web setup script manually: ```bash # SSH into Portia ssh portia.incus # Run the setup script sudo /usr/pgadmin4/bin/setup-web.sh ``` This interactive script: - Prompts for the **admin email address** and **password** (use the values from `pgadmin_email` and `pgadmin_password` vault variables) - Configures Apache virtual host for PgAdmin4 - Sets file permissions and ownership - Restarts Apache to activate the configuration This step cannot be automated via Ansible because the script requires interactive input and performs Apache configuration that depends on the local environment. ### Variables #### Host Variables (`host_vars/portia.incus.yml`) | Variable | Description | |----------|-------------| | `pgadmin_user` | System user (`pgadmin`) | | `pgadmin_group` | System group (`pgadmin`) | | `pgadmin_directory` | Data directory (`/srv/pgadmin`) | | `pgadmin_port` | External port (`25555`) | | `pgadmin_email` | Admin login email (`{{ vault_pgadmin_email }}`) | | `pgadmin_password` | Admin login password (`{{ vault_pgadmin_password }}`) | #### Vault Variables (`group_vars/all/vault.yml`) | Variable | Description | |----------|-------------| | `vault_pgadmin_email` | PgAdmin admin email address | | `vault_pgadmin_password` | PgAdmin admin password | ## Configuration ### SSL Certificate for Titania Connection The playbook fetches the self-signed PostgreSQL SSL certificate from Titania and places it at `/var/lib/pgadmin/certs/titania-postgres-ca.crt`. When adding Titania's PostgreSQL as a server in PgAdmin: 1. Navigate to **Servers → Register → Server** 2. On the **Connection** tab: - Host: `titania.incus` - Port: `5432` - Username: `postgres` 3. On the **SSL** tab: - SSL mode: `verify-ca` or `require` - Root certificate: `/var/lib/pgadmin/certs/titania-postgres-ca.crt` ### Registered Servers After setup, register both PostgreSQL instances: | Server Name | Host | Port | SSL | |-------------|------|------|-----| | Portia (local) | `localhost` | `5432` | Off | | Titania (Casdoor) | `titania.incus` | `5432` | verify-ca | ## Operations ### Start/Stop ```bash # PgAdmin runs under Apache sudo systemctl start apache2 sudo systemctl stop apache2 sudo systemctl restart apache2 ``` ### Health Check ```bash # Check Apache is serving PgAdmin curl -s -o /dev/null -w "%{http_code}" http://localhost/pgadmin4/login # Check from external host curl -s -o /dev/null -w "%{http_code}" http://portia.incus/pgadmin4/login ``` ### Logs ```bash # Apache error log tail -f /var/log/apache2/error.log # PgAdmin application log tail -f /var/log/pgadmin/pgadmin4.log ``` ## Troubleshooting ### Common Issues | Symptom | Cause | Resolution | |---------|-------|------------| | 502/503 on pgadmin.ouranos.helu.ca | Apache not running on Portia | `sudo systemctl restart apache2` on Portia | | Login page loads but can't authenticate | Setup script not run | SSH to Portia and run `sudo /usr/pgadmin4/bin/setup-web.sh` | | Can't connect to Titania PostgreSQL | Missing SSL certificate | Re-run `ansible-playbook pgadmin/deploy.yml` to fetch cert | | SSL certificate error for Titania | Certificate expired or regenerated | Re-fetch cert by re-running the playbook | | Port 25555 unreachable | Incus proxy device missing | Verify proxy device in `terraform/containers.tf` for Portia | ## References - [PgAdmin 4 Documentation](https://www.pgadmin.org/docs/pgadmin4/latest/) - [PostgreSQL Deployment](postgresql.md) - [Terraform Practices](terraform.md) - [Ansible Practices](ansible.md)