Operations and Deployment
This page describes how to run, deploy and operate the SIM Database. All commands are wrapped in the Makefile so they work the same way on Windows cmd.exe, Git Bash and POSIX shells.
Prerequisites
Section titled “Prerequisites”- Docker with the Compose plugin (
docker compose version) - GNU Make (Git Bash / MSYS2 / Chocolatey on Windows, Xcode CLT on macOS,
apt install makeon Debian) - Node + pnpm (only for seed password hashing)
No local Java, PostgreSQL or Flyway installation is required.
Local environment setup
Section titled “Local environment setup”The first time you clone the repository:
cd sim-databasemake setup # copies .env.example to .env if missingFill in the values in .env:
| Variable | Default | Purpose |
|---|---|---|
POSTGRES_DB |
sim_db |
Database name |
POSTGRES_USER |
sim |
Application role |
POSTGRES_PASSWORD |
admin |
Local password (not for production) |
POSTGRES_PORT |
5432 |
Published port on 127.0.0.1 |
POSTGRES_HOST |
localhost |
Host used by clients |
Local development workflow
Section titled “Local development workflow”| Step | Command | What it does |
|---|---|---|
| Start database | make up |
Builds/starts sim-postgres:local, waits for pg_isready |
| Stop database | make down |
Stops the container but keeps the data volume |
| Restart | make restart |
Restarts the PostgreSQL container |
| View logs | make logs |
Follows container logs |
| Status | make status |
Shows docker compose ps output |
| Apply migrations | make migrate |
Runs Flyway against migrations/ |
| Migration history | make migration-info |
Shows flyway info |
| Validate migrations | make validate |
Fails if any applied migration file changed |
| Load reference seeds | make seed-ref |
Idempotent seeds/reference/ load |
| Load dev seeds | make seed-dev |
Loads seeds/dev/ and applies bcrypt hashes |
| Load both | make seed |
seed-ref then seed-dev |
| Bootstrap admin | make admin |
Inserts the bootstrap ADMINISTRATEUR and hashes |
| Open psql | make db |
Interactive shell inside the container |
| Run tests | make test |
Migrates then runs the pgTAP suite in tests/ |
| Backup | make backup |
pg_dump -Fc to backups/sim_<ts>.dump |
| List backups | make backup-list |
Lists backups/ contents |
| Restore | make restore file=sim_<ts>.dump |
pg_restore --clean --if-exists (destructive) |
| Reset from zero | make reset |
down -v, fresh up, then migrate (destructive) |
| Clean everything | make clean |
Stops and removes the data volume (destructive) |
Typical local session
Section titled “Typical local session”make upmake migratemake seedmake testmake db# ... develop ...make downBackup and recovery
Section titled “Backup and recovery”Backups are logical pg_dump -Fc custom-format dumps written to backups/ on the host. They are suitable for full rebuilds, not point-in-time recovery (PITR is not configured).
Create a backup
Section titled “Create a backup”make backupRestore a backup
Section titled “Restore a backup”make restore file=sim_20250908_120000.dumpRestoring drops the objects in the dump and recreates them. Data created after the backup is lost. Objects created after the backup (for example newer migrations) are left in place, so make migrate may be needed afterward.
Rebuild from migrations and seeds
Section titled “Rebuild from migrations and seeds”make cleanmake upmake migratemake seedThis is useful when the schema has drifted or you want a clean state.
VPS deployment (shared Postgres)
Section titled “VPS deployment (shared Postgres)”The VPS stack uses a shared PostgreSQL instance already present on the host. It is intended for the dev/demo environment.
- Configuration:
.env.vps(from.env.vps.example) - Network:
internal - Trigger: push to
mainwhenmigrations/**,seeds/**,config/**,scripts/bootstrap-vps.shor.env.vps.examplechange, orworkflow_dispatch - Runner:
vps-runner - Workflow:
.github/workflows/deploy.yml
The workflow:
- Restores
.env.vpsfrom theENV_VPS_B64GitHub secret. - Installs Node/pnpm and dependencies.
- Runs
scripts/bootstrap-vps.sh:- Provisions the
simrole andsim_dbdatabase idempotently. - Runs
Flyway migratewithFLYWAY_OUT_OF_ORDER=true. - Loads
seeds/reference,seeds/seed_admin_user.sql,seeds/dev, andseeds/generated/10_auth_passwords.sql.
- Provisions the
Because this is a development environment, dev seeds and demo passwords are acceptable.
Production deployment (dedicated Postgres)
Section titled “Production deployment (dedicated Postgres)”The production stack is a dedicated container reachable by the backend at postgres-prod:5432 on prod-network.
- Configuration:
.env.prod(from.env.prod.example) - Trigger:
workflow_dispatchonly, with a typedconfirmand required reviewer on theproductionenvironment - Runner:
gsg-prod - Workflow:
.github/workflows/deploy-prod.yml
The workflow:
make prod-up— builds/startssim-postgres-prod.make prod-migrate— applies Flyway migrations.make prod-seed— loadsseeds/reference/, the bootstrap admin, and a bcrypt hash generated in memory fromADMIN_LOGIN/ADMIN_PASSWORDin.env.prod.make prod-admin-ui-up— starts/updates pgAdmin behind Traefik (optional).
prod-seed never loads seeds/dev/. The production admin password is hashed by scripts/hash-prod-admin.mjs and piped to psql; it is never logged or committed.
Production commands
Section titled “Production commands”make prod-upmake prod-migratemake prod-seedmake prod-dbmake prod-backupmake prod-admin-ui-uppgAdmin (production)
Section titled “pgAdmin (production)”The pgadmin profile in docker-compose.prod.yml exposes pgAdmin behind Traefik at https://${PGADMIN_HOST}. It is not started by prod-up; start it explicitly with:
make prod-admin-ui-upThe pre-registered server in docker/pgadmin/servers.json connects to postgres-prod:5432 / sim_db.
CI/CD pipelines
Section titled “CI/CD pipelines”| Workflow | Trigger | Runner | Purpose |
|---|---|---|---|
ci.yml |
push: main, pull_request |
ubuntu-latest |
Starts the local compose stack, migrates and runs make test |
deploy.yml |
push: main on DB paths or workflow_dispatch |
vps-runner |
Bootstrap/migrate/seeds the VPS shared Postgres |
deploy-prod.yml |
workflow_dispatch with manual approval |
gsg-prod |
Deploy the dedicated production Postgres |
Both deploy workflows decode the whole .env file from a base64 secret and chmod 600 it. The production workflow removes .env.prod in an always() step.
Things deliberately out of scope
Section titled “Things deliberately out of scope”- WAL/PITR backup (only
wal_level=replicais preconfigured) - Native monitoring stack
- Multi-master or read replicas
These are left for the wider sim-backend/hosting milestone.
Command walk-through
Section titled “Command walk-through”Starting from scratch
Section titled “Starting from scratch”$ cd sim-database$ make setupCreated .env from .env.example
$ make up[+] Running 2/2 ✔ Container sim-database-postgres-1 Started
$ make migrateFlyway ...Successfully applied 73 migrations.
$ make seed-> reference seeds loaded-> dev seeds loaded-> bcrypt hashes applied
$ make test000_smoke.sql ........................ PASS010_regles_transverses.sql ........... PASS020_regles_residence.sql ............. PASS030_regles_market.sql ................ PASS040_regles_pressing_restaurant_fete.sql PASS050_regles_rh.sql .................... PASS060_regles_dynamiques_residence.sql .. PASS070_regles_dynamiques_market.sql ..... PASS080_regles_dynamiques_finances.sql ... PASS090_regles_dynamiques_rh.sql ......... PASS100_audit.sql ........................ PASS110_auth.sql ......................... PASS120_resident_portal.sql .............. PASSAdding a new migration and testing it
Section titled “Adding a new migration and testing it”# 1. Create the new migration file$ touch migrations/residence/074_residence_demande_maintenance.sql
# 2. Write the DDL, save, then migrate$ make migrateFlyway ...Current version: 73+---------+ ...| 074 ... | ...+---------+ ...
# 3. Run tests to make sure nothing is broken$ make test
# 4. Open psql to verify$ make dbsim=# \dt residence.*What not to do operationally
Section titled “What not to do operationally”| Do not | Why | Instead |
|---|---|---|
Edit migrations/common/001_bootstrap_schemas.sql |
It has already been applied | Add a new migration |
Run make seed-dev on the production compose stack |
prod-seed is the only production-safe seed command |
make prod-seed |
Run make restore on a live production database during business hours |
It drops objects and restores the dump; downtime | Schedule a maintenance window |
Commit .env or .env.prod |
Secrets in Git are a security risk | Use .env.example templates and GitHub secrets |
Run make clean expecting to keep data |
It removes the Docker volume | Use make down to stop, make backup before make clean |