docs: déploiement Karrio (expédition multi-transporteurs self-hosted) + sources
Architecture, accès, Dockerfile.carriers + override compose (sanitisés), transporteurs (Canada Post/Purolator/Canpar/Nationex/Dicom/BoxKnight + agrégateurs eShipper/Freightcom), pièges (collision hostname, admin, binaire venv), plan d'intégration hub #54. Sources incluses. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a855e11476
commit
3a90dafb9f
150
docs/karrio-shipping.md
Normal file
150
docs/karrio-shipping.md
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
# Karrio — plateforme d'expédition multi-transporteurs (self-hosted)
|
||||
|
||||
Karrio est l'**EasyPost/Shippo open-source** (LGPL), auto-hébergé sur le serveur de prod.
|
||||
Il fournit, sous une **API unifiée**, le **calcul de tarif d'expédition + étiquettes + suivi**
|
||||
à travers de nombreux transporteurs (BYOCA : on branche nos propres comptes, **0 frais par étiquette**).
|
||||
|
||||
Objectif : calculer les frais de livraison au **checkout de la boutique matériel** (`/store`) et
|
||||
gérer l'expédition des commandes (#54). Déployé le 2026-06-04.
|
||||
|
||||
> ⚠️ Ce document ne contient **aucun secret**. Les identifiants vivent sur le serveur
|
||||
> (`/opt/karrio/.env`, `/opt/karrio/ADMIN_CREDS.txt`).
|
||||
|
||||
---
|
||||
|
||||
## Accès
|
||||
|
||||
| Quoi | URL |
|
||||
|---|---|
|
||||
| **Dashboard** (GUI gestion transporteurs) | https://karrio.gigafibre.ca — connexion `admin@targo.ca` (mdp : `/opt/karrio/ADMIN_CREDS.txt`) |
|
||||
| **API publique** | https://api.karrio.gigafibre.ca |
|
||||
| **API interne** (depuis le hub) | `http://karrio.api:5002` (réseau Docker `erpnext_erpnext`) |
|
||||
| Auth API | `POST /api/token {email,password}` → JWT `access` |
|
||||
|
||||
DNS Cloudflare : `karrio` + `api.karrio`.gigafibre.ca → 96.125.196.67, **DNS-only** (proxied=false,
|
||||
comme `msg`/`erp`, pour le challenge Let's Encrypt). TLS via Traefik (resolver `letsencrypt`).
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
- **Emplacement** : `/opt/karrio/` (compose) ; source clonée dans `/opt/karrio-src/` (Git).
|
||||
- **Conteneurs** : `karrio.api` (5002) · `karrio.worker` · `karrio.dashboard` (3002) · `karrio.db`
|
||||
(postgres:16 dédié) · `karrio.redis` · `karrio.mail` (maildev).
|
||||
- **Réseaux Docker** : `karrio_default` (interne) + `erpnext_erpnext` (pour que le hub joigne l'API)
|
||||
+ `proxy` (Traefik). L'attache aux réseaux externes est dans `docker-compose.override.yml` (persistante).
|
||||
- **Images** : `karrio/server` + `karrio/dashboard` **2026.1.31**. L'`api`/`worker` utilisent une
|
||||
**image custom** `karrio-server-targo:2026.1.31` (transporteurs canadiens supplémentaires, voir plus bas).
|
||||
|
||||
### `Dockerfile.carriers` (transporteurs canadiens opt-in)
|
||||
```dockerfile
|
||||
FROM karrio.docker.scarf.sh/karrio/server:2026.1.31
|
||||
# Transporteurs non bundlés dans l'image OSS (paquets PyPI gratuits)
|
||||
RUN /karrio/venv/bin/pip install --no-cache-dir "karrio==2026.1.31" \
|
||||
karrio_canpar karrio_nationex karrio_dicom karrio_boxknight
|
||||
```
|
||||
Build : `docker build -t karrio-server-targo:2026.1.31 -f Dockerfile.carriers .`
|
||||
|
||||
### `docker-compose.override.yml` (réseaux + image custom + labels Traefik)
|
||||
```yaml
|
||||
networks:
|
||||
erpnext_erpnext: { external: true }
|
||||
proxy: { external: true }
|
||||
services:
|
||||
api:
|
||||
image: karrio-server-targo:2026.1.31
|
||||
networks: [default, erpnext_erpnext, proxy]
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.docker.network=proxy
|
||||
- traefik.http.routers.karrio-api.rule=Host(`api.karrio.gigafibre.ca`)
|
||||
- traefik.http.routers.karrio-api.entrypoints=websecure
|
||||
- traefik.http.routers.karrio-api.tls.certresolver=letsencrypt
|
||||
- traefik.http.services.karrio-api.loadbalancer.server.port=5002
|
||||
worker:
|
||||
image: karrio-server-targo:2026.1.31
|
||||
dashboard:
|
||||
networks: [default, proxy]
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.docker.network=proxy
|
||||
- traefik.http.routers.karrio-dash.rule=Host(`karrio.gigafibre.ca`)
|
||||
- traefik.http.routers.karrio-dash.entrypoints=websecure
|
||||
- traefik.http.routers.karrio-dash.tls.certresolver=letsencrypt
|
||||
- traefik.http.services.karrio-dash.loadbalancer.server.port=3002
|
||||
```
|
||||
|
||||
### Variables `.env` clés (valeurs réelles sur le serveur)
|
||||
```
|
||||
KARRIO_TAG=2026.1.31
|
||||
DATABASE_HOST=karrio.db # nom de conteneur, PAS "db" (collision ERPNext)
|
||||
REDIS_HOST=karrio.redis # idem
|
||||
USE_HTTPS=True
|
||||
KARRIO_PUBLIC_URL=https://api.karrio.gigafibre.ca
|
||||
DASHBOARD_URL=https://karrio.gigafibre.ca
|
||||
ALLOW_SIGNUP=False
|
||||
ADMIN_EMAIL=admin@targo.ca
|
||||
# SECRET_KEY / JWT_SECRET / OIDC_RSA_PRIVATE_KEY / ADMIN_PASSWORD / DATABASE_PASSWORD : générés
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Transporteurs disponibles
|
||||
|
||||
- **Bundlés (image OSS)** : Canada Post, Purolator, UPS, FedEx, DHL (×4), GLS, USPS, DPD, Chronopost,
|
||||
La Poste, Sendle, Australia Post, **eShipper**, **Freightcom**, generic… (~29).
|
||||
- **Ajoutés (image custom)** : 🇨🇦 **Canpar**, **Nationex** (QC), **Dicom / GLS Canada**, **BoxKnight** (last-mile Montréal).
|
||||
- **Agrégateurs canadiens** (1 compte → multi-transporteurs à tarifs négociés, **Canpar inclus**) :
|
||||
**eShipper**, **Freightcom** (déjà bundlés).
|
||||
- Dispo sur PyPI si besoin (international) : `karrio_tge, karrio_geodis, karrio_asendia, karrio_aramex`.
|
||||
Non publiés : shiptime, loomis, intelcom, ics_courier.
|
||||
|
||||
> Karrio OSS ne bundle qu'un sous-ensemble ; les autres transporteurs sont des paquets PyPI
|
||||
> `karrio_<nom>` **gratuits** (pas une limitation de licence — du packaging). On les cuit dans
|
||||
> l'image custom.
|
||||
|
||||
---
|
||||
|
||||
## Pièges rencontrés (résolus)
|
||||
|
||||
1. **Collision de hostname** : `api` étant sur le réseau partagé `erpnext_erpnext`, `db`/`redis`
|
||||
résolvaient vers le **Postgres/Redis d'ERPNext** (« password auth failed for user karrio »).
|
||||
→ `.env` : `DATABASE_HOST=karrio.db`, `REDIS_HOST=karrio.redis` (noms de conteneurs non ambigus).
|
||||
2. **Attache réseau** : `docker network connect` est perdu au recreate → réseaux dans l'`override.yml`.
|
||||
3. **Admin non auto-semé** : créer manuellement —
|
||||
binaire = `/karrio/venv/bin/karrio` (absent du PATH en `bash -lc` → utiliser `docker exec ... sh -c`).
|
||||
```
|
||||
docker exec -e KPW=<pw> karrio.api sh -c "cd /karrio/app && karrio shell < /tmp/mkadmin.py"
|
||||
# mkadmin.py : get_user_model().objects.create_superuser('admin@targo.ca', os.environ['KPW'])
|
||||
```
|
||||
4. Réinit DB si besoin : `docker compose down -v` (sinon vieux creds persistent dans le volume).
|
||||
|
||||
---
|
||||
|
||||
## Intégration prévue (hub → #54)
|
||||
|
||||
`services/targo-hub/lib/shipping.js` exposera `quoteRates({origin, dest, parcel})` :
|
||||
1. token JWT (`POST /api/token`) → cache,
|
||||
2. appel API Karrio (rates) avec origine (entrepôt) + destination (client) + colis
|
||||
(poids = `Item.weight_per_unit` ERPNext),
|
||||
3. options de tarif → ligne « Frais de livraison » au checkout boutique,
|
||||
4. `/store/checkout` → Sales Invoice ERPNext (`update_stock`) + Stripe via `lib/payments.js`.
|
||||
|
||||
---
|
||||
|
||||
## Sources
|
||||
|
||||
- Karrio — dépôt : <https://github.com/karrioapi/karrio>
|
||||
- Karrio — intégrations transporteurs : <https://docs.karrio.io/carriers/>
|
||||
- Karrio — Canada Post : <https://docs.karrio.io/carriers/integrations/canadapost>
|
||||
- Karrio — Purolator : <https://www.karrio.io/docs/carriers/purolator>
|
||||
- Karrio — plateforme / éditions : <https://www.karrio.io/platform>
|
||||
- Karrio — starter Next.js (dashboard) : <https://docs.karrio.io/resources/nextjs-starter>
|
||||
- Extension Canpar (PyPI) : <https://pypi.org/project/karrio_canpar/>
|
||||
- Agrégateurs canadiens — eShipper : <https://www.eshipper.com/>
|
||||
- Agrégateurs canadiens — Freightcom : <https://www.freightcom.com/>
|
||||
- ShipTime (transporteurs/rabais, non Karrio-natif) : <https://ca.linkedin.com/company/shiptime>
|
||||
- Comparatif shipping APIs 2026 : <https://revaddress.com/blog/shipping-api-comparison-2026/>
|
||||
- Comparatif transporteurs Canada 2026 : <https://www.goodfirms.co/supply-chain-logistics-companies/shipping/canada>
|
||||
|
||||
_Mémoire interne liée : `project_karrio_shipping.md`._
|
||||
Loading…
Reference in New Issue
Block a user