1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
|
# App management - Lucien-sens-bon
Ce document explique comment diagnostiquer les conteneurs, la base de donnees
et le reverse proxy (Apache).
## 1) Diagnostic Docker
Statut des services :
```
docker compose ps
```
Logs temps reel :
```
docker compose logs -f
docker compose logs -f backend
docker compose logs -f storefront
```
Redemarrer un service :
```
docker compose restart backend
```
Rebuild force d'un service :
```
docker compose build --no-cache backend
docker compose up -d --build backend
```
Entrer dans un conteneur :
```
docker exec -it medusa-backend sh
```
## 2) Verifier la connexion PostgreSQL
La connexion est definie dans `.env` :
```
DATABASE_URL=postgres://user:password@host:5432/nom_db
```
### 2.1 Tester depuis le serveur (si psql est installe)
```
psql "$DATABASE_URL" -c "select 1;"
```
### 2.2 Tester depuis un conteneur temporaire
```
docker run --rm -it postgres:16-alpine psql "$DATABASE_URL" -c "select 1;"
```
### 2.3 Tester le port (reseau)
```
nc -vz <host_db> 5432
```
Si la DB est sur la machine hote :
- eviter `localhost` dans `DATABASE_URL`
- utiliser l'IP de la machine hote
Documentation PostgreSQL :
https://www.postgresql.org/docs/current/app-psql.html
https://www.postgresql.org/docs/current/app-pg-isready.html
## 3) Tests applicatifs rapides
Storefront :
```
curl http://localhost:8000
```
API Medusa :
```
curl http://localhost:9000/store/products
```
## 3.1) Depannage avance: backend 9000 ne repond pas
Cette section documente les commandes utilisees en incident et explique
ce qu'elles permettent de verifier.
### A) Etre dans le bon dossier compose
```
cd /var/www/lucien-sens-bon
ls -l docker-compose.yml
```
- `cd ...` : se place dans le dossier ou se trouve `docker-compose.yml`.
- `ls -l docker-compose.yml` : confirme que le fichier compose existe
(sinon `docker compose` renvoie "no configuration file provided").
### B) Etat et logs du backend
```
sudo docker compose ps
sudo docker compose logs -f backend
```
- `docker compose ps` : liste les conteneurs, leur statut et les ports publies.
- `docker compose logs -f backend` : suit les logs du backend en temps reel
pour identifier l'erreur exacte.
### C) Test HTTP local (depuis le serveur)
```
curl -v http://localhost:9000/store/products
```
- `curl -v` : verifie que l'API repond et montre les details de connexion.
- Si "connection reset by peer" -> le backend crash apres accept.
### D) Verifier la base (depuis un conteneur temporaire)
```
sudo docker compose run --rm backend node -e "const { Client }=require('pg'); const c=new Client({connectionString: process.env.DATABASE_URL}); c.connect().then(()=>console.log('DB OK')).catch(e=>{console.error('DB ERROR:', e.message); process.exit(1)})"
```
- `docker compose run --rm backend` : lance un conteneur temporaire base sur
l'image backend (meme environnement que le service).
- `node -e ...` : teste la connexion a PostgreSQL via `DATABASE_URL`.
### E) Tester droits et extension PostgreSQL
```
sudo docker compose run --rm backend node -e "const {Client}=require('pg'); const c=new Client({connectionString: process.env.DATABASE_URL}); c.connect().then(async()=>{const p=await c.query(\"select has_database_privilege(current_user, current_database(), 'CREATE') as can_create\"); console.log(p.rows); try{await c.query('CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\"'); console.log('EXT OK');}catch(e){console.error('EXT ERROR:', e.message);} await c.end();}).catch(e=>{console.error('DB ERROR:', e.message); process.exit(1);});"
```
- Verifie que l'utilisateur a le droit de creer dans la base.
- Cree l'extension `uuid-ossp` si elle manque (souvent requise par Medusa).
### F) Migrations Medusa (creation des tables)
```
sudo docker compose run --rm backend npx medusa migrations run
```
- Applique les migrations en base. Sans ca, le backend peut echouer a demarrer.
### G) Seed de donnees (optionnel)
```
sudo docker compose run --rm backend npm run seed
```
- Ajoute des donnees de demo si un fichier seed existe.
- Si le fichier `data/seed.json` manque, cette commande echoue sans impact
sur le demarrage de l'API.
### H) Redemarrage et rebuild
```
sudo docker compose restart backend
sudo docker compose up -d --build backend
```
- `restart` : redemarre seulement le backend.
- `up -d --build` : reconstruit l'image puis redemarre le service.
### I) Cas erreur PaymentProviderService (crash apres init)
```
sudo docker compose run --rm backend node -e "const {Client}=require('pg'); const c=new Client({connectionString: process.env.DATABASE_URL}); c.connect().then(async()=>{const rows=await c.query('select * from payment_provider'); console.log(rows.rows); await c.end();}).catch(e=>{console.error('DB ERROR:', e.message); process.exit(1);});"
```
- Controle le contenu de `payment_provider` si le backend plante au demarrage
dans le service des providers de paiement.
## 3.2) Procedure complete + explications (incident backend 9000)
Objectif : demarrer le backend sans crash, appliquer les correctifs, puis
verifier que l'API repond.
### A) Confirmer les symptomes
```
sudo docker compose ps
sudo docker compose logs --tail=200 backend
curl -v http://localhost:9000/store/products
```
- `ps` : confirme si le conteneur redemarre en boucle.
- `logs` : montre l'erreur exacte (ex: TypeORM "Empty criteria").
- `curl -v` : valide la reponse HTTP (200 attendu).
### B) Comprendre la cause racine (pourquoi ca casse)
Cause principale :
- Dans certaines versions de Medusa, plusieurs services font
`update({}, { is_installed: false })` sans criteres.
- Avec la version de TypeORM utilisee, `update` refuse les criteres vides
-> crash au demarrage.
- Le code fautif est dans les fichiers compiles de `node_modules`
(pas dans les sources du projet).
Effet domino :
- Chaque correctif debloque l'etape suivante du demarrage,
revelant une autre erreur du meme type.
### C) Correctif technique (patch postinstall)
Le projet applique un patch automatique dans l'image Docker via :
- `backend/scripts/patch-medusa.js` (script)
- `backend/package.json` -> `postinstall`
- `backend/Dockerfile` -> `COPY scripts ./scripts` avant `npm install`
Le patch remplace les `update({}, ...)` par un update explicite :
`createQueryBuilder().update().set(...).where('1=1').execute()`.
### D) Forcer l'application du patch
```
cd /var/www/lucien-sens-bon
sudo docker compose build --no-cache backend
sudo docker compose up -d backend
```
- `--no-cache` : force `npm install` + `postinstall`, donc le patch.
- `up -d` : redeploie le conteneur avec la nouvelle image.
### E) Verifier que le patch est bien applique
```
sudo docker compose run --rm backend sh -c "grep -n \"update({}, { is_installed: false })\" node_modules/@medusajs/medusa/dist/services/tax-provider.js || echo 'OK: patch present'"
```
- Si le grep ne trouve rien, la patch est presente.
### F) Validation finale
```
sudo docker compose logs --tail=200 backend
curl -v http://localhost:9000/store/products
```
- Le log doit contenir `Server is ready on port: 9000`.
- L'API doit repondre `200` avec JSON.
### G) Cas "Compiling Webpack" trop long
Le plugin `@medusajs/admin` peut prendre du temps a compiler.
Si blocage > 10 min, on peut le desactiver temporairement dans
`backend/medusa-config.js` pour demarrer l'API, puis le reactiver.
## 3.3) Verifier que l'image est saine apres reboot
Objectif : s'assurer que le redemarrage ne casse pas l'API.
### A) Redemarrer proprement
```
sudo docker compose restart backend
```
### B) Verifier etats + port
```
sudo docker compose ps
curl -v http://localhost:9000/store/products
```
- Le conteneur doit etre `Up` (pas `Restarting`).
- L'API doit repondre en `200`.
### C) Verifier la patch dans l'image (controle rapide)
```
sudo docker compose run --rm backend sh -c "rg -n \"update\\(\\{\\}, \\{ is_installed: false \\}\\)\" node_modules/@medusajs/medusa/dist/services || echo 'OK: aucun update vide'"
```
- Si aucun match, les patchs sont bien en place.
### D) Conseils pour eviter les surprises
- Toujours rebuild `--no-cache` apres modification du patch.
- Ne pas editer `node_modules` a la main dans un conteneur running.
- Garder `backend/scripts/patch-medusa.js` versionne.
## 3.4) Seed des produits + connexion storefront
### A) Seed (donnees demo)
```
sudo docker compose run --rm backend npm run seed
```
- Necessite `backend/data/seed.json`.
- Sinon la commande echoue sans casser le backend.
### B) Verifier l'API apres seed
```
curl -v http://localhost:9000/store/products
```
### C) Connecter la boutique (storefront)
Verifier `NEXT_PUBLIC_MEDUSA_BACKEND_URL` dans `.env` :
```
NEXT_PUBLIC_MEDUSA_BACKEND_URL=http://api.lsb.huitral.ruka.lan
```
Puis reconstruire le storefront :
```
sudo docker compose up -d --build storefront
```
Si on travaille en local (pas via Apache), utiliser l'URL directe :
```
NEXT_PUBLIC_MEDUSA_BACKEND_URL=http://<IP_DU_SERVEUR>:9000
```
## 4) Apache / Reverse proxy
Verifier les services Apache :
```
sudo systemctl status apache2
```
Logs Apache :
```
sudo journalctl -u apache2 -f
sudo tail -f /var/log/apache2/error.log
sudo tail -f /var/log/apache2/access.log
```
Modules proxy :
```
sudo a2enmod proxy
sudo a2enmod proxy_http
```
Reload Apache :
```
sudo systemctl reload apache2
```
Documentation Apache reverse proxy :
https://httpd.apache.org/docs/2.4/howto/reverse_proxy.html
## 5) Ports a verifier
- `8000` : storefront
- `9000` : backend
- `5432` : PostgreSQL
- `6379` : Redis
Verifier l'ouverture locale :
```
ss -lntp | egrep '8000|9000|5432|6379'
```
Verifier le firewall (UFW) :
```
sudo ufw status
```
## 6) Git - Remise en ordre apres modifications locales
Cette section documente les commandes utilisees pour remettre la branche locale
en etat propre, definir le suivi distant, et pousser les changements.
### A) Retirer les fichiers sensibles ou locaux du commit
```
git reset HEAD .env output*.txt
```
- Retire `.env` et les fichiers `output*.txt` du staging.
- Evite d'inclure des secrets ou des artefacts locaux dans le commit.
### B) Corriger les droits si `.git` est en lecture seule
```
sudo chown -R "$USER":"$USER" /var/www/lucien-sens-bon
```
- Redonne les droits d'ecriture a l'utilisateur courant sur le depot.
- Corrige l'erreur `Permission denied` lors de la creation du commit.
### C) Committer en definissant l'identite temporairement
```
GIT_AUTHOR_NAME="toshiro" GIT_AUTHOR_EMAIL="toshiro@chillka" GIT_COMMITTER_NAME="toshiro" GIT_COMMITTER_EMAIL="toshiro@chillka" git commit -m "local changes on huitral"
```
- Injecte l'identite uniquement pour ce commit, sans modifier la configuration
globale de git.
- Permet de valider le commit quand `user.name`/`user.email` ne sont pas definis.
### D) Definir la branche distante suivie
```
git branch --set-upstream-to=origin/docs-git-dns
```
- Associe `docs-git-dns` a la branche distante pour autoriser `git pull`.
### E) Rebaser sur la remote puis pousser
```
git pull --rebase
git push origin docs-git-dns
```
- `pull --rebase` aligne la branche locale sur la remote sans commit de merge.
- `push` publie les commits locaux sur la remote.
### F) Recuperer le dernier code sur un serveur (alignement strict)
```
cd /var/www/lucien-sens-bon
git fetch origin
git checkout docs-git-dns
git reset --hard origin/docs-git-dns
```
- S'assure d'etre a la racine du depot (pas dans `backend/`).
- Aligne la branche locale strictement sur la remote (`origin/docs-git-dns`).
- Ecrase les changements locaux sur cette branche.
Verifier la presence d'un fichier sur la remote :
```
git ls-tree -r origin/docs-git-dns --name-only | grep "backend/scripts/patch-medusa.js"
```
- Confirme que le fichier existe bien sur la branche distante.
Nettoyer les fichiers non suivis (optionnel) :
```
git clean -fd
```
- Supprime les fichiers/dossiers non suivis (ex: `output*.txt`, `uploads/`).
### G) Push refuse (non-fast-forward) + rebase avec identite temporaire
Si `git push` refuse avec `non-fast-forward`, integrer la remote puis repousser.
1) Mettre de cote les fichiers locaux non committes :
```
git status
git stash push -u -m "wip avant rebase"
```
2) Rebaser avec identite temporaire (sans modifier la config git) :
```
git -c user.name="toshiro" -c user.email="toshiro@chillka" pull --rebase origin docs-git-dns
```
3) Si un rebase est en cours et demande un commit :
```
git -c user.name="toshiro" -c user.email="toshiro@chillka" commit -m "local changes on huitral"
git -c user.name="toshiro" -c user.email="toshiro@chillka" rebase --continue
```
4) Pousser puis restaurer le stash :
```
git push origin docs-git-dns
git stash pop
```
- Le rebase rejoue les commits locaux au-dessus de la remote.
- L'option `-c user.name/user.email` injecte l'identite uniquement pour la commande.
### H) Ignorer les fichiers locaux (.env, output*.txt)
Option 1 - Ignorer pour tout le depot (partage en equipe) :
```
# .gitignore (exemples)
.env
output*.txt
```
- Ajoute ces patterns au `.gitignore` si ces fichiers ne doivent jamais etre commits.
- Utile pour les fichiers generes localement.
Option 2 - Ignorer localement sans toucher au `.gitignore` :
```
git update-index --skip-worktree .env
```
- Masque les changements locaux de `.env` sans impacter le depot distant.
- Annuler si besoin :
```
git update-index --no-skip-worktree .env
```
### I) Pull refuse (divergent branches) sans modifier la config
Probleme :
```
fatal: Need to specify how to reconcile divergent branches.
```
Cause :
- La branche locale et la branche distante ont diverge.
- Git demande une strategie explicite (merge, rebase, ff-only).
Solution recommandee (rebase ponctuel) :
```
git fetch origin
git pull --rebase origin docs-git-dns
git push origin docs-git-dns
```
- `--rebase` aligne l'historique local sans commit de merge.
- A utiliser sans changer `git config`, juste pour cette commande.
Si des changements locaux non committes existent :
```
git stash push -u -m "wip avant rebase"
git pull --rebase origin docs-git-dns
git push origin docs-git-dns
git stash pop
```
|