Déploiement Job·Ka — nœud m3u96a
Cible
- Nœud :
M3U96a.maclustr.io(Mac Studio, 32 cœurs, 96 Go) — imposé par le CLAUDE.md du projet (§6). Dérogation assumée à la règle « M3U96a = staging » : demande explicite du projet, commevrai-prixetsorti-kadéjà sur ce nœud. - Répertoire :
~/apps/job-ka(convention des projets Ka remote-first) - Port interne :
8096(8095 = lou-ka ; vérifier les conflits avecpick-node.py/lsofavant de démarrer) - Exposition : ngrok, domaine réservé
www.job-ka.com - Superviseur : PM2 (3 processus)
Processus PM2
text
job-ka-web .venv/bin/python run.py serve 8096 # API + frontend
job-ka-sync .venv/bin/python run.py watch 60 # resync horaire
job-ka-ngrok ngrok http --url=www.job-ka.com 8096 # tunnel superviséProcédure
bash
# 1. Pousser le code (jamais les données : data/*.db, dist/, .env restent locaux au nœud)
ssh M3U96a 'mkdir -p ~/apps'
rsync -a --delete \
--exclude .venv --exclude node_modules --exclude dist \
--exclude 'data/*.db' --exclude .env --exclude .git \
~/Desktop/job-ka/ M3U96a:~/apps/job-ka/
# 2. Sur le nœud : runtime + build + secrets
ssh M3U96a 'cd ~/apps/job-ka \
&& python3 -m venv .venv && .venv/bin/pip install -r requirements.txt \
&& cd frontend && npm install && npm run build'
# .env : créer sur le nœud (SCRAPFLY_API_KEY) — jamais commité ni rsyncé
# 3. Amorçage des données
ssh M3U96a 'cd ~/apps/job-ka && .venv/bin/python run.py sync && .venv/bin/python run.py geocode'
# 4. PM2
ssh M3U96a 'cd ~/apps/job-ka \
&& pm2 start ".venv/bin/python run.py serve 8096" --name job-ka-web \
&& pm2 start ".venv/bin/python run.py watch 60" --name job-ka-sync \
&& pm2 start "ngrok http --url=www.job-ka.com 8096" --name job-ka-ngrok \
&& pm2 save'Vérifications post-déploiement
curl https://www.job-ka.com/health→{"status":"ok", ...}aveclast_sync_age_s< 7200 ;https://www.job-ka.comrépond (frontend) ;https://www.job-ka.com/api/sources→last_syncrécents sur chaque source ;pm2 ls: les 3 processusonline;- Mettre à jour
~/Desktop/cluster-skill/cluster-deployments.json(registre cross-session : app, node, port, domain, process_manager, dir, start, deployed).
Règles
- Jamais d'interface d'admin ni de BD exposée par le tunnel (seuls
/,/api/*,/healthexistent ;POST /api/syncest le seul point mutateur — il ne fait que déclencher une resynchronisation). - Les mises à jour de code passent par rsync (ou git sur le nœud, protocole
remote-first des projets Ka) puis
pm2 restart job-ka-web job-ka-sync.
Variations par rapport à Lou·Ka
- Carte : MapLibre GL + fond Carto libre au lieu de Mapbox/ka-maps — aucun jeton requis, aucun paquet lié à builder à côté du dépôt.
dedup.run()s'exécute aussi aprèsrun.py sync(pas seulement danswatch) ;geocode_failedest remis à 0 quand l'adresse d'une offre change.- Endpoint
/healthdédié (Lou·Ka n'en a pas).