Proxmox: node1-3 → 10.0.19.101-103 Talos cp1-3 → 10.0.19.1-3, workers → 10.0.19.4-6 K8s endpoint → VIP https://10.0.19.10:6443 Ansible: prom → 10.0.19.31, db → 10.0.19.30 Talos: added VIP block to controlplane.yaml base config Promtail: Loki URL → 10.0.19.31 Docs: all references updated, talos4 removed
185 lines
4.6 KiB
YAML
185 lines
4.6 KiB
YAML
---
|
|
ansible_host: 10.0.19.30
|
|
ansible_python_interpreter: /usr/bin/python3
|
|
ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new'
|
|
|
|
firewall_trusted_subnets:
|
|
- subnet: 100.64.0.0/10
|
|
comment: Tailscale
|
|
- subnet: 10.0.8.0/21
|
|
comment: Home cluster network
|
|
|
|
firewall_allow_rules:
|
|
- port: 5432
|
|
proto: tcp
|
|
comment: PostgreSQL
|
|
- port: 6432
|
|
proto: tcp
|
|
comment: PgBouncer
|
|
|
|
# Override role defaults - this server uses default Debian paths, not RAID
|
|
postgresql_version: "17"
|
|
postgresql_storage_setup_enabled: false
|
|
postgresql_data_directory: /var/lib/postgresql/17/main
|
|
postgresql_wal_directory: /var/lib/postgresql/17/main/pg_wal
|
|
postgresql_config_directory: /etc/postgresql/17/main
|
|
postgresql_backup_enabled: false
|
|
|
|
# TimescaleDB
|
|
timescaledb_enabled: true
|
|
timescaledb_max_background_workers: 16
|
|
timescaledb_apt_repo: "deb https://packagecloud.io/timescale/timescaledb/debian/ trixie main"
|
|
|
|
# PostgreSQL config (matches live server tuning)
|
|
postgresql_config:
|
|
# Connection
|
|
listen_addresses: "'*'"
|
|
# Matches the live server (was raised from 100). With PgBouncer fronting the
|
|
# backend, real backend connections stay well under this; the headroom covers
|
|
# apps still connecting directly during/after cutover.
|
|
max_connections: 300
|
|
port: 5432
|
|
|
|
# Memory (tuned for 8GB ARM server)
|
|
shared_buffers: 2014MB
|
|
work_mem: 5157kB
|
|
maintenance_work_mem: 1031576kB
|
|
effective_cache_size: 6044MB
|
|
|
|
# Disk
|
|
random_page_cost: 1.1
|
|
effective_io_concurrency: 256
|
|
|
|
# Workers
|
|
max_worker_processes: 23
|
|
max_parallel_workers: 4
|
|
max_parallel_workers_per_gather: 2
|
|
|
|
# WAL
|
|
wal_buffers: 16MB
|
|
max_wal_size: 1GB
|
|
min_wal_size: 512MB
|
|
checkpoint_completion_target: 0.9
|
|
|
|
# Autovacuum
|
|
autovacuum_max_workers: 10
|
|
autovacuum_naptime: 10
|
|
|
|
# Query tuning
|
|
default_statistics_target: 100
|
|
jit: off
|
|
|
|
# Compression and locking
|
|
default_toast_compression: lz4
|
|
max_locks_per_transaction: 128
|
|
|
|
# Logging
|
|
log_line_prefix: "'%m [%p] %q%u@%d '"
|
|
log_timezone: "'UTC'"
|
|
cluster_name: "'17/main'"
|
|
|
|
# Locale
|
|
datestyle: "'iso, dmy'"
|
|
timezone: "'Europe/London'"
|
|
lc_messages: "'en_GB.UTF-8'"
|
|
lc_monetary: "'en_GB.UTF-8'"
|
|
lc_numeric: "'en_GB.UTF-8'"
|
|
lc_time: "'en_GB.UTF-8'"
|
|
default_text_search_config: "'pg_catalog.english'"
|
|
|
|
# Extensions
|
|
shared_preload_libraries: "'pg_stat_statements,timescaledb'"
|
|
|
|
# TimescaleDB
|
|
timescaledb.max_background_workers: 16
|
|
|
|
# SSL
|
|
ssl: on
|
|
ssl_cert_file: "'server.crt'"
|
|
ssl_key_file: "'server.key'"
|
|
|
|
# pg_hba.conf entries (matches live server)
|
|
postgresql_hba_entries:
|
|
- type: local
|
|
database: all
|
|
user: postgres
|
|
auth_method: peer
|
|
- type: local
|
|
database: all
|
|
user: all
|
|
auth_method: peer
|
|
- type: host
|
|
database: all
|
|
user: all
|
|
address: 127.0.0.1/32
|
|
auth_method: scram-sha-256
|
|
- type: host
|
|
database: all
|
|
user: all
|
|
address: "::1/128"
|
|
auth_method: scram-sha-256
|
|
- type: local
|
|
database: replication
|
|
user: all
|
|
auth_method: peer
|
|
- type: host
|
|
database: replication
|
|
user: all
|
|
address: 127.0.0.1/32
|
|
auth_method: scram-sha-256
|
|
- type: host
|
|
database: replication
|
|
user: all
|
|
address: "::1/128"
|
|
auth_method: scram-sha-256
|
|
- type: hostssl
|
|
database: all
|
|
user: all
|
|
address: 10.0.8.0/21
|
|
auth_method: scram-sha-256
|
|
|
|
# Databases and users (matches live server)
|
|
postgresql_databases:
|
|
- name: aprsme_prod
|
|
owner: aprsme
|
|
- name: gridmap
|
|
owner: gridmap
|
|
- name: towerops
|
|
owner: towerops
|
|
- name: prop
|
|
owner: prop
|
|
|
|
postgresql_users:
|
|
- name: aprsme
|
|
password: "{{ vault_postgresql_aprsme_password | default(omit) }}"
|
|
- name: gridmap
|
|
password: "{{ vault_postgresql_gridmap_password | default(omit) }}"
|
|
- name: towerops
|
|
password: "{{ vault_postgresql_towerops_password | default(omit) }}"
|
|
- name: prop
|
|
password: "{{ vault_postgresql_prop_password | default(omit) }}"
|
|
|
|
postgresql_extensions:
|
|
aprsme_prod:
|
|
- citext
|
|
- pg_stat_statements
|
|
- pg_trgm
|
|
- postgis
|
|
|
|
# --- PgBouncer ---
|
|
# Per-database backend connection pools. Sized from observed live usage in
|
|
# session mode (which pins ~1 server conn per active client): towerops runs 2
|
|
# replicas, aprsme peaks ~52, prop ~70. Sum (~210) + reserves stays under
|
|
# max_connections (300) with room for TimescaleDB workers and gridmap (direct).
|
|
# All session mode (safe for Ecto prepared statements and Oban LISTEN/NOTIFY);
|
|
# switch an app to pool_mode: transaction only after verifying it tolerates it.
|
|
pgbouncer_max_db_connections: 100
|
|
pgbouncer_databases:
|
|
- name: towerops
|
|
pool_size: 30
|
|
- name: aprsme_prod
|
|
pool_size: 60
|
|
- name: prop
|
|
pool_size: 80
|
|
- name: gridmap
|
|
pool_size: 20
|