Une base PostgreSQL fiable, sauvegardée et performante est le socle de toute application sérieuse. Avec Coolify, vous pouvez provisionner une instance PostgreSQL en un clic, mais le passage en production demande quelques précautions : tuning des paramètres, sauvegardes automatiques vers une destination S3, monitoring des requêtes lentes, stratégie de récupération en cas de crash, et sécurisation. Voici le guide complet, basé sur l’expérience de plusieurs projets en production en Afrique de l’Ouest.
Ce tutoriel s’inscrit dans notre série Coolify. Pour les bases conceptuelles, voir notre guide d’installation Coolify.
Pourquoi PostgreSQL en 2026 ?
PostgreSQL reste en 2026 la base relationnelle de référence pour la grande majorité des projets. Versions stables 16 et 17, écosystème mature (Prisma, Drizzle, TypeORM, Sequelize côté Node.js ; SQLAlchemy côté Python ; Doctrine côté PHP ; etc.), extensions puissantes (PostGIS pour le géographique, pgvector pour l’IA, pg_stat_statements pour le monitoring, TimescaleDB pour les séries temporelles, Citus pour le sharding). Postgres est aussi une excellente base pour les workloads OLTP comme OLAP modérés.
Comparé à MySQL/MariaDB, Postgres a un meilleur support des contraintes complexes, des transactions plus robustes, et un écosystème JSON natif qui en fait un excellent compagnon pour les API modernes. Pour 90 % des projets, c’est le bon choix par défaut.
Provisionner PostgreSQL via Coolify
Dans votre projet Coolify, « + New Resource » → Database → PostgreSQL. Choisissez la version (PostgreSQL 16 ou 17 en 2026), définissez un nom d’instance lisible (par exemple app-prod-db), un mot de passe robuste (Coolify peut en générer un de 32 caractères), et déployez. La base est lancée dans un conteneur Docker, exposée uniquement sur le réseau interne par défaut. C’est le bon choix : ne pas exposer Postgres publiquement sauf besoin précis.
L’URL de connexion interne ressemble à : postgres://postgres:PASSWORD@nom-instance:5432/postgres. Vous l’utilisez directement comme variable DATABASE_URL dans vos applications hébergées sur le même Coolify. Coolify résout le nom d’hôte interne nom-instance via le réseau Docker partagé.
Sécuriser l’instance
- Ne jamais exposer publiquement à moins d’avoir une bonne raison documentée. Si nécessaire (BI tool externe, équipe distante avec un client SQL), utilisez SSH tunneling depuis le VPS, ou un VPN Tailscale qui ouvre le port uniquement pour les machines autorisées.
- Mot de passe fort : 32 caractères minimum, géré dans un password manager (Bitwarden, 1Password). Régénérez-le périodiquement (annuel minimum).
- Utilisateurs séparés par application : créez un user PostgreSQL dédié par application avec privilèges minimaux. Ne réutilisez jamais le user
postgressuperuser en production. Exemple :
-- Connecté en superuser, créez un user dédié
CREATE DATABASE myapp_prod;
CREATE USER myapp_user WITH PASSWORD 'ROBUSTE_32_CARS';
GRANT CONNECT ON DATABASE myapp_prod TO myapp_user;
\c myapp_prod
GRANT USAGE ON SCHEMA public TO myapp_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO myapp_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO myapp_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT ALL ON TABLES TO myapp_user;
- SSL même en interne : forcez
sslmode=requiredans les chaînes de connexion si vous êtes paranoïaque. Coolify configure les certificats automatiquement. - pg_hba.conf restrictif : par défaut Coolify autorise les connexions du réseau Docker. N’ajoutez de règles ouvertes que ponctuellement et avec audit.
Tuning pour un VPS modeste
Les paramètres par défaut de PostgreSQL sont conservateurs et conçus pour démarrer sur n’importe quelle machine. Sur un VPS de 4 à 8 Go RAM, ajustez via postgresql.conf (Coolify expose un éditeur dans l’onglet Configuration de l’instance) :
# Pour un VPS 4 Go RAM dédié à PostgreSQL
shared_buffers = 1GB
effective_cache_size = 3GB
work_mem = 16MB
maintenance_work_mem = 256MB
max_connections = 100
random_page_cost = 1.1 # SSD/NVMe
checkpoint_completion_target = 0.9
wal_buffers = 16MB
default_statistics_target = 100
huge_pages = try
# Logs des requêtes lentes
log_min_duration_statement = 1000 # Log les requêtes > 1s
log_checkpoints = on
log_lock_waits = on
log_temp_files = 0
L’outil pgtune.leopard.in.ua génère une config personnalisée selon votre RAM et votre type de workload (web, OLTP, OLAP, mixed, desktop). Utilisez-le comme point de départ, puis ajustez après quelques semaines de prod selon les métriques réelles.
Sauvegardes automatiques
Coolify intègre nativement les backups vers une destination S3-compatible. Onglet Backups → Add. Configurez :
- Schedule cron :
0 3 * * *pour 3h du matin (heure du serveur). Adaptez à votre fenêtre de moindre activité. - Retention : 30 jours quotidiens. Pour une rétention plus complète (3-2-1), automatisez côté S3 avec des règles de cycle de vie : 30 jours en standard, puis transition vers stockage froid pour les backups mensuels.
- Destination : Backblaze B2 (ultra-économique, ~6 $/To/mois) ou MinIO auto-hébergé.
- Compression : Coolify utilise
pg_dump -Fcqui produit un format custom déjà compressé.
Notre tutoriel dédié aux backups Coolify détaille la mise en place complète, le test de restauration mensuel obligatoire et les pièges à éviter.
Monitoring et observabilité
Activez l’extension pg_stat_statements dès le départ : c’est l’outil indispensable pour identifier les requêtes lentes. Connectez-vous en SQL et exécutez :
-- Activer l'extension
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
-- Top 10 requêtes les plus coûteuses cumulées
SELECT
query,
calls,
ROUND(total_exec_time::numeric, 2) AS total_ms,
ROUND(mean_exec_time::numeric, 2) AS mean_ms,
rows
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;
-- Top 10 requêtes les plus lentes en moyenne
SELECT
query,
calls,
ROUND(mean_exec_time::numeric, 2) AS mean_ms
FROM pg_stat_statements
WHERE calls > 100
ORDER BY mean_exec_time DESC
LIMIT 10;
Ajoutez aussi pgbadger pour générer des rapports HTML hebdomadaires sur les logs. Pour une supervision continue, branchez Grafana + Prometheus + postgres_exporter — le tout déployable en quelques clics depuis le marketplace Coolify.
Indexes et VACUUM
PostgreSQL utilise MVCC, ce qui signifie que les lignes mises à jour ou supprimées laissent des « tuples morts » qu’il faut nettoyer périodiquement. Le démon autovacuum gère ça par défaut, mais vérifiez régulièrement :
-- Tables avec plus de tuples morts que vivants
SELECT relname, n_live_tup, n_dead_tup,
ROUND(100 * n_dead_tup / NULLIF(n_live_tup + n_dead_tup, 0), 1) AS dead_pct
FROM pg_stat_user_tables
WHERE n_dead_tup > 1000
ORDER BY dead_pct DESC NULLS LAST
LIMIT 20;
-- Forcer un VACUUM ANALYZE manuel sur une table critique
VACUUM ANALYZE nom_table;
Pour les indexes, surveillez l’utilisation et la fragmentation :
-- Indexes jamais utilisés
SELECT schemaname, relname AS table, indexrelname AS index
FROM pg_stat_user_indexes
WHERE idx_scan = 0
AND schemaname = 'public';
Réplication et haute disponibilité
Coolify v4 supporte la réplication streaming primary-replica via Docker Compose custom. Pour la plupart des PME ouest-africaines, une seule instance bien sauvegardée est suffisante : un crash matériel se résout en restaurant le dernier backup S3 sur un nouveau VPS, en 30 minutes à 1 heure. Si vous avez vraiment besoin de HA (RPO < 5 minutes), regardez Patroni avec etcd, mais c’est un projet à part entière qui sort du scope de Coolify.
Pooling de connexions
Si votre application a beaucoup de connexions courtes (par exemple Next.js avec Prisma en serverless mode), ajoutez PgBouncer en transaction pooling devant Postgres. Coolify permet de déployer PgBouncer comme un service Docker Compose dédié. Configuration de base :
[databases]
* = host=postgres-instance port=5432
[pgbouncer]
listen_port = 6432
pool_mode = transaction
max_client_conn = 1000
default_pool_size = 25
reserve_pool_size = 5
Vos applications se connectent alors sur PgBouncer (port 6432) qui multiplexe les connexions vers Postgres (port 5432). Vous passez de 1000 connexions client réduites à 25-30 connexions Postgres réelles, ce qui économise massivement la RAM.
Adaptation Afrique de l’Ouest
Pour des applications utilisées en Afrique de l’Ouest avec un VPS européen, gardez à l’esprit la latence : chaque requête Postgres ajoute ~10-30 ms par aller-retour application↔base. Pour des opérations critiques (login, paiement Mobile Money), réduisez le nombre de requêtes par requête utilisateur (préférez un JOIN à 5 SELECT séparés). Pour des données fréquemment lues mais peu modifiées (catalogues produits, sessions), ajoutez Redis pour caching applicatif.
Si vos données sont sensibles (santé, scolaire, financier dans un pays avec exigence d’hébergement national), Coolify fonctionne aussi sur des VPS chez Maktoob ou DigitalRise au Sénégal. La configuration est identique.
Erreurs fréquentes
| Erreur | Cause | Solution |
|---|---|---|
| FATAL: too many connections | Pool d’apps trop large | Utiliser PgBouncer en transaction pooling |
| OOM killer tue Postgres | VPS sous-dimensionné ou shared_buffers trop élevé | Réduire shared_buffers ou ajouter swap, monter en RAM |
| Backup échoue silencieusement | Credentials S3 invalides ou bucket plein | Tester avec aws s3 ls depuis le conteneur, vérifier logs Coolify |
| Slow queries après mise à jour | Index manquants ou stats obsolètes | VACUUM ANALYZE puis EXPLAIN ANALYZE les requêtes lentes |
| Disque saturé inattendu | WAL non archivé, ou table bloat | Vérifier wal_level, checkpoints, et vacuum full |
| Réplication stoppée | WAL trop ancien | Augmenter wal_keep_size, réinitialiser le réplica |
Pour aller plus loin
- Guide complet Coolify self-hosted
- Backups Coolify S3 et MinIO
- Next.js sur Coolify depuis GitHub
- Documentation officielle PostgreSQL : postgresql.org/docs
- PgTune : pgtune.leopard.in.ua