Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018BAUeCFpDkRD6tU5wGsc1C
109 lines
4.1 KiB
Plaintext
109 lines
4.1 KiB
Plaintext
# =============================================================================
|
|
# PostgreSQL 15 - production Xpeditis
|
|
# Cible : Hetzner CPX31 (4 vCPU / 8 Go), partage avec Redis (1,5 Go plafonne).
|
|
# Budget memoire retenu pour PostgreSQL : ~6 Go.
|
|
# =============================================================================
|
|
|
|
# --- Connexions --------------------------------------------------------------
|
|
listen_addresses = '*' # le confinement reseau est assure par le bind
|
|
# Docker sur l'IP privee + UFW + pg_hba
|
|
port = 5432
|
|
max_connections = 150 # 2 replicas backend x pool TypeORM + marge ops
|
|
superuser_reserved_connections = 5
|
|
|
|
# --- TLS ---------------------------------------------------------------------
|
|
# Obligatoire : pg_hba n'accepte que des lignes `hostssl`. Le reseau prive
|
|
# Hetzner n'est pas chiffre par l'hyperviseur, c'est nous qui le chiffrons.
|
|
ssl = on
|
|
ssl_cert_file = '/var/lib/xpeditis/certs/server.crt'
|
|
ssl_key_file = '/var/lib/xpeditis/certs/server.key'
|
|
ssl_min_protocol_version = 'TLSv1.2'
|
|
ssl_prefer_server_ciphers = on
|
|
|
|
# --- Authentification --------------------------------------------------------
|
|
password_encryption = scram-sha-256
|
|
|
|
# --- Memoire -----------------------------------------------------------------
|
|
shared_buffers = 2GB
|
|
effective_cache_size = 5GB
|
|
maintenance_work_mem = 512MB
|
|
work_mem = 16MB # par operation de tri/hash, pas par connexion
|
|
huge_pages = try
|
|
|
|
# --- Disque (SSD NVMe Hetzner) ----------------------------------------------
|
|
random_page_cost = 1.1
|
|
effective_io_concurrency = 200
|
|
max_worker_processes = 4
|
|
max_parallel_workers = 4
|
|
max_parallel_workers_per_gather = 2
|
|
max_parallel_maintenance_workers = 2
|
|
|
|
# --- WAL / archivage ---------------------------------------------------------
|
|
wal_level = replica # suffisant pour PITR + futur standby physique
|
|
wal_compression = on
|
|
max_wal_size = 4GB
|
|
min_wal_size = 1GB
|
|
checkpoint_completion_target = 0.9
|
|
checkpoint_timeout = 15min
|
|
|
|
archive_mode = on
|
|
archive_command = 'wal-g wal-push %p'
|
|
# Force la cloture d'un segment WAL toutes les 5 min meme sans activite :
|
|
# c'est ce qui plafonne le RPO a 5 minutes de donnees perdues au maximum.
|
|
archive_timeout = 300
|
|
|
|
# Conserve de quoi rattacher un standby sans repartir d'un basebackup.
|
|
max_wal_senders = 5
|
|
wal_keep_size = 1GB
|
|
max_replication_slots = 5
|
|
|
|
# --- Autovacuum --------------------------------------------------------------
|
|
# audit_logs et csv_rates subissent beaucoup d'ecritures : on vacuume plus tot
|
|
# que les valeurs par defaut, sinon les index gonflent et les recherches
|
|
# tarifaires ralentissent.
|
|
autovacuum = on
|
|
autovacuum_max_workers = 3
|
|
autovacuum_naptime = 30s
|
|
autovacuum_vacuum_scale_factor = 0.05
|
|
autovacuum_analyze_scale_factor = 0.02
|
|
autovacuum_vacuum_cost_limit = 1000
|
|
|
|
# --- Delais de garde ---------------------------------------------------------
|
|
statement_timeout = 300000 # 5 min : borne les requetes folles
|
|
# tout en laissant passer les
|
|
# imports CSV de grilles
|
|
idle_in_transaction_session_timeout = 300000 # 5 min : libere les verrous oublies
|
|
lock_timeout = 30000
|
|
tcp_keepalives_idle = 60
|
|
tcp_keepalives_interval = 10
|
|
tcp_keepalives_count = 6
|
|
|
|
# --- Observabilite -----------------------------------------------------------
|
|
shared_preload_libraries = 'pg_stat_statements'
|
|
pg_stat_statements.max = 5000
|
|
pg_stat_statements.track = top
|
|
track_io_timing = on
|
|
track_functions = pl
|
|
|
|
logging_collector = off # les logs partent sur stdout -> Docker -> Loki
|
|
log_destination = 'stderr'
|
|
log_min_duration_statement = 500 # trace toute requete > 500 ms
|
|
log_line_prefix = '%m [%p] %q%u@%d %a '
|
|
log_checkpoints = on
|
|
log_connections = on
|
|
log_disconnections = on
|
|
log_lock_waits = on
|
|
log_temp_files = 0
|
|
log_autovacuum_min_duration = 1000
|
|
log_statement = 'ddl' # trace les changements de schema (migrations)
|
|
log_timezone = 'Europe/Paris'
|
|
|
|
# --- Localisation ------------------------------------------------------------
|
|
timezone = 'Europe/Paris'
|
|
datestyle = 'iso, mdy'
|
|
lc_messages = 'C'
|
|
lc_monetary = 'C'
|
|
lc_numeric = 'C'
|
|
lc_time = 'C'
|
|
default_text_search_config = 'pg_catalog.french'
|