Penpot vs Figma : ce que l'alternative open-source change vraiment
Figma et Penpot partagent le même paradigme : design vectoriel dans le navigateur, collaboration en temps réel, composants réutilisables et handoff développeur intégré. La différence fondamentale tient au modèle de données et au contrôle. Figma stocke tout sur ses serveurs, dans un format propriétaire. Penpot s'appuie sur SVG et CSS comme langage de base et tourne sur votre infrastructure : vous décidez où vivent les fichiers, qui s'y connecte et quand vous mettez à jour. Pour une équipe qui auto-héberge déjà son code sur Gitea, sa documentation sur Docmost et sa messagerie sur Mattermost, héberger aussi son outil de design sur ServOrbit est la suite logique. Le prix à payer est l'exploitation : sauvegardes, mises à jour et dimensionnement deviennent votre affaire, et c'est l'objet des sections suivantes.
Ce que Penpot offre hors de la boîte
- Design vectoriel en temps réel — plusieurs designers simultanément sur le même fichier, curseurs visibles, commentaires contextuels sur les calques.
- Composants et bibliothèques partagées — créez des design systems et publiez-les dans des bibliothèques partagées entre projets.
- Handoff développeur natif — inspecteur CSS, export des assets, annotations et mesures d'espacement générées depuis les designs.
- Prototypage interactif — liez des boards avec des transitions et simulez la navigation sans quitter l'outil.
- Mises en page flexibles — auto layouts, grilles CSS et contraintes de redimensionnement comparables à celles de Figma.
- Formats ouverts — export
.penpot(archive complète) et export SVG par board, lisible dans Inkscape ou tout éditeur vectoriel. - Serveur MCP — le service
penpot-mcpexpose vos fichiers aux assistants compatibles MCP (voir l'encadré dédié plus bas).
Architecture : une pile Docker, un seul point d'entrée HTTP
Penpot est une pile de plusieurs conteneurs. Le Compose publié par le projet déclare, à la version 2.18, huit services : penpot-frontend, penpot-backend, penpot-admin-console, penpot-mcp, penpot-exporter, penpot-postgres, penpot-valkey et penpot-mailpit. Le template ServOrbit en démarre un sous-ensemble selon sa version : le nombre exact se lit avec docker compose ps sur votre VPS. Le tableau ci-dessous donne le rôle de chaque service, tel que le Compose amont le décrit. Un seul port compte pour l'exposition : le frontend écoute en interne sur 8080 et le Compose le publie sur 9001. Placez votre reverse proxy devant ce port et rien d'autre.
Les services de la pile Penpot
Faites défiler le tableau
| Service | Rôle | À savoir |
|---|---|---|
| `penpot-frontend` | Sert l'application et route les requêtes vers les autres services | Seul service à exposer : port 9001 dans le Compose amont |
| `penpot-backend` | API et logique métier (application Java/Clojure) | Fichiers (assets) dans un volume, SMTP et stockage configurés ici |
| `penpot-exporter` | Exports PNG, PDF et SVG via un navigateur headless | Joint l'application par `PENPOT_PUBLIC_URI` : certificat valide requis |
| `penpot-postgres` | Base PostgreSQL 15 : comptes, projets, fichiers | Volume `penpot_postgres_v15` à sauvegarder |
| `penpot-valkey` | Notifications temps réel (websockets) et cache | Plafonné à 128 Mo (`--maxmemory 128mb`) dans le Compose amont |
| `penpot-mcp` | Serveur MCP pour assistants IA | Activé par le flag `enable-mcp`, websocket `/mcp/ws` |
| `penpot-admin-console` | Console d'administration | Ajoutée à la pile en 2.18, flag `enable-admin-console` |
| `penpot-mailpit` | Boîte SMTP de test (interface sur le port 8025) | À remplacer par un vrai SMTP en production |
Prérequis chiffrés : RAM, CPU, disque, ports
La documentation amont ne publie pas de plancher mini pour une petite équipe. Elle indique que 4 CPU et 16 Go de RAM suffisent à servir des milliers d'utilisateurs, et vous autorise à rester prudent dans l'allocation. Côté disque, elle recommande de partir de 50 à 100 Go de base de données avec une taille extensible, ce qui couvre jusqu'à 10 éditeurs, puis environ 5 Go de plus par éditeur supplémentaire. La taille réelle dépend de l'usage et de la complexité des fichiers, pas du nombre de comptes. Notre recommandation éditoriale pour une équipe de quelques personnes : un VPS de 4 Go de RAM avec une limite par service (section mémoire plus bas), ce qui laisse de la marge à l'export de fichiers lourds ; 2 Go conviennent pour un essai. Côté réseau, ouvrez 80 et 443 vers le reverse proxy, jamais 9001 ni 8025 directement. Le corps de requête maximal du Compose est de 367001600 octets (350 Mio) : la directive client_max_body_size de votre proxy doit suivre. Côté poste, la documentation recommande la dernière version stable de Chrome.
Déploiement en 8 étapes
Commandez un VPS ServOrbit
Prévoyez 4 Go de RAM pour un usage en équipe, 2 Go pour un essai. Ubuntu 24.04 LTS est le template par défaut. Gardez au moins 50 Go de disque libre si vous importez des fichiers volumineux.
Pointez un sous-domaine vers votre VPS
Créez un enregistrement A pour
design.votre-domaine.comvers l'IP du VPS. Le provisioner ServOrbit génère un certificat Let's Encrypt. Un domaine en HTTPS est indispensable : Penpot pose des cookies de sessionsecurepar défaut, et la documentation amont réservedisable-secure-session-cookiesaux essais hors production.Installez depuis le marketplace
Dans la console ServOrbit : Marketplace, Collaboration, Penpot, Déployer. Le job AWX démarre les conteneurs, génère
PENPOT_SECRET_KEYet fixePENPOT_PUBLIC_URIsur votre domaine. L'interface répond surhttps://design.votre-domaine.comen quelques minutes.Vérifiez que tous les services tournent
Connectez-vous en SSH et lancez
docker compose lspour repérer le fichier Compose, puisdocker compose -p penpot -f docker-compose.yaml ps. Chaque service doit être à l'étatrunning,penpot-postgresetpenpot-valkeyenhealthy. Les journaux se lisent avecdocker compose -p penpot -f docker-compose.yaml logs -f.Créez votre compte
L'inscription est ouverte par défaut. Ouvrez
https://design.votre-domaine.comet cliquez sur « Créer un compte » : dans le Compose amont la vérification par e-mail est désactivée (disable-email-verification), le compte est donc actif immédiatement. Créez le vôtre tout de suite, avant que quelqu'un d'autre ne le fasse.Fermez les inscriptions publiques
Ajoutez le flag
disable-registrationàPENPOT_FLAGS(frontend et backend) puis recréez les conteneurs. Les invitations continuent de fonctionner tant queenable-login-with-passwordreste actif. Pour créer un compte sans invitation, exécutezdocker exec -ti penpot-penpot-backend-1 python3 manage.py create-profile: le script exige le flagenable-prepl-serveret le nom du conteneur peut varier, vérifiez-le avecdocker ps.Branchez un vrai serveur SMTP
Sans SMTP, aucune invitation ni réinitialisation de mot de passe ne part. Voir la section suivante pour les variables.
Importez vos fichiers Figma
Penpot n'ouvre pas les fichiers
.figdirectement. Le chemin officiel passe par le plugin Figma « Penpot Exporter », qui produit une archive.zipà importer dans Penpot. La procédure et ses limites sont détaillées plus bas.
Configuration post-installation : e-mail et stockage des fichiers
Pour l'e-mail, activez enable-smtp dans PENPOT_FLAGS et renseignez sur le backend PENPOT_SMTP_DEFAULT_FROM, PENPOT_SMTP_DEFAULT_REPLY_TO, PENPOT_SMTP_HOST, PENPOT_SMTP_PORT (587 dans l'exemple amont), PENPOT_SMTP_USERNAME, PENPOT_SMTP_PASSWORD et PENPOT_SMTP_TLS. Le Compose amont pointe par défaut vers penpot-mailpit, qui garde les messages en mémoire et les perd à la recréation du conteneur. En production, retirez aussi disable-email-verification, que la documentation déconseille hors essai. Côté fichiers, les images et clips SVG envoyés par les utilisateurs sont stockés par défaut sur le système de fichiers, dans le volume penpot_assets monté sur /opt/data/assets (PENPOT_OBJECTS_STORAGE_BACKEND: fs). Un stockage compatible S3 est possible avec PENPOT_OBJECTS_STORAGE_BACKEND: s3, un bucket, un endpoint optionnel et les variables AWS_ACCESS_KEY_ID et AWS_SECRET_ACCESS_KEY. Depuis la version 2.11.0, les anciens noms PENPOT_STORAGE_ASSETS_* ont été remplacés par PENPOT_OBJECTS_STORAGE_* : si vous reprenez un vieux Compose, renommez-les.
Sauvegarde et mise à jour
Une instance Penpot a deux états à sauvegarder ensemble : la base PostgreSQL et le volume des fichiers. La documentation amont prévient qu'on ne peut pas copier directement le dossier de données d'un volume Docker et renvoie à la procédure de sauvegarde de volume de Docker. Notre approche : un export logique de la base avec docker exec penpot-penpot-postgres-1 pg_dump -U penpot penpot > penpot.sql, puis une archive du volume des fichiers via un conteneur temporaire qui le monte en lecture. Repérez les noms de volumes avec docker volume ls. Prenez les deux au même moment, sinon la base peut référencer des fichiers absents de l'archive, et testez une restauration sur un autre VPS avant d'en avoir besoin. Pour la mise à jour, fixez la version avec PENPOT_VERSION plutôt que de suivre la dernière image, lancez docker compose -p penpot -f docker-compose.yaml pull puis up -d, et avancez par petites étapes : la documentation déconseille de sauter entre versions éloignées. Au 1er novembre 2026, la dernière version publiée est la 2.18.5. Si vous maintenez votre propre Compose, la 2.18 a ajouté le service penpot-admin-console et la variable PENPOT_ADMIN_CONSOLE_URI sur le frontend et le backend. Sauvegardez toujours avant de mettre à jour.
Mémoire : ce que rapporte le fil #3299 et comment la borner
Le ticket penpot #3299, ouvert en juin 2023, est toujours ouvert et a reçu un message en octobre 2026. Il rassemble des témoignages de consommation de RAM élevée sur des installations Docker : un utilisateur rapporte environ 20 Go occupés après trois à quatre jours sur un serveur de 64 Go, un autre plus de 50 Go demandés par une VM sans utilisateur, un dernier 15 Go pour un seul utilisateur avec un redémarrage du backend toutes les 12 heures. Ce sont des rapports individuels, non reproduits : un membre de l'équipe Penpot répond dans le fil qu'il dispose d'installations Docker à fort trafic sans ce symptôme, et demande un fichier et des traces pour diagnostiquer. Nous ne pouvons donc pas promettre de chiffre de consommation. Ce que nous pouvons dire, c'est comment ne pas laisser un service seul décider : le backend est un processus Java, et sans limite de conteneur la machine virtuelle Java dimensionne son tas d'après la mémoire qu'elle voit, c'est-à-dire celle de l'hôte entier. Une limite par service transforme une dérive silencieuse en redémarrage contrôlé.
Dimensionner la mémoire : limite, surveillance, redémarrage planifié
Un contributeur du fil #3299 rapporte avoir ajouté mem_limit: 12g à tous les services du Compose pour garder la consommation supportable. Sur un VPS de 4 Go, posez des valeurs plus basses, par exemple mem_limit: 2g sur penpot-backend et mem_limit: 1g sur penpot-exporter, et laissez le reste à PostgreSQL et au système. Le script de lancement du backend ajoute JVM_OPTS et JAVA_OPTS à la ligne de commande Java : vous pouvez y passer -XX:MaxRAMPercentage=70, option standard de la JVM, mais la documentation Penpot ne décrit aucun réglage JVM, testez-le avant la production. Surveillez avec docker stats --no-stream, et si le backend dérive malgré la limite, prévoyez un redémarrage de nuit (docker compose -p penpot -f docker-compose.yaml restart penpot-backend) : les collaborateurs reconnectent leurs websockets. Valkey est déjà plafonné à 128 Mo dans le Compose amont. Si la limite est atteinte trop souvent, c'est le signal de choisir une offre VPS avec plus de RAM, pas de relever la limite à l'aveugle.
Importer ses fichiers depuis Figma
Contrairement à ce qu'on lit parfois, Penpot n'importe pas un fichier .fig. Le projet maintient un plugin Figma, « Penpot Exporter », qui convertit un fichier Figma en archive .zip importable. Dans Figma, ouvrez le fichier, puis Resources, Plugins, cherchez « Penpot Exporter » et lancez l'export. Dans Penpot, ouvrez le menu à trois points d'un projet ou des brouillons, choisissez « Import Penpot files » et sélectionnez le .zip. D'après le README du plugin, sont repris les formes de base, vecteurs, frames et sections (des boards dans Penpot), groupes et masques, textes, remplissages, contours, ombres, composants et instances, auto layouts, variants et bibliothèques de couleurs et de typographies. Ne sont pas repris : les réglages de prototypage. Les fichiers très volumineux restent un point difficile, car l'export parcourt chaque nœud sous les limites de l'API Figma, et certains rendus peuvent différer légèrement. Importez d'abord un fichier de test, comparez les composants et les polices, puis migrez le reste. Les polices personnalisées se téléversent dans Penpot.
Intégrer Penpot dans votre workflow Git
Penpot ne stocke pas vos designs comme des fichiers texte dans un dépôt : la source de vérité est la base PostgreSQL. En revanche, deux exports se prêtent à Git. L'archive .penpot sert de sauvegarde portable d'un fichier. L'export SVG d'un board produit un texte lisible que vous pouvez commiter dans Gitea, par exemple pour les icônes et illustrations d'un design system. Une pull request affiche alors le diff du SVG, et votre pipeline CI peut détecter une modification inattendue. Cette approche reste une convention d'équipe : elle suppose de re-exporter à chaque changement, ce qu'un script ou une revue de design peut vous rappeler.
Penpot MCP : piloter vos designs depuis un assistant IA
Le Compose amont inclut un service penpot-mcp, activé par le flag enable-mcp, et son reverse proxy doit relayer la websocket /mcp/ws en plus de /ws/notifications. Un client compatible MCP peut alors se connecter à votre instance. Réservez cet accès à des comptes de confiance et servez-le en HTTPS. Testez d'abord sur un fichier de brouillon, puis généralisez si le résultat vous convient.
Dépannage : les erreurs réellement rapportées
- Bannière « Something wrong has happened » ou cookie
auth-tokenrejeté — rapporté sur un serveur joint en HTTP depuis le réseau local. Réponse d'un membre de l'équipe Penpot : les cookies sontsecurepar défaut, frontend et backend doivent être servis en HTTPS. Servez l'instance derrière un certificat valide et fixezPENPOT_PUBLIC_URIsur l'URL exacte. - Erreur interne après quelques clics sur l'inscription ou la connexion — rapporté avec
disable-secure-session-cookiessur un accès HTTP public. Même remède : HTTPS. Le flag n'est pas un correctif de production. WebSocket connection to 'wss://…/ws/notifications…' failed: Invalid frame header— rapporté juste après la connexion, avec l'interface qui se fige, derrière Nginx. La réponse donnée dans la communauté est de relayer/ws/notificationsavec les en-têtesUpgradeetConnectionvers le port 9001. Le fil ne confirme pas que cela a levé le cas du demandeur.net::ERR_CERT_AUTHORITY_INVALIDdans les journaux depenpot-exporter— l'export échoue. L'exporteur charge l'application parPENPOT_PUBLIC_URI: avec un certificat auto-signé ou non reconnu, il ne peut pas valider la connexion. Utilisez un certificat d'une autorité reconnue.- Export PDF qui expire sans message clair — rapporté sur une installation manuelle où l'exporteur recevait
PENPOT_PUBLIC_URI=http://localhost. L'exporteur doit pouvoir joindre l'URL publique de l'application, pas une adresse locale à son propre conteneur. - Impossible de se connecter, aucune piste — vérifiez d'abord
docker compose -p penpot -f docker-compose.yaml ps, puis les journaux du service concerné, et la console du navigateur (F12) qui affiche la version exacte de Penpot et les requêtes en erreur.