En résumé
Une instance serveur se déploie avec un seul fichier Docker Compose et une clé secrète que vous générez. Deux services suffisent — l’application et l’interface web —, la base est créée toute seule, et les migrations s’appliquent à chaque démarrage. Pour un vrai nom de domaine, deux réglages sont à changer : l’origine autorisée et le certificat TLS, que Linkr ne fournit pas.
Deux façons de déployer
Mode serveur
Docker, sur une machine de votre établissement.
Comptes utilisateurs, stockage partagé, exécution de code côté serveur, versioning git. C’est le sujet de cette page.
Site statique
Des fichiers à poser sur un hébergement statique.
Tout tourne dans le navigateur. Pas de compte, pas de stockage partagé, pas de versioning git — voir Modes de déploiement.
Démarrer une instance
Un seul fichier est nécessaire. Il est autonome : ni clone, ni compilation.
curl -O https://framagit.org/interhop/linkr/linkr/-/raw/main/docker/docker-compose.hub.yml
export LINKR_SECRET_KEY=$(python3 -c "import secrets; print(secrets.token_urlsafe(48))")
docker compose -f docker-compose.hub.yml up
Puis ouvrez http://localhost:3000 : l’assistant de configuration prend le relais.
La clé secrète : générée une fois, conservée pour toujours
Elle signe les jetons de connexion et chiffre les mots de passe des bases enregistrées. Sans elle, le démarrage est refusé — c’est délibéré. La perdre rend ces secrets illisibles : sauvegardez-la comme vous sauvegardez les données.
Ce qu’elle protège exactement et ce qu’implique sa rotation : Configuration.
Ce que le fichier démarre
Deux services, et rien d’autre à installer.
| Service | Rôle | Port |
|---|---|---|
| web | L’interface, servie par nginx, qui relaie aussi les appels vers l’application. | 3000 |
| api | L’application : données, exécution de code, git. | 8000 |
Le navigateur ne s’adresse qu’au port 3000 : les appels passent par /api/, relayés en interne. Le port 8000 n’a donc pas besoin d’être exposé à l’extérieur, et vous pouvez retirer sa publication du fichier.
Aucun service de base de données
Par défaut, les données tiennent dans un fichier SQLite rangé avec le reste. Il n’y a pas de conteneur PostgreSQL à gérer, pas de mot de passe de base à choisir. Pour un usage multi-utilisateurs soutenu, PostgreSQL reste possible en changeant l’adresse de la base — voir Configuration.
L’assistant de configuration
Au premier démarrage, l’application détecte qu’aucun compte n’existe et affiche un assistant en trois étapes.
Base de données
Affiche, en lecture seule, le moteur et l’emplacement effectivement utilisés. La base se configure côté serveur et se crée automatiquement ; pour en changer, on modifie la configuration et on redémarre.
Compte administrateur
Nom d’utilisateur et mot de passe du premier administrateur. Cette étape n’est possible que tant qu’aucun compte n’existe.
Données par défaut
Propose d’installer un espace de démonstration — base OMOP, alignements, pipeline ETL, projets d’exemple. Nécessite un accès réseau au catalogue ; sans réseau, l’instance démarre à vide et l’assistant se termine quand même.
Aucune exigence n'est imposée sur le mot de passe administrateur
L’application vérifie seulement que les deux saisies correspondent. La robustesse de ce mot de passe — le compte le plus privilégié de l’instance — est entièrement à votre charge.
Passer à un vrai nom de domaine
Le fichier livré est réglé pour localhost. Deux choses sont à traiter avant d’exposer l’instance.
L’origine autorisée
L’application n’accepte les appels que depuis les origines déclarées. Tant que LINKR_CORS_ORIGINS vaut http://localhost:3000, une instance servie sur un autre nom verra tous ses appels bloqués par le navigateur. Déclarez l’origine publique réelle :
- LINKR_CORS_ORIGINS=https://linkr.exemple.fr
Le joker est refusé au démarrage
Mettre * fait échouer le lancement, avec un message explicite. Ce n’est pas une contrariété à contourner : les appels portant les identifiants de session, un joker autoriserait n’importe quel site à interroger votre instance au nom de vos utilisateurs.
Le chiffrement TLS
Linkr ne termine pas le HTTPS. Le conteneur web écoute en clair sur le port 80 ; c’est à vous de placer devant lui un terminateur TLS — nginx, Traefik, HAProxy, ou le reverse proxy de votre établissement — et d’y gérer les certificats.
Si vous mettez votre propre proxy devant, deux détails comptent
Les WebSockets doivent être relayés sur /api/ aussi, pas seulement sur /ws/ : le terminal d’exécution ouvre sa connexion sous /api/. Un proxy qui n’upgrade que /ws/ donne un terminal qui ne se connecte jamais.
Les délais d’attente doivent être longs. Une exécution R ou Python et une grosse requête dépassent largement les 60 secondes par défaut ; le proxy livré attend jusqu’à une heure.
Taille maximale des envois : deux plafonds, le plus bas gagne
Le proxy livré accepte des corps de requête jusqu’à 512 Mo, tandis que l’application en autorise 2 Go. C’est donc 512 Mo qui s’applique. Pour déposer des fichiers plus gros, relevez la limite du proxy — ou mieux, évitez l’envoi : posez le fichier sur le serveur et désignez-le par son chemin, voir Fichiers sur le serveur.
Où vivent les données
Tout ce que vos utilisateurs créent — la base et chaque fichier — tient dans un seul dossier, monté dans le conteneur. Les images ne contiennent aucune donnée.
Par défaut c’est un volume Docker nommé : il survit aux redémarrages et aux mises à jour, mais Docker en est propriétaire et il est malcommode à copier. Pour le ranger dans un vrai dossier, remplacez la ligne du volume :
volumes:
- /srv/linkr:/root/.linkr
Un dossier monté ne se supprime jamais par accident
docker compose down -v détruit un volume nommé ; un dossier monté n’est jamais touché. C’est la seconde raison de le préférer pour ce à quoi vous tenez.
Le détail de ce que contient ce dossier est dans Configuration, et ce qu’il faut réellement copier dans Sauvegarde et restauration.
Mettre à jour
Les versions sont épinglées volontairement : un latest laisserait une mise à jour déplacer l’application sous une instance en service sans que personne l’ait demandé.
Pour mettre à jour, changez les deux lignes d’image vers la nouvelle version, puis relancez :
docker compose -f docker-compose.hub.yml pull
docker compose -f docker-compose.hub.yml up -d
Les deux lignes se changent ensemble
Les deux images inscrivent la même version de format dans les exports : une paire dépareillée produit des exports en désaccord avec eux-mêmes.
Sauvegardez avant, car le retour arrière n'est pas symétrique
Les migrations de schéma s’appliquent automatiquement au démarrage. Revenir à l’image précédente ne les annule pas : une instance mise à jour ne redescend pas d’un simple changement de version. La sauvegarde prise avant la mise à jour est votre seul vrai retour arrière.
Les migrations ne se lancent pas à la main
Elles s’appliquent à chaque démarrage et ne font rien quand le schéma est déjà à jour. Aucune commande n’est à exécuter lors d’une mise à jour.
Pour aller plus loin
- Configuration — toutes les variables, et ce qu’elles changent.
- Sauvegarde et restauration — ce qu’il faut copier, et dans quel ordre restaurer.
- Authentification et permissions — créer les comptes après l’assistant.
- Modes de déploiement — ce que change le choix du mode.