Guide de déploiement

Déployer Plane sur VPS : guide et régressions post-2.3.7

Déployer sur un VPS Cloud →

Tutoriel

Automatisation

Déployer Plane sur VPS : guide et régressions post-2.3.7

La facture Linear ou Jira grimpe avec chaque nouveau siège, et confier vos tickets de projet à un éditeur tiers n'est pas toujours acceptable. Plane est une alternative sous licence AGPL-3.0, distribuée en édition Community auto-hébergeable avec un installateur Docker Compose officiel. Ce guide montre comment la déployer sur un VPS Linux, la placer derrière un reverse proxy HTTPS, comprendre ce que l'image AIO exige réellement, et diagnostiquer les pannes qui reviennent dans les tickets publics : image MinIO introuvable, boucle de redirection sur la page de profil, problèmes après une montée de version.

13 min de lecture8 étapes
Sommaire· Pourquoi héberger Plane vous-même plutôt que de payer par siège1/11
  1. 01Pourquoi héberger Plane vous-même plutôt que de payer par siège
  2. 02Ce que vous gagnez en hébergeant Plane sur votre propre VPS
  3. 03Prérequis chiffrés pour un déploiement stable
  4. 04Déployer Plane Community en huit étapes
  5. 05Configuration post-installation : les variables qui comptent
  6. 06Stockage objet : l'image MinIO introuvable et la correction de la release 1.4.3
  7. 07Après une montée de version : ce que le ticket 8708 établit, et ce qu'il n'établit pas
  8. 08Installateur Compose ou image AIO : ce que chacun exige
  9. 09Dépannage : boucle de redirection entre /profile/ et /?next_path=/profile/
  10. 10Dépannage : autres erreurs fréquentes et leurs remèdes
  11. 11Garder le contrôle de votre infrastructure sans maintenir la couche système

Pourquoi héberger Plane vous-même plutôt que de payer par siège

Un outil de suivi de tickets concentre ce qu'une équipe a de plus bavard : décisions, pièces jointes, noms de clients, échéances. L'héberger sur votre VPS déplace le coût du nombre de sièges vers la capacité du serveur : vous payez des ressources, pas des utilisateurs. Plane dépasse 61 000 étoiles sur GitHub, son code est publié sous AGPL-3.0 et l'éditeur annonce sur son blog plus de 100 000 déploiements Docker et plus de 44 000 déploiements Kubernetes, ce qui donne une idée de la base installée et de la quantité de retours d'expérience publics disponibles.

Il y a une contrepartie, à connaître avant de commencer. La pile Community comprend plusieurs services : interface web, API, workers, serveur temps réel, base PostgreSQL, cache Valkey, file de messages RabbitMQ, stockage objet compatible S3 et reverse proxy. L'installateur officiel les orchestre avec Docker Compose, mais c'est vous qui répondez des sauvegardes, des mises à jour et de l'état du stockage objet. Les sections qui suivent détaillent chaque point en distinguant ce que les mainteneurs ont confirmé de ce que seuls des utilisateurs ont rapporté.

Ce que vous gagnez en hébergeant Plane sur votre propre VPS

  • Un coût lié à la machine, pas aux sièges — le tarif du VPS ne varie pas avec le nombre de comptes ; ce qui borne l'équipe, ce sont la mémoire et le disque.
  • Des données sous votre contrôle — tickets, commentaires, fichiers et membres restent dans votre base PostgreSQL et votre stockage objet, sur votre disque.
  • Une licence AGPL-3.0 — le code est auditable ; la licence impose de publier vos modifications si vous exposez une version modifiée à des utilisateurs.
  • Issues, cycles, modules, pages et inbox — suivi de tâches, sprints, regroupements fonctionnels, documentation légère et remontées entrantes, sans module séparé.
  • Un installateur officiel — le script setup.sh récupère un docker-compose.yaml et un plane.env publiés avec la release, puis pilote démarrage, arrêt, mise à jour et sauvegarde.
  • Des mises à jour à votre rythme — vous choisissez le moment de la montée de version, après sauvegarde, et le script archive l'ancien fichier Compose avant de le remplacer.
  • Un stockage déportable — base PostgreSQL et stockage S3 peuvent vivre hors du VPS ; la documentation de Plane le recommande pour la production.
  • Une API REST documentée — utile pour synchroniser des issues depuis un pipeline CI ou depuis GitHub.

Prérequis chiffrés pour un déploiement stable

La documentation de Plane indique 2 cœurs et 4 Go de RAM au minimum, avec 8 Go recommandés en production. Comptez 2 vCPU et 8 Go de RAM si l'équipe dépasse une dizaine de personnes ou si vous utilisez beaucoup les pages et les cycles : PostgreSQL, RabbitMQ, les workers et l'API partagent la même machine. Prévoyez 20 Go de disque ou davantage : les images Docker et la base pèsent peu au départ, ce sont les fichiers téléversés qui font grossir le volume uploads.

Il vous faut un Docker récent avec le plugin Compose (le script appelle docker compose), un nom de domaine ou un sous-domaine dont l'enregistrement A pointe vers le VPS, et les ports 80 et 443 ouverts. Un certificat TLS est indispensable en production : sans HTTPS, mots de passe et sessions circulent en clair.

Déployer Plane Community en huit étapes

  1. Préparer l'hôte et installer Docker

    Sur un VPS Debian ou Ubuntu à jour, installez Docker avec le script officiel : curl -fsSL https://get.docker.com | sh. Activez le service avec systemctl enable --now docker, puis vérifiez docker version et docker compose version. Ouvrez les ports 80 et 443 dans le pare-feu et limitez le port 22 à vos adresses.

  2. Télécharger l'installateur officiel

    Créez un dossier dédié avec mkdir -p /opt/plane-selfhost && cd /opt/plane-selfhost, puis téléchargez le script de la dernière release : curl -fsSL -o setup.sh https://github.com/makeplane/plane/releases/latest/download/setup.sh et chmod +x setup.sh. Le script travaille dans le dossier courant : il y crée le sous-dossier plane-app.

  3. Lancer l'installation

    Exécutez ./setup.sh en root ou avec un utilisateur du groupe docker, puis choisissez l'option 1 (Install). Le script télécharge docker-compose.yaml et plane.env dans plane-app/ et, dans les versions récentes, génère des identifiants pour le stockage objet embarqué. Quittez le menu avec l'option 8 avant de configurer : la documentation demande d'arrêter la pile avant toute édition de plane.env.

  4. Renseigner plane.env

    Ouvrez plane-app/plane.env et fixez au minimum APP_DOMAIN=plane.votre-domaine.com, WEB_URL=https://plane.votre-domaine.com et CORS_ALLOWED_ORIGINS=https://plane.votre-domaine.com. Pour laisser Nginx tenir les ports 80 et 443, ajoutez LISTEN_HTTP_PORT=8080. Vérifiez que SECRET_KEY et LIVE_SERVER_SECRET_KEY portent des valeurs uniques, jamais des exemples : openssl rand -hex 32 en produit une.

  5. Démarrer la pile et contrôler les conteneurs

    Relancez ./setup.sh et choisissez l'option 2 (Start). Le premier démarrage télécharge les images, puis le conteneur migrator prépare la base et s'arrête. Contrôlez l'état avec docker compose -f plane-app/docker-compose.yaml --env-file plane-app/plane.env ps : tous les autres conteneurs doivent être en cours d'exécution. L'option 6 du menu affiche les journaux.

  6. Obtenir un certificat TLS avec Certbot

    Installez Nginx et Certbot avec apt install -y nginx certbot python3-certbot-nginx, puis demandez le certificat : certbot certonly --nginx -d plane.votre-domaine.com. Les fichiers sont déposés dans /etc/letsencrypt/live/plane.votre-domaine.com/. Le nom de domaine doit déjà pointer vers le VPS.

  7. Configurer Nginx comme reverse proxy HTTPS

    Créez un site Nginx qui écoute sur le port 443 avec le certificat obtenu et transmet tout vers http://127.0.0.1:8080. Ajoutez les en-têtes Host, X-Real-IP, X-Forwarded-For et X-Forwarded-Proto, ainsi que Upgrade et Connection pour les WebSocket du serveur temps réel. Un second bloc server redirige le port 80 vers HTTPS avec return 301 https://$host$request_uri;. Activez le site, puis nginx -t && systemctl reload nginx. Docker publie le port 8080 sans passer par UFW : fermez-le depuis l'extérieur avec le pare-feu de votre fournisseur.

  8. Créer l'administrateur de l'instance et l'équipe

    Ouvrez https://plane.votre-domaine.com/god-mode/ pour créer le compte administrateur de l'instance. Gardez la barre oblique finale : un utilisateur rapporte qu'une adresse sans elle restait bloquée, point que les mainteneurs n'ont pas confirmé. Ouvrez ensuite l'application, créez l'espace de travail et le premier projet, puis invitez vos collaborateurs.

Configuration post-installation : les variables qui comptent

WEB_URL et CORS_ALLOWED_ORIGINS : la documentation demande de fixer les deux à l'adresse réellement utilisée par le navigateur. C'est la première vérification en cas de comportement étrange après la connexion.

LISTEN_HTTP_PORT et LISTEN_HTTPS_PORT : ports publiés par le proxy embarqué, 80 et 443 par défaut. Changez-les si Nginx occupe déjà les ports standards.

TRUSTED_PROXIES et NUM_PROXIES : ils déterminent l'adresse IP du client vue par l'API, donc la limitation de débit. Derrière votre propre reverse proxy, le README de l'installateur demande d'augmenter NUM_PROXIES d'une unité par saut supplémentaire ; laissé vide, le comportement par défaut s'applique.

UNSPLASH_ACCESS_KEY : optionnelle, elle alimente le sélecteur d'images de couverture. Laissez-la vide si vous n'utilisez pas Unsplash ; c'est le premier réglage à relire en cas de boucle de redirection, décrite plus bas.

APP_RELEASE : la release suivie, stable au départ. Le script la résout en numéro de version lors de l'installation et à chaque mise à jour.

Arrêtez la pile avec l'option 3 avant de modifier plane.env, puis redémarrez avec l'option 4.

Avant toute mise à jour, sauvegardez : l'option 7 du script, plus un dump PostgreSQL avec docker compose -f plane-app/docker-compose.yaml --env-file plane-app/plane.env exec -T plane-db pg_dump -U plane plane > plane-backup-$(date +%F).sql. Lancez ensuite l'option 5 (Upgrade) : le script compare la release installée à la dernière, demande confirmation, archive l'ancien docker-compose.yaml dans plane-app/archive/ et garde une copie plane.env.bak. Relisez plane.env après coup pour repérer les nouvelles variables. Ne mettez jamais à jour par docker compose down -v : l'option -v supprime le volume uploads, donc vos pièces jointes. Les notes de la release v1.4.3, publiée en octobre 2026, corrigent plusieurs failles de contrôle d'accès et demandent aux instances auto-hébergées de mettre à jour.

Stockage objet : l'image MinIO introuvable et la correction de la release 1.4.3

Symptôme. Sur une installation neuve ou une mise à jour, le téléchargement des images échoue sur le service de stockage avec le message pull access denied for minio/minio, repository does not exist or may require 'docker login'. Le registre répond 401 plutôt que 404 à un client anonyme, d'où un message qui ressemble à un problème d'identifiants : aucun docker login n'y change rien.

Confirmé par l'équipe Plane. L'organisation minio a disparu de Docker Hub. La PR #9829, fusionnée en septembre 2026, le constate et bascule les images vers quay.io. Les notes de la release v1.4.3 précisent ensuite que le stockage objet embarqué utilise l'image pgsty/silo, épinglée sur un tag de release plutôt que sur latest. Un contributeur du dépôt a aussi indiqué dans le ticket #9834, ouvert en septembre 2026, que la release avait été mise à jour avec une autre image.

Rapporté par des utilisateurs seulement. Le contournement par quay.io/minio/minio a fonctionné pour certains, puis plusieurs participants ont signalé des erreurs 401 sur ce registre à partir du 24 septembre 2026. Ces retours datent d'avant la correction de la release ; ne les appliquez pas à une installation récente.

Que faire. Sur une installation neuve, utilisez le script de la dernière release, puis vérifiez avec grep -n 'image:' plane-app/docker-compose.yaml qu'aucune ligne ne cite minio/minio. Sur une installation existante qui la cite encore, sauvegardez puis lancez l'option 5 du script. Pour la production, la PR #9829 recommande elle-même de privilégier un stockage S3 externe plutôt que le MinIO embarqué, dont la branche communautaire est gelée en amont selon son auteur : c'est une orientation de l'équipe Plane, pas une garantie.

Après une montée de version : ce que le ticket 8708 établit, et ce qu'il n'établit pas

En mars 2026, un utilisateur a ouvert le ticket #8708 pour décrire une installation difficile. Après le passage de la version 2.3.3 à la 2.3.7, les permissions des fichiers téléversés étaient cassées ; un volume déclaré avec des guillemets simples dans un fichier de l'image AIO était mal interprété ; et le premier bouton proposé à l'administrateur menait à /god-mode sans barre oblique finale, page qui restait bloquée.

Ce que les mainteneurs ont confirmé tient en une phrase : la version 2.3.7 n'est pas une release officielle, elle avait été produite pour un client précis, et la 2.4.0 règle le problème. Ils n'ont confirmé aucune des trois anomalies. L'auteur a répondu que le défaut de guillemets persistait dans le Dockerfile, et le ticket a été clos sans correctif associé.

Retenez trois consignes. Installez uniquement des releases publiées sur la page Releases du dépôt, dont la dernière est v1.4.3 ; ne tirez pas une version intermédiaire. Sauvegardez avant chaque montée de version. Après la mise à jour, ouvrez une pièce jointe ancienne et une récente : si l'ouverture échoue, inspectez les droits du volume d'uploads avec docker volume inspect avant de modifier quoi que ce soit, en gardant la sauvegarde à portée de main.

Installateur Compose ou image AIO : ce que chacun exige

Faites défiler le tableau

CritèreInstallateur Compose (Community)Image AIO Community
Services inclusPostgreSQL, Valkey, RabbitMQ, stockage objet et proxy dans la pile ComposeApplications, API, workers et proxy Caddy dans un seul conteneur
Services externesAucun obligatoire ; recommandés en productionPostgreSQL, Redis, RabbitMQ et stockage S3 à fournir vous-même
Point d'entrée`./setup.sh` et le fichier `plane.env``docker run` avec `DOMAIN_NAME`, `DATABASE_URL`, `REDIS_URL`, `AMQP_URL` et les variables S3
SecretsValeurs à vérifier dans `plane.env``SECRET_KEY` et `LIVE_SERVER_SECRET_KEY` obligatoires : le conteneur s'arrête s'ils sont vides
Mise à jourOption 5 du script, avec archive de l'ancien fichier ComposeTirer la nouvelle image et recréer le conteneur
Usage décritServeur unique, avec stockage externe conseillé en productionDéploiement simple et tests, selon son README

Dépannage : boucle de redirection entre /profile/ et /?next_path=/profile/

Symptôme (ticket #6694, ouvert en mars 2025, encore ouvert le 24 octobre 2026). Derrière un nom de domaine, l'ouverture de https://votre-domaine.com/profile/ renvoie vers https://votre-domaine.com/?next_path=/profile/, puis la page repart en boucle. Dans le journal de l'API de l'auteur, presque toutes les requêtes répondent 200, sauf une qui revient à chaque tour : GET /api/unsplash/?query= HTTP/1.1" 401, suivie de Unauthorized: /api/unsplash/.

Établi. L'auteur utilisait Docker Compose avec un Nginx externe devant Plane. Les mainteneurs ont demandé le mode de déploiement, puis la présence d'un reverse proxy, et ont répondu en mars 2025 qu'ils enquêtaient. Ils n'ont publié aucune cause.

Rapporté. En juillet 2026, un participant a retrouvé le même symptôme : il avait saisi la clé secrète d'Unsplash à la place de la clé d'accès dans UNSPLASH_ACCESS_KEY. Une PR proposée par un contributeur externe, la #10108, encore ouverte le 31 octobre 2026, avance l'explication : l'API renvoie tel quel le 401 d'Unsplash et l'application web traite tout 401 comme une session expirée, d'où la redirection ; elle propose de répondre 502 à la place. C'est une hypothèse de contributeur, appuyée par un seul témoignage, pas un constat des mainteneurs, et elle ne couvre pas forcément toutes les boucles de redirection.

Que faire, dans l'ordre. D'abord, cherchez la ligne dans le journal : docker compose -f plane-app/docker-compose.yaml --env-file plane-app/plane.env logs api | grep unsplash. Si elle n'apparaît pas, votre boucle a une autre cause : relisez WEB_URL et CORS_ALLOWED_ORIGINS. Si elle apparaît avec un 401, relisez UNSPLASH_ACCESS_KEY dans plane.env et dans la section Images du panneau /god-mode/ : il faut la clé d'accès (Access Key), pas la clé secrète. Si vous n'utilisez pas Unsplash, videz la valeur et redémarrez la pile ; selon la PR, une clé absente renvoie une liste vide sans erreur.

Dépannage : autres erreurs fréquentes et leurs remèdes

Redirections vers http://localhost ou ressources qui ne se chargent pas. WEB_URL et CORS_ALLOWED_ORIGINS ne correspondent pas à l'adresse publique. Corrigez les deux, puis arrêtez et redémarrez la pile.

pull access denied for minio/minio. Voir la section sur le stockage objet : passez à une release récente avec l'option 5 du script.

502 Bad Gateway renvoyé par Nginx. Le proxy embarqué n'écoute pas sur le port visé. Comparez LISTEN_HTTP_PORT dans plane.env avec la cible de proxy_pass, puis testez curl -I http://127.0.0.1:8080 depuis le VPS. Si la réponse tarde, docker compose -f plane-app/docker-compose.yaml --env-file plane-app/plane.env ps montre quel conteneur redémarre en boucle.

Les invitations par e-mail ne partent pas. Renseignez le serveur SMTP dans les paramètres e-mail de l'instance, depuis /god-mode/, puis envoyez une invitation de test. Vérifiez aussi que l'hébergeur ne filtre pas le port SMTP sortant.

Lenteur avec beaucoup d'utilisateurs. Observez docker stats : si la mémoire est saturée, augmentez la RAM avant tout autre réglage, puis envisagez de déporter PostgreSQL et le stockage objet hors du VPS.

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é : l'installateur officiel, 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.

Déployer Plane depuis le Marketplace ServOrbit

ServOrbit propose Plane pré-configuré sur VPS : PostgreSQL 16, Redis 7, RabbitMQ et MinIO montés automatiquement. Domaine requis inclus dans la recette — premier accès en quelques minutes, données sous votre contrôle.