From 9c74eb911447d9074aaf718f0f7737651548e652 Mon Sep 17 00:00:00 2001 From: tristan Date: Tue, 31 Mar 2026 10:51:33 +0200 Subject: [PATCH] feat : initial PostgreSQL infrastructure setup - docker-compose with postgres:16-alpine - Init script to create databases (SIRH + Ferme, prod + recette) - Deploy script with readiness check - Backup script with rotation (keeps last 7) - Auto-tag CI workflow - Full deployment documentation --- .env.example | 3 + .gitea/workflows/auto-tag.yml | 43 ++++++++++ .gitignore | 3 + README.md | 18 +++++ backup.sh | 18 +++++ deploy.sh | 18 +++++ doc/deployment.md | 146 ++++++++++++++++++++++++++++++++++ docker-compose.yml | 11 +++ init/01-create-databases.sql | 20 +++++ 9 files changed, 280 insertions(+) create mode 100644 .env.example create mode 100644 .gitea/workflows/auto-tag.yml create mode 100644 .gitignore create mode 100644 README.md create mode 100755 backup.sh create mode 100755 deploy.sh create mode 100644 doc/deployment.md create mode 100644 docker-compose.yml create mode 100644 init/01-create-databases.sql diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..6357059 --- /dev/null +++ b/.env.example @@ -0,0 +1,3 @@ +# Superuser PostgreSQL (utilise pour creer les BDD/users au premier lancement) +POSTGRES_USER=admin +POSTGRES_PASSWORD=change-me diff --git a/.gitea/workflows/auto-tag.yml b/.gitea/workflows/auto-tag.yml new file mode 100644 index 0000000..34c51ce --- /dev/null +++ b/.gitea/workflows/auto-tag.yml @@ -0,0 +1,43 @@ +name: Auto Tag + +on: + push: + branches: + - main + +jobs: + tag: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.REGISTRY_TOKEN }} + persist-credentials: true + + - name: Create next tag + shell: bash + run: | + set -euo pipefail + + if git tag --points-at HEAD | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then + echo "Tag already exists on this commit. Skipping." + exit 0 + fi + + last_tag="$(git tag -l 'v*' --sort=-v:refname | head -n1 || true)" + if [ -z "$last_tag" ]; then + version="0.1.0" + else + base="${last_tag#v}" + IFS='.' read -r major minor patch <<< "$base" + version="${major}.${minor}.$((patch + 1))" + fi + + tag="v$version" + git config user.name "gitea-actions" + git config user.email "gitea-actions@local" + git tag "$tag" + git push origin "$tag" + echo "Tagged: $tag" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3dcecc5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +data/ +backups/ +.env diff --git a/README.md b/README.md new file mode 100644 index 0000000..aacdc57 --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# infra-postgres + +PostgreSQL centralise pour les applications MALIO (SIRH, Ferme, etc.). + +Un seul conteneur PostgreSQL gere toutes les bases de donnees (prod + recette). + +## Quick start + +```bash +cp .env.example .env +# Editer .env et init/01-create-databases.sql avec les vrais mots de passe +chmod +x deploy.sh backup.sh +./deploy.sh +``` + +## Documentation + +Voir `doc/deployment.md` pour le guide complet. diff --git a/backup.sh b/backup.sh new file mode 100755 index 0000000..6c4c678 --- /dev/null +++ b/backup.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +set -euo pipefail + +cd "$(dirname "$0")" + +BACKUP_DIR="./backups" +DATE=$(date +%Y-%m-%d_%H%M%S) + +mkdir -p "$BACKUP_DIR" + +echo "==> Dumping all databases..." +docker compose exec -T postgres pg_dumpall -U admin > "${BACKUP_DIR}/all-databases-${DATE}.sql" + +echo "==> Backup saved to ${BACKUP_DIR}/all-databases-${DATE}.sql" + +# Garder les 7 derniers backups +ls -t "${BACKUP_DIR}"/all-databases-*.sql | tail -n +8 | xargs -r rm -- +echo "==> Old backups cleaned (keeping last 7)." diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 0000000..b30b614 --- /dev/null +++ b/deploy.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +set -euo pipefail + +cd "$(dirname "$0")" + +echo "==> Pulling PostgreSQL image..." +docker compose pull + +echo "==> Starting PostgreSQL..." +docker compose up -d + +echo "==> Waiting for PostgreSQL to be ready..." +until docker compose exec -T postgres pg_isready -U admin > /dev/null 2>&1; do + sleep 1 +done + +echo "==> PostgreSQL is ready." +docker compose exec -T postgres psql -U admin -c "SELECT version();" diff --git a/doc/deployment.md b/doc/deployment.md new file mode 100644 index 0000000..1fce6a2 --- /dev/null +++ b/doc/deployment.md @@ -0,0 +1,146 @@ +# Deploiement PostgreSQL — Infrastructure + +PostgreSQL centralise pour toutes les applications (SIRH, Ferme, etc.) en prod et recette. + +## Pre-requis + +Docker installe sur la machine (voir la doc SIRH pour l'installation). + +## Premier deploiement + +### 1. Creer le dossier + +```bash +sudo mkdir -p /var/www/postgres +sudo chown -R $(whoami):$(whoami) /var/www/postgres +cd /var/www/postgres +``` + +### 2. Creer les fichiers + +Copier depuis le repo : +- `docker-compose.yml` +- `deploy.sh` +- `backup.sh` +- `init/01-create-databases.sql` +- `.env.example` → `.env` + +```bash +chmod +x deploy.sh backup.sh +``` + +### 3. Configurer les mots de passe + +Editer `.env` : + +```env +POSTGRES_USER=admin +POSTGRES_PASSWORD= +``` + +Editer `init/01-create-databases.sql` : remplacer tous les `change-me` par des mots de passe forts pour chaque base. + +> **Important :** le script `init/01-create-databases.sql` n'est execute qu'au **premier lancement** (quand le dossier `data/` est vide). Si tu modifies les mots de passe apres le premier lancement, il faut les changer manuellement via `psql`. + +### 4. Deployer + +```bash +./deploy.sh +``` + +### 5. Verifier + +```bash +docker compose exec -T postgres psql -U admin -l +``` + +Toutes les bases (sirh_prod, sirh_recette, ferme_prod, ferme_recette) doivent apparaitre. + +## Connexion depuis les applications + +Les applications Docker sur la meme machine se connectent via `host.docker.internal` : + +```env +# SIRH prod +DATABASE_URL="postgresql://sirh_prod:password@host.docker.internal:5432/sirh_prod?serverVersion=16&charset=utf8" + +# SIRH recette +DATABASE_URL="postgresql://sirh_recette:password@host.docker.internal:5432/sirh_recette?serverVersion=16&charset=utf8" +``` + +## Ajouter une nouvelle base + +Se connecter au conteneur : + +```bash +docker compose exec -T postgres psql -U admin +``` + +Puis : + +```sql +CREATE USER nouvelle_app WITH PASSWORD 'motdepasse'; +CREATE DATABASE nouvelle_app OWNER nouvelle_app; +\q +``` + +Penser a ajouter les lignes dans `init/01-create-databases.sql` pour documenter (meme si le script ne sera pas re-execute). + +## Backups + +### Backup manuel + +```bash +cd /var/www/postgres +./backup.sh +``` + +Les backups sont sauvegardes dans `backups/` (les 7 derniers sont conserves). + +### Backup d'une seule base + +```bash +docker compose exec -T postgres pg_dump -U admin sirh_prod > backup-sirh-prod.sql +``` + +### Restaurer un backup + +```bash +# Toutes les bases +docker compose exec -T postgres psql -U admin < backups/all-databases-2026-03-30_120000.sql + +# Une seule base +docker compose exec -T postgres psql -U admin sirh_prod < backup-sirh-prod.sql +``` + +### Backup automatique (cron) + +```bash +crontab -e +``` + +Ajouter : + +``` +# Backup PostgreSQL tous les jours a 2h du matin +0 2 * * * /var/www/postgres/backup.sh >> /var/log/postgres-backup.log 2>&1 +``` + +## Voir les logs + +```bash +cd /var/www/postgres +docker compose logs -f +docker compose logs -f --tail=100 +``` + +## Mise a jour de PostgreSQL + +Pour passer a une nouvelle version (ex: 16 → 17) : + +1. Faire un backup : `./backup.sh` +2. Arreter le conteneur : `docker compose down` +3. Modifier la version dans `docker-compose.yml` +4. Supprimer les donnees : `rm -rf data/` (le backup est dans `backups/`) +5. Relancer : `./deploy.sh` +6. Restaurer : `docker compose exec -T postgres psql -U admin < backups/all-databases-XXXX.sql` diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..c0eea24 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,11 @@ +services: + postgres: + image: postgres:16-alpine + container_name: postgres + env_file: .env + ports: + - "5432:5432" + volumes: + - ./data:/var/lib/postgresql/data + - ./init:/docker-entrypoint-initdb.d:ro + restart: unless-stopped diff --git a/init/01-create-databases.sql b/init/01-create-databases.sql new file mode 100644 index 0000000..c65fab3 --- /dev/null +++ b/init/01-create-databases.sql @@ -0,0 +1,20 @@ +-- Ce script est execute automatiquement au premier lancement de PostgreSQL +-- (uniquement si le volume data/ est vide) +-- +-- Ajouter ici les bases et users pour chaque application. + +-- SIRH Production +CREATE USER sirh_prod WITH PASSWORD 'change-me'; +CREATE DATABASE sirh_prod OWNER sirh_prod; + +-- SIRH Recette +CREATE USER sirh_recette WITH PASSWORD 'change-me'; +CREATE DATABASE sirh_recette OWNER sirh_recette; + +-- Ferme Production +CREATE USER ferme_prod WITH PASSWORD 'change-me'; +CREATE DATABASE ferme_prod OWNER ferme_prod; + +-- Ferme Recette +CREATE USER ferme_recette WITH PASSWORD 'change-me'; +CREATE DATABASE ferme_recette OWNER ferme_recette;