- Ajout scripts/ reproduisant chaque étape (secrets, render config, up CLI, init Garage, bootstrap prod, admin, vérif E2E, adoption Coolify, backup) - Templates envsubst (config.yml, garage.toml, cantaloupe.properties) + .example - deploy.conf (config non-secrète : domaine, versions, uuids Coolify) - docs/ : ARCHITECTURE, TROUBLESHOOTING (11 problèmes/fixes), RUNBOOK, SECURITY - Makefile (raccourcis) - .gitignore + retrait du suivi de .env/.secrets.env/config.yml/garage.toml (fichiers conservés sur disque ; secrets restent dans l'historique -> voir SECURITY.md) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
77 lines
4.9 KiB
Markdown
77 lines
4.9 KiB
Markdown
# Architecture — Arkindex sur Coolify
|
||
|
||
## Vue d'ensemble
|
||
|
||
```
|
||
Internet (navigateur)
|
||
│ HTTPS (Let's Encrypt, HTTP-01)
|
||
▼
|
||
┌─────────────────────────────┐
|
||
│ coolify-proxy (Traefik v3) │ :80/:443
|
||
│ routage par labels Docker │
|
||
└───────┬───────────┬──────────┘
|
||
ark.nak0x.dev │ │ s3.nak0x… / iiif.nak0x…
|
||
(split par chemin) │ │
|
||
┌───────────────┬────────┘ └──────────┬──────────────┐
|
||
▼ ▼ ▼ ▼
|
||
ark-front ark-backend ark-garage ark-cantaloupe
|
||
(SPA nginx) (API gunicorn) (S3) (IIIF)
|
||
│ │ \ ▲ │
|
||
│ │ \ hairpin S3 │ http interne│ http interne
|
||
│ │ └──► https://s3.<DOMAIN> ───┘ :3900 │ :3900
|
||
│ ▼ │
|
||
│ ark-worker (RQ/Ponos) │
|
||
│ │ ▼
|
||
│ ┌──────┴──────┬──────────┐ (lit les images
|
||
▼ ▼ ▼ ▼ dans les buckets)
|
||
[réseau "ark"] ark-database ark-redis ark-solr
|
||
(Postgres) (RQ+cache) (recherche)
|
||
```
|
||
|
||
## Réseaux Docker
|
||
- **`ark`** (interne) : tous les services ; communication par **nom de service** (`ark-database`,
|
||
`ark-redis`, …). Ces noms sont **uniques** exprès (cf. Troubleshooting P4).
|
||
- **`coolify`** (externe, partagé) : uniquement `ark-garage`, `ark-cantaloupe`, `ark-backend`,
|
||
`ark-front`, `ark-worker` — pour être joignables par le proxy Traefik et pour le hairpin S3.
|
||
- En mode Coolify, un 3ᵉ réseau par ressource (`<uuid>`) est ajouté automatiquement.
|
||
|
||
## TLS & hostnames (contrainte centrale)
|
||
Coolify n'a que le challenge **HTTP-01** → **pas de certificat wildcard**. Or Arkindex sert S3 et
|
||
IIIF en **virtual-hosted** (`<bucket>.s3.<DOMAIN>`, `<x>.iiif.<DOMAIN>`). Comme l'ensemble des
|
||
hostnames est **fini et connu**, on les énumère dans les règles `Host(...)` Traefik → Traefik émet
|
||
un certificat HTTP-01 par hostname. Le **wildcard DNS** `*.nak0x.dev` (résolution, pas TLS) fait
|
||
pointer tous ces noms vers le serveur, donc **zéro entrée DNS à créer**.
|
||
|
||
Hostnames servis :
|
||
- `ark.<DOMAIN>` — front (catch-all, priorité 1) + backend (`/api`,`/api-docs`,`/admin`,`/rq`,`/static`, priorité 100)
|
||
- `s3.<DOMAIN>` + `<bucket>.s3.<DOMAIN>` × 9 buckets — Garage
|
||
- `iiif.<DOMAIN>`, `uploads.iiif.<DOMAIN>`, `ingest.iiif.<DOMAIN>` — Cantaloupe
|
||
|
||
## Stockage S3 (Garage)
|
||
- Le backend utilise boto3 avec `addressing_style="auto"` (codé en dur) → **virtual-hosted**
|
||
(`<bucket>.s3.<DOMAIN>`). D'où l'énumération des sous-domaines de bucket + `root_domain` dans
|
||
`garage.toml` (Garage mappe sous-domaine → bucket).
|
||
- **Hairpin** : le backend doit joindre `https://s3.<DOMAIN>` (les URLs présignées données au
|
||
navigateur utilisent ce host) : requête → IP publique → `coolify-proxy` (TLS valide) → Garage.
|
||
Vérifié fonctionnel ici.
|
||
- Cantaloupe, lui, parle à Garage **en interne** (`http://ark-garage:3900`, sans TLS).
|
||
- 9 buckets : `uploads, ingest, export, iiif-cache, ponos-artifacts, ponos-logs, staging, thumbnails, training`.
|
||
- Clé S3 : importée dans Garage (admin API/CLI) = `GK_ID`/`GK_SECRET` de `.secrets.env`.
|
||
|
||
## IIIF (Cantaloupe)
|
||
- Image custom Teklia : `ScriptLookupStrategy` + `S3Source.top_domain = iiif.<DOMAIN>` → le bucket
|
||
est déduit du sous-domaine (`uploads.iiif.<DOMAIN>` → bucket `uploads`).
|
||
- 2 `ImageServer` en base : `12345` (uploads) et `67890` (ingest), URLs `https://…iiif.<DOMAIN>/iiif/2`.
|
||
|
||
## Recherche (Solr)
|
||
- SolrCloud (`solr -f -cloud`). Les collections sont créées **par corpus** (`project-<uuid>`) à la
|
||
volée lors de l'indexation (`arkindex reindex`). Rien à pré-créer.
|
||
|
||
## Images (versions)
|
||
`backend/frontend 1.12.2`, `tasks 0.6.2`, `cantaloupe 5.0.7`, `postgis 17-3.5`, `solr 9`,
|
||
`garage v2.1.0`, `redis alpine`. Toutes **publiques** (pull anonyme).
|
||
|
||
## Bootstrap : pourquoi on ne l'utilise pas
|
||
`arkindex bootstrap` est **dev-only** : il refuse si `DEBUG=False` et code les URLs en
|
||
`*.ark.localhost`. On réplique ses 3 actions avec le vrai domaine (`scripts/20` + `scripts/30`).
|