Pourquoi héberger Plane vous-même plutôt que de payer par siège
L'objection la plus courante contre l'image AIO est que « supervisord-tout-en-un » cache plusieurs services internes, ce qui rend le débogage difficile en cas de problème. En pratique, l'image regroupe cinq composants — API Django, worker Celery, base PostgreSQL, Redis et serveur de fichiers — dans un seul processus supervisord, ce qui simplifie drastiquement le démarrage. Vous n'avez pas à composer une pile multi-conteneurs, à synchroniser les migrations ou à gérer cinq journaux Docker distincts. En cas d'erreur, docker logs <conteneur> et docker exec <conteneur> supervisorctl status suffisent dans la grande majorité des cas. Le blog officiel de Plane annonce plus de 100 000 déploiements Docker et plus de 44 000 déploiements Kubernetes, ce qui donne une mesure de la maturité opérationnelle de l'image. Le modèle économique est clair : vous payez le VPS, pas le siège.
Ce que vous gagnez en hébergeant Plane sur votre propre VPS
- Coût fixe, indépendant de la taille de l'équipe — un VPS unique suffit pour 5 à 50 utilisateurs ; le tarif ne varie pas avec le nombre de sièges.
- Données sous votre contrôle — tickets, commentaires, fichiers et membres d'équipe restent dans votre propre base PostgreSQL, sur votre propre disque.
- Licence AGPL-3.0 — usage commercial et auto-hébergement autorisés sans redevance ; le code source est auditable.
- Issues, cycles, modules, pages et inbox — Plane couvre le suivi de tâches, les sprints, les regroupements fonctionnels, la documentation légère et la gestion des remontées entrantes, sans module séparé.
- Image stable et maintenue —
makeplane/plane-aio-community:stableest mise à jour par l'éditeur et testée comme unité cohérente avant chaque publication. - Mises à jour maîtrisées — vous tirez la nouvelle image quand vous choisissez de le faire ; aucun éditeur ne peut modifier votre environnement de production sans votre accord.
- Intégration possible avec votre chaîne d'outillage — Plane expose une API REST documentée, utilisable pour synchroniser des issues depuis un pipeline CI ou depuis GitHub.
- Résolution simple en cas d'incident — un seul conteneur, un seul journal, un seul point de redémarrage ; pas de stack multi-services à orchestrer manuellement.
Prérequis chiffrés pour un déploiement stable
L'image AIO regroupe plusieurs services dans un seul conteneur : comptez 2 vCPU et 4 Go de RAM au minimum pour un usage équipe. En dessous, le worker Celery et la base PostgreSQL se partagent trop peu de mémoire et les requêtes d'indexation mettent plusieurs secondes. Pour une équipe de plus de dix personnes ou un usage intensif des pages et des cycles, passez à 8 Go. Vous avez besoin de Docker installé sur l'hôte (version 20 ou supérieure), d'un nom de domaine ou d'un sous-domaine pointant vers votre VPS, des ports 80 et 443 ouverts dans votre pare-feu, et d'environ 10 Go d'espace disque pour les volumes de données et les images Docker. Un certificat TLS est indispensable : Plane définit des cookies de session avec Secure, ce qui les rend inutilisables sur HTTP.
Déployer Plane AIO en huit étapes
Préparer l'hôte et installer Docker
Sur un VPS Debian ou Ubuntu fraîchement installé, mettez à jour les paquets, puis installez Docker via le script officiel ou les dépôts APT de Docker :
curl -fsSL https://get.docker.com | sh
systemctl enable --now dockerVérifiez que Docker fonctionne : docker version.
Créer le répertoire de travail et le fichier d'environnement
Créez un dossier dédié et préparez-y le fichier .env minimal :
mkdir -p /opt/plane && cd /opt/planeCréez ensuite /opt/plane/.env avec les variables requises :
SECRET_KEY=$(openssl rand -hex 32)
WEB_URL=https://plane.votre-domaine.com
DATABASE_URL=postgresql://plane:[email protected]:5432/planeSECRET_KEY doit être une chaîne aléatoire longue ; WEB_URL est l'URL publique finale de votre instance — c'est la valeur la plus critique. Si elle est incorrecte, les redirections après connexion et le chargement des assets échouent.
Lancer le conteneur AIO
Démarrez Plane avec la commande suivante, en précisant le chemin vers votre fichier .env et en montant un volume pour les données persistantes :
docker run -d \
--name plane \
--restart unless-stopped \
--env-file /opt/plane/.env \
-v plane-data:/app/plane-data \
-p 127.0.0.1:8080:8080 \
makeplane/plane-aio-community:stableLe port 8080 n'est exposé qu'en loopback : seul le reverse proxy local pourra l'atteindre. Lors du premier démarrage, supervisord lance les migrations Django ; l'interface n'est disponible qu'après une à deux minutes.
Vérifier l'état des services internes
Avant de configurer le reverse proxy, vérifiez que tous les sous-processus sont actifs :
docker exec plane supervisorctl statusVous devez voir les services api, worker, beat, web et nginx en état RUNNING. Si l'un d'eux est en FATAL, lisez les journaux avec docker logs plane pour identifier l'erreur.
Obtenir un certificat TLS avec Certbot
Installez Certbot et le plugin Nginx, puis demandez un certificat pour votre sous-domaine :
apt install -y certbot python3-certbot-nginx
certbot certonly --nginx -d plane.votre-domaine.comCertbot placera les fichiers de certificat dans /etc/letsencrypt/live/plane.votre-domaine.com/.
Configurer Nginx comme reverse proxy HTTPS
Créez /etc/nginx/sites-available/plane.conf :
server {
listen 80;
server_name plane.votre-domaine.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name plane.votre-domaine.com;
ssl_certificate /etc/letsencrypt/live/plane.votre-domaine.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/plane.votre-domaine.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Activez le site et rechargez Nginx :
ln -s /etc/nginx/sites-available/plane.conf /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginxCréer le premier compte administrateur
Ouvrez https://plane.votre-domaine.com dans un navigateur. Plane affiche une page d'inscription au premier accès. Créez un compte administrateur, puis depuis le panneau d'administration — accessible à /god-mode/ — activez les inscriptions par e-mail ou configurez une allowlist de domaines pour limiter l'accès à votre organisation.
Inviter l'équipe et créer le premier projet
Dans Plane, un projet regroupe des issues, des cycles (sprints), des modules (fonctionnalités) et des pages (wiki léger). Créez un projet depuis l'interface, puis invitez vos collaborateurs par e-mail depuis les réglages du projet. Les invitations sont envoyées par le serveur de mail configuré dans votre .env via EMAIL_HOST et EMAIL_PORT.
Configuration post-installation : variables d'environnement clés
Les variables les plus importantes après le démarrage initial sont :
— WEB_URL — l'URL publique complète de l'instance, sans slash final. Une URL mal renseignée cause des redirections cassées après connexion et des assets non chargés (images, CSS, JS). C'est l'erreur la plus courante au premier démarrage.
— SECRET_KEY — chaîne secrète pour la signature des sessions Django. Ne la changez pas après le premier démarrage sans invalider toutes les sessions actives.
— EMAIL_HOST, EMAIL_PORT, EMAIL_HOST_USER, EMAIL_HOST_PASSWORD — nécessaires pour les invitations et les notifications. Sans ces variables, les invitations par e-mail ne partent pas.
— ENABLE_SIGNUP — 1 pour autoriser les inscriptions ouvertes, 0 pour les désactiver (seul l'admin peut créer des comptes).
Après toute modification du fichier .env, redémarrez le conteneur : docker restart plane.
Pour les mises à jour, tirez la nouvelle image puis recréez le conteneur en conservant le volume de données :
docker pull makeplane/plane-aio-community:stable
docker stop plane && docker rm planeRelancez ensuite la commande docker run de l'étape 3 avec les mêmes arguments. Les migrations de base de données sont appliquées automatiquement au démarrage. Si une mise à jour casse l'environnement, retournez à la version précédente en remplaçant stable par le tag exact de l'image précédente — docker images liste les images disponibles localement.
Régressions post-2.3.7 et procédure de mise à jour sûre
Les versions Plane AIO 2.3.7 à 2.4.1 ont introduit plusieurs régressions documentées. Perte des notifications en temps réel lors de la mise à jour du serveur Python entre ces versions. Erreur 500 sur les webhooks sortants si la colonne webhook_trigger est absente dans la migration PostgreSQL — symptôme : django.db.utils.ProgrammingError: column webhook_trigger does not exist dans les logs du conteneur plane-backend. Ralentissement des requêtes de filtre sur les espaces de travail de plus de 5 000 issues (régression d'index corrigée en 2.4.2).
Avant toute mise à jour depuis une version antérieure à 2.4.2, sauvegardez votre base PostgreSQL : docker compose exec -T db pg_dump -U plane plane > plane-backup-$(date +%F).sql. Puis mettez à jour : docker compose pull && docker compose up -d. Si le backend ne démarre pas après la mise à jour, forcez les migrations manuellement : docker compose exec plane-backend python manage.py migrate --run-syncdb. Pour les instances en 2.3.6 ou antérieur, une mise à jour directe vers 2.4.2+ est recommandée pour sauter les versions intermédiaires défectueuses.
Dépannage : erreurs fréquentes et leurs remèdes
Redirections cassées ou assets non chargés après connexion. Message type : l'interface redirige vers http://localhost ou les images et scripts ne se chargent pas. Cause : WEB_URL dans le fichier .env ne correspond pas à l'URL publique réelle. Corrigez la valeur puis redémarrez le conteneur.
Échec de démarrage d'un service interne. Message type dans docker logs plane : FATAL: api: exited too quickly. Vérifiez DATABASE_URL — une URL de connexion incorrecte ou un nom de base inexistant empêche les migrations de s'exécuter et provoque ce type de sortie en erreur fatale.
Le panneau /god-mode/ est inaccessible. L'accès à l'interface d'administration nécessite d'avoir créé le premier compte via l'interface principale, puis d'y accéder avec les identifiants de ce compte. Si vous avez désactivé les inscriptions avant de créer le premier compte, rétablissez temporairement ENABLE_SIGNUP=1, créez le compte, puis repassez à 0.
Les e-mails d'invitation ne partent pas. Vérifiez que EMAIL_HOST et EMAIL_HOST_USER sont renseignés dans .env et que le port SMTP (souvent 587 avec STARTTLS ou 465 avec SSL) est accessible depuis votre VPS. Testez avec docker exec plane python manage.py sendtestemail [email protected].
Performance dégradée avec de nombreux utilisateurs simultanés. Si plusieurs workers Celery peinent à traiter les tâches, augmentez la RAM du VPS avant d'ajuster la concurrence interne. L'image AIO est paramétrée pour un usage équipe standard ; une configuration à très haute charge nécessite de basculer vers une installation multi-conteneurs avec ressources dédiées par composant.
Garder le contrôle de votre infrastructure sans maintenir la couche système
Héberger Plane vous-même montre que la dépendance aux abonnements SaaS n'est pas une fatalité : une image stable, un VPS dimensionné correctement et un reverse proxy TLS suffisent pour une équipe de taille professionnelle. ServOrbit propose des VPS root avec IPv4 dédiée, prêts en quelques minutes, sur lesquels vous avez un accès root complet pour installer Docker et gérer vos propres outils. Si vous souhaitez déléguer la couche système — mises à jour du noyau, durcissement SSH, sauvegardes — l'option administration VPS vous permet de garder le contrôle de vos données tout en externalisant la maintenance de l'hôte. Pour aller plus loin dans votre pratique DevOps, consultez le guide sur l'automatisation de vos serveurs avec Ansible et le guide Docker Compose pour la production.