Process-compose: Docker Compose sans les conteneurs
Tes BDD dans Podman, ton code en process. Le meilleur des deux mondes, orchestré proprement.
J’ai besoin de Postgres et Redis pour le dev local. Plus mon API Rust avec hot reload et un frontend Vite
Tout mettre dans Docker Compose ? Même avec des volumes montés, le hot reload rame. Les file watchers ratent des changements. Le HMR de Vite plante une fois sur deux. Les permissions de fichiers mettent le bordel sur Linux
Tout lancer en process natifs ? Là tu te tapes la gestion des versions Postgres et des configs Redis à la main
Je mixe les deux. Les BDD dans des conteneurs. Le code en process. Un seul outil pour orchestrer le tout
Ce que fait process-compose
C’est un orchestrateur de process et de conteneurs. Pas l’un ou l’autre. Les deux
Tu définis ce qui tourne, les dépendances, les health checks. Il démarre tout dans l’ordre, surveille, redémarre en cas d’échec, avec des logs unifiés
version: "0.5"
processes:
postgres:
command: podman run --rm -p 5432:5432 -e POSTGRES_PASSWORD=dev postgres:15
readiness_probe:
exec:
command: pg_isready -h localhost
initial_delay_seconds: 3
redis:
command: podman run --rm -p 6379:6379 redis:7
api:
command: cargo watch -x run
depends_on:
postgres:
condition: process_healthy
redis:
condition: process_healthy
frontend:
command: npm run dev
depends_on:
api:
condition: process_healthy Les BDD tournent dans Podman avec les images officielles, zéro config. Ton code tourne en natif avec le hot reload qui fonctionne.
Une commande process-compose, tout démarre dans le bon ordre.
Pourquoi des conteneurs pour les BDD
Postgres, Redis, Elasticsearch. Ils ont tous des images officielles. Versionnées, testées, prêtes à l’emploi.
Tu veux Postgres 15 ? podman run postgres:15. C’est fait. Pas de prise de tête avec le package manager. Pas de conflits de version. Pas de configs qui traînent.
Besoin de Postgres 14 pour un autre projet ? Port différent, conteneur différent. Ils ne se marchent pas dessus.
Les conteneurs isolent les BDD. Tes changements de code n’y touchent pas. L’état persiste dans des volumes. Séparation propre.
Pourquoi des process pour ton code
Rust avec cargo watch. TypeScript avec Vite. Go avec air. Ils ont tous le hot reload intégré.
Tu les wraps dans des conteneurs ? Le hot reload plante. Les file watchers ne voient pas les changements. Les rebuilds sont lents.
Tu les lances en process. Les changements de fichiers déclenchent une recompilation instantanée. Le HMR fonctionne. Les debuggers s’attachent facilement.
Ton code, c’est ce qui change constamment. Garde ça rapide.
Config réelle pour une stack web
version: "0.5"
environment:
- DATABASE_URL=postgresql://postgres:dev@localhost:5432/myapp
- REDIS_URL=redis://localhost:6379
processes:
db:
command: podman run --rm -p 5432:5432 -v postgres-data:/var/lib/postgresql/data -e POSTGRES_PASSWORD=dev postgres:15
availability:
restart: on_failure
readiness_probe:
exec:
command: pg_isready -h localhost
initial_delay_seconds: 2
period_seconds: 1
redis:
command: podman run --rm -p 6379:6379 redis:7
availability:
restart: on_failure
readiness_probe:
exec:
command: redis-cli -h localhost ping
initial_delay_seconds: 1
migrate:
command: sqlx migrate run
depends_on:
db:
condition: process_healthy
availability:
restart: no
api:
command: cargo watch -x 'run --bin api'
depends_on:
db:
condition: process_healthy
migrate:
condition: process_completed
redis:
condition: process_healthy
readiness_probe:
http_get:
host: localhost
port: 8080
path: /health
period_seconds: 2
frontend:
command: npm run dev
depends_on:
api:
condition: process_healthy
working_dir: ./frontend Postgres et Redis dans des conteneurs. La migration de BDD s’exécute une fois. L’API Rust avec cargo watch pour le hot reload. Le frontend Vite attend que l’API soit healthy.
Tu changes ton code Rust. cargo watch recompile en 500ms. Pas de rebuild d’image. Pas de restart de conteneur.
La TUI montre tout
Tu lances process-compose et tu as une interface terminal qui affiche :
- Tous les process, conteneurs et natifs
- Le statut : running, healthy, failed
- Les logs en temps réel
- Les dépendances visualisées
- Restart avec
r
Les logs du conteneur Postgres. La sortie de compilation Rust. Les messages HMR de Vite. Tout au même endroit.
Tu tapes 1 pour les logs du process 1. l pour tous les logs. q pour quitter. Tout s’arrête proprement.
Health checks qui marchent vraiment
processes:
api:
command: cargo watch -x run
readiness_probe:
http_get:
host: localhost
port: 8080
path: /health
initial_delay_seconds: 5
period_seconds: 3
timeout_seconds: 2 Des health checks pour les process natifs. HTTP, exec, TCP. Comme Kubernetes, mais en local.
Le frontend ne démarre pas tant que l’API n’est pas healthy. Pas juste “démarrée”, vraiment en train de servir des requêtes.
Les conteneurs ont aussi des health checks :
processes:
db:
command: podman run --rm postgres:15
readiness_probe:
exec:
command: pg_isready -h localhost Les dépendances attendent la vraie santé. Pas de race conditions.
Combine avec Devbox
Devbox pour tes outils de dev. process-compose pour les lancer
{
"packages": [
"podman",
"postgresql",
"redis",
"rustup",
"nodejs",
"process-compose"
],
"shell": {
"init_hook": [
"rustup default stable"
]
}
} devbox shell te donne Podman, les outils clients Postgres, Node, Rust et process-compose. Les mêmes versions partout.
Tu ajoutes .envrc :
use devbox
export DATABASE_URL=postgresql://postgres:dev@localhost:5432/myapp
export REDIS_URL=redis://localhost:6379 direnv allow charge tout. process-compose démarre ta stack.
Devbox gère les outils. Podman gère les BDD. process-compose orchestre. Séparation claire.
Quand utiliser des conteneurs pour le code
Tu build pour la prod. Tu as besoin de l’environnement d’exécution exact.
Tu testes le Dockerfile réel. Tu vérifies que ça marche avant de déployer.
Multi-stage builds où la conteneurisation fait partie du processus de build.
Mais le dev quotidien avec hot reload ? Les process gagnent.
Si t’es obsédé par les conteneurs
Tu aimes vraiment Docker Compose et lancer une commande podman run te semble contre nature ? Utilise Docker Compose DANS process-compose
version: "0.5"
processes:
infra:
command: docker compose -f infra.yml up
working_dir: ./infra
shutdown:
command: docker compose -f infra.yml down
api:
command: cargo watch -x run
depends_on:
infra:
condition: process_healthy
frontend:
command: npm run dev
depends_on:
api:
condition: process_healthy Ton infra.yml contient tous tes services conteneurisés (Postgres, Redis, etc.), et process-compose le lance comme un seul process. Garde ton Docker Compose pour l’infra, ton code en process natifs.
Le meilleur ? Quand tu quits process-compose, il exécute automatiquement docker compose down. Tout se nettoie proprement.
Plusieurs environnements, même config
Le dev utilise des conteneurs pour les BDD :
processes:
db:
command: podman run --rm postgres:15 La CI utilise du vrai Postgres :
processes:
db:
command: postgres -D /ci/postgres Même fichier process-compose.yaml, environnement différent. Override avec process-compose -f base.yaml -f ci.yaml.
Démarrer
Installe process-compose :
# Arch
yay -S process-compose
# Avec Devbox
devbox add process-compose
# Manuel
wget https://github.com/F1bonacc1/process-compose/releases/latest/download/process-compose_linux_amd64.tar.gz
tar xf process-compose_linux_amd64.tar.gz
sudo mv process-compose /usr/local/bin/ Crée process-compose.yaml :
version: "0.5"
processes:
db:
command: podman run --rm -p 5432:5432 -e POSTGRES_PASSWORD=dev postgres:15
app:
command: cargo watch -x run
depends_on:
db:
condition: process_started Lance :
process-compose Le conteneur Postgres démarre. L’app Rust attend qu’il soit prêt, puis se lance avec le hot reload. Les logs streamés dans la TUI.
Tu changes le code. cargo watch recompile. Pas de rebuild de conteneur.
Comparaison réelle
Docker Compose pour tout :
- Les BDD : ça marche bien
- Le code : rebuilds lents, hot reload cassé, problèmes de permissions sur les volumes
- Logs :
docker compose logs -f service - Restart :
docker compose restart - Changement de code : rebuild d’image
process-compose en mixant :
- Les BDD : conteneurs, images officielles
- Le code : process natifs, hot reload qui marche
- Logs : TUI unifiée
- Restart : tu tapes
r - Changement de code : hot reload automatique
J’ai basculé un projet Rust + TypeScript sur ce setup. Les changements de code sont passés de 8 secondes de rebuild Docker à 500ms de hot reload. Le HMR de Vite s’est remis à fonctionner. Le debugging est devenu bien plus simple.
Les BDD dans des conteneurs. Isolées, reproductibles. Le code en process. Rapide, debuggable.
Le meilleur des deux mondes.
Vous avez aimé cet article ? Partagez-le !


