Aller au contenu

Déploiement avec Docker ​

Mindwtr fournit une prise en charge officielle de Docker pour exécuter :

  • mindwtr-app : la version web de bureau/PWA, servie par Nginx.
  • mindwtr-cloud : le serveur léger de synchronisation et l’API REST d’automatisation des tâches.

Ces composants sont disponibles sous forme d’images Docker et peuvent être facilement orchestrés avec Docker Compose.


Démarrage rapide (Docker Compose) ​

Vous n’avez pas besoin de cloner le dépôt. Les images officielles sont publiées sur GHCR, et le fichier compose.yaml les télécharge pour vous.

  1. Téléchargez le fichier compose :

    bash
    curl -LO https://raw.githubusercontent.com/dongdongbh/Mindwtr/main/docker/compose.yaml
  2. Créez un fichier .env à côté (Docker Compose le lit automatiquement) :

    dotenv
    MINDWTR_CLOUD_AUTH_TOKENS=your_token_here
    MINDWTR_CLOUD_CORS_ORIGIN=http://localhost:5173

    MINDWTR_CLOUD_CORS_ORIGIN doit correspondre exactement à l’adresse à laquelle vous ouvrez la PWA dans votre navigateur, schéma et port compris. http://localhost:5173 ne fonctionne que si le navigateur s’exécute sur l’hôte Docker lui-même. Depuis une autre machine, utilisez l’adresse de l’hôte, par exemple http://192.168.1.20:5173. Une seule origine peut être définie.

  3. Téléchargez et démarrez les services :

    bash
    docker compose pull
    docker compose up -d
  4. Accédez aux services :

    • PWA (application web) : ouvrez http://localhost:5173 dans votre navigateur.
    • Contrôle de disponibilité du Cloud : ouvrez http://localhost:8787/health.
    • Contrôle de l’espace de stockage du Cloud : ouvrez http://localhost:8787/ready.
    • URL auto-hébergée pour les tests locaux : http://localhost:8787
    • URL de base de l’API REST : http://localhost:8787/v1

/health indique seulement que le serveur cloud répond aux requêtes HTTP. /ready vérifie en plus que le répertoire de données configuré est accessible en écriture : c’est donc l’adresse à consulter pour savoir si le serveur peut réellement enregistrer vos données. Compose utilise le contrôle de santé intégré à l’image : les images actuelles vérifient /ready, les anciennes /health.

Pour construire les images depuis les sources, clonez le dépôt et exécutez docker compose -f docker/compose.yaml up --build -d depuis sa racine. Voir Construction manuelle ci-dessous.

Ce fichier Compose par défaut utilise uniquement HTTP et est destiné aux tests locaux ou privés. Les clients de bureau et mobiles Mindwtr n’acceptent HTTP que pour les cibles locales ou privées reconnues, comme localhost, 127.0.0.1, 10.x.x.x, 172.16.x.x à 172.31.x.x, 192.168.x.x, les adresses IPv6 de bouclage ou privées, *.local et *.home.arpa.

Pour les URL publiques, les noms DNS personnalisés, les noms d’hôte VPN, Tailscale, ZeroTier ou tout nom qui n’est pas reconnu comme local ou privé, utilisez HTTPS, ou activez Autoriser HTTP non sécurisé (non recommandé) dans les réglages de synchronisation de l’application pour accepter ce nom d’hôte en HTTP non chiffré. Les données circulent alors en clair ; ne l’utilisez que sur un réseau de confiance.


Configuration HTTPS avec Caddy ​

Pour la synchronisation publique depuis un ordinateur ou un appareil mobile, utilisez le fichier Compose reposant sur Caddy :

bash
cp docker/.env.https.example docker/.env.https.local

Modifiez docker/.env.https.local :

dotenv
MINDWTR_CLOUD_DOMAIN=mindwtr.example.com
MINDWTR_CLOUD_AUTH_TOKENS=your_long_random_token
MINDWTR_CLOUD_CORS_ORIGIN=https://mindwtr.example.com
MINDWTR_CADDYFILE=Caddyfile.https

Démarrez la pile :

bash
docker compose --env-file docker/.env.https.local -f docker/compose.https.yaml up -d

Vérifiez le serveur :

bash
curl https://mindwtr.example.com/health
curl https://mindwtr.example.com/ready

Dans Mindwtr, sous Réglages -> Synchronisation -> Auto-hébergé, définissez l’URL auto-hébergée sur :

text
https://mindwtr.example.com

Mindwtr ajoutera automatiquement /v1/data.

HTTPS public ​

Utilisez Caddyfile.https lorsque MINDWTR_CLOUD_DOMAIN est un nom DNS public qui pointe vers cet hôte Docker. Les ports 80 et 443 doivent être accessibles pour l’émission automatique du certificat. Caddy obtient le certificat, le renouvelle et transmet les requêtes à mindwtr-cloud par proxy inverse.

HTTPS sur réseau local uniquement ​

Utilisez Caddyfile.local-https lorsque le nom d’hôte n’est résolu que sur votre réseau domestique :

dotenv
MINDWTR_CLOUD_DOMAIN=mindwtr.home.arpa
MINDWTR_CLOUD_CORS_ORIGIN=https://mindwtr.home.arpa
MINDWTR_CADDYFILE=Caddyfile.local-https

Cette configuration utilise l’autorité de certification interne de Caddy. Chaque appareil client doit faire confiance au certificat racine local de Caddy avant que Mindwtr n’accepte la connexion HTTPS. Mindwtr 1.2.0 et les versions ultérieures font confiance aux autorités installées par l’utilisateur sur Android ; sur iPhone et iPad, il faut aussi installer le certificat racine et activer explicitement la confiance totale. Les certificats publics Let’s Encrypt restent la solution la plus simple lorsque le nom d’hôte est accessible publiquement.

Après le démarrage de la pile réservée au réseau local, exportez le certificat racine local de Caddy :

bash
docker compose --env-file docker/.env.https.local -f docker/compose.https.yaml cp caddy:/data/caddy/pki/authorities/local/root.crt ./mindwtr-caddy-root.crt

Installez ce certificat comme racine de confiance sur chaque appareil qui se synchronisera avec ce nom d’hôte.


Configuration ​

Jeton de synchronisation ​

Le serveur Cloud exige un jeton pour l’authentification. Vous devez le définir dans les variables d’environnement.

Dans docker/compose.yaml (ou via une variable d’environnement), définissez :

yaml
MINDWTR_CLOUD_AUTH_TOKENS=your_token_here

MINDWTR_CLOUD_TOKEN reste accepté pour la rétrocompatibilité, mais il est obsolète.

Pour un secret Docker basé sur un fichier, retirez MINDWTR_CLOUD_AUTH_TOKENS de votre fichier .env, placez le jeton dans un fichier de l’hôte que seul son propriétaire peut lire, puis démarrez Compose avec la surcouche docker/compose.secrets.yaml. MINDWTR_CLOUD_AUTH_TOKENS_FILE_HOST doit être un chemin absolu sur l’hôte :

bash
printf '%s\n' 'replace_with_a_token_at_least_20_characters_long' > /absolute/path/mindwtr-cloud-tokens
chmod 600 /absolute/path/mindwtr-cloud-tokens
MINDWTR_CLOUD_AUTH_TOKENS_FILE_HOST=/absolute/path/mindwtr-cloud-tokens \
  docker compose -f docker/compose.yaml -f docker/compose.secrets.yaml up -d

La surcouche monte ce fichier en lecture seule sur /run/secrets/mindwtr_cloud_tokens et définit MINDWTR_CLOUD_AUTH_TOKENS_FILE à votre place ; le jeton n’arrive donc jamais dans l’environnement Compose généré. Laissez le fichier de l’hôte en mode 0600. Le serveur refuse toujours de démarrer si ni le réglage écrit directement ni un fichier de jeton lisible ne fournit un jeton valide.

La même surcouche fonctionne avec la pile HTTPS de Caddy. Retirez le jeton écrit directement dans docker/.env.https.local, puis exécutez :

bash
MINDWTR_CLOUD_AUTH_TOKENS_FILE_HOST=/absolute/path/mindwtr-cloud-tokens \
  docker compose --env-file docker/.env.https.local \
    -f docker/compose.https.yaml -f docker/compose.secrets.yaml up -d

Générer un jeton : Vous pouvez générer un jeton aléatoire robuste avec :

bash
cat /dev/urandom | LC_ALL=C tr -dc 'a-zA-Z0-9' | fold -w 50 | head -n 1

Configuration du client ​

Pour connecter vos clients Mindwtr (bureau ou mobile) à ce Cloud auto-hébergé :

  1. Accédez à Réglages → Synchronisation.
  2. Sélectionnez Auto-hébergé (ou Cloud).
  3. Définissez l’URL auto-hébergée sur le point de terminaison de base de votre serveur :
    http://localhost:8787
    Mindwtr ajoutera automatiquement /v1/data à cette URL.
  4. Saisissez le même jeton que celui configuré dans MINDWTR_CLOUD_AUTH_TOKENS.

Pour HTTP sur un réseau local privé, utilisez une adresse locale ou privée telle que http://192.168.1.20:8787. Pour les URL publiques, utilisez la configuration HTTPS avec Caddy décrite ci-dessus.

Préremplir les réglages de synchronisation de l'application web ​

Un nouveau navigateur ouvrant la PWA peut arriver avec l'URL du cloud déjà remplie, de sorte qu'il ne reste qu'à saisir le jeton :

  • Même domaine (recommandé) : quand l'application et l'API cloud partagent un domaine (comme dans la configuration HTTPS avec Caddy), l'application web détecte le cloud sur sa propre origine automatiquement. Rien à configurer.
  • Domaines séparés : définissez MINDWTR_DEFAULT_CLOUD_URL sur le conteneur mindwtr-app avec l'URL publique du cloud, par exemple sous Kubernetes ou dans tout déploiement où l'application et l'API vivent sur des hôtes différents.

La valeur ne fait que préremplir le formulaire de configuration. Elle n'écrase jamais une URL déjà configurée, et la synchronisation reste désactivée tant que la personne n'enregistre pas avec son jeton.

Restreindre qui peut ouvrir l'application web hébergée ​

La version navigateur est un bundle statique, et les données qu'elle affiche ne vivent que dans le stockage de chaque navigateur ; les données de tâches et l'API sont protégées par le jeton bearer sur /v1/*. Mindwtr n'a donc pas d'écran de connexion propre. Si l'application web est accessible depuis internet et que vous ne voulez pas que des inconnus l'ouvrent, mettez une authentification HTTP Basic sur le proxy placé devant, sur tous les chemins sauf /v1/*, afin que les navigateurs se connectent une fois tandis que les applications de bureau et mobiles continuent d'utiliser leur jeton bearer. Avec le Caddy fourni, générez un hachage avec caddy hash-password et utilisez :

example.com {
	@ui not path /v1/*
	basic_auth @ui {
		alice <bcrypt hash>
	}
	handle /v1/* {
		reverse_proxy mindwtr-cloud:8787
	}
	handle {
		reverse_proxy mindwtr-app:5173
	}
}

Avec nginx, placez auth_basic dans le bloc location / et laissez location /v1/ sans. Gardez MINDWTR_CLOUD_AUTH_TOKENS et MINDWTR_CLOUD_CORS_ORIGIN définis comme décrit plus haut ; ce sont eux qui protègent les données, la connexion au proxy décide seulement qui peut charger la page.

Synchronisation Dropbox et PWA Docker ​

L’image Docker mindwtr-app sert la version navigateur/PWA. La synchronisation OAuth native avec Dropbox n’est pas disponible dans cet environnement d’exécution, car la connexion Dropbox est implémentée par les applications natives de bureau et mobiles. Ajouter VITE_DROPBOX_APP_KEY ou DROPBOX_APP_KEY via .env, env_file, l’environnement d’exécution Compose ou un argument de construction Docker n’activera pas Dropbox dans Docker.

Pour une synchronisation hébergée avec Docker, utilisez le serveur Cloud auto-hébergé fourni ou WebDAV. Si le point de terminaison auto-hébergé se trouve derrière Authelia ou un autre proxy SSO interactif, configurez le proxy pour que le chemin de synchronisation/API de Mindwtr utilise directement le jeton porteur de Mindwtr ; l’application mobile ne peut pas effectuer une connexion Authelia dans le navigateur devant /v1/data.

Rappels dans la PWA Docker ​

Les rappels de tâche, de date de début, d’échéance et de revue s’affichent aussi dans la version navigateur, sous forme de notifications web. Accordez l’autorisation de notification au site (Réglages → Notifications) et gardez un onglet Mindwtr ouvert : la version navigateur n’a pas de service en arrière-plan, les rappels ne sont donc délivrés que tant qu’un onglet tourne. Un onglet en arrière-plan voit ses minuteurs bridés, un rappel peut donc arriver jusqu’à une minute en retard, et celui atteint alors que tous les onglets étaient fermés est ignoré plutôt que délivré ensuite. Pour des rappels qui survivent à un navigateur fermé, utilisez l’application de bureau ou mobile.

API d’automatisation des tâches ​

Le même conteneur mindwtr-cloud expose également l’API REST d’automatisation des tâches. Elle utilise la même URL de base et le même jeton porteur que la synchronisation.

Points de terminaison courants :

  • GET /v1/data et PUT /v1/data pour la synchronisation
  • GET /v1/tasks et POST /v1/tasks pour répertorier et créer des tâches
  • GET /v1/projects pour les projets
  • GET /v1/search?query=... pour rechercher des tâches et des projets

Exemple :

bash
curl -X POST http://localhost:8787/v1/tasks \
  -H "Authorization: Bearer your_token_here" \
  -H "Content-Type: application/json" \
  -d '{"input":"Review PR @work /due:tomorrow"}'

Origine CORS (production) ​

Le serveur Cloud utilise par défaut http://localhost:5173 pour CORS. En production, définissez :

yaml
MINDWTR_CLOUD_CORS_ORIGIN=https://your-app-domain.example

Persistance des données ​

Pour protéger vos données Cloud lors des redémarrages des conteneurs, montez un volume pour le répertoire de données.

Dans votre compose.yaml :

yaml
volumes:
  - ./data:/app/cloud_data

Construction manuelle ​

Si vous préférez construire les images vous-même sans Compose :

Construire la PWA :

bash
docker build -f docker/app/Dockerfile -t mindwtr-app .

Construire le serveur Cloud :

bash
docker build -f docker/cloud/Dockerfile -t mindwtr-cloud .

GitHub Actions et GHCR ​

Le projet comprend un workflow GitHub Actions qui construit automatiquement les images et les publie dans le GitHub Container Registry (GHCR).

Images officielles :

  • ghcr.io/dongdongbh/mindwtr-app:latest
  • ghcr.io/dongdongbh/mindwtr-cloud:latest

Les versions préliminaires sont disponibles sous l’étiquette flottante beta, qui pointe toujours vers la version la plus récente (candidate ou stable), ou peuvent être épinglées par version, par exemple ghcr.io/dongdongbh/mindwtr-app:1.2.0-rc.1. latest reste toujours sur la version stable. Consultez Rejoindre les canaux bêta pour les autres plateformes.

Le fichier docker/compose.yaml est configuré pour utiliser ces images par défaut, ce qui permet de récupérer facilement la dernière version sans la construire localement.


Notes techniques ​

  • Service de la PWA : l’application web utilise un rendu côté client. Le conteneur Nginx est configuré avec try_files pour rediriger toutes les requêtes vers index.html, ce qui évite les erreurs 404 lors de l’actualisation d’une page.
  • Image de base : la construction utilise Bun (épinglé à la v1.3) et inclut les options C++20 requises pour better-sqlite3.

Mindwtr est gratuit, open source et local.
Getting Things Done et GTD sont des marques déposées de David Allen Company. Mindwtr n’est ni affilié à David Allen Company, ni approuvé ou parrainé par celle-ci.