Penpot vs Figma: lo que cambia realmente la alternativa de código abierto
Figma y Penpot comparten el mismo paradigma: diseño vectorial en el navegador, colaboración en tiempo real, componentes reutilizables y entrega a desarrollo integrada. La diferencia fundamental está en el modelo de datos y en el control. Figma guarda todo en sus servidores, en un formato propietario. Penpot se apoya en SVG y CSS como lenguaje base y funciona en su infraestructura: usted decide dónde viven los archivos, quién se conecta y cuándo actualiza. Para un equipo que ya autoaloja su código en Gitea, su documentación en Docmost y su mensajería en Mattermost, alojar también la herramienta de diseño en ServOrbit es la continuación lógica. El precio es la operación: copias de seguridad, actualizaciones y dimensionamiento pasan a ser cosa suya, y de eso tratan las secciones siguientes.
Lo que Penpot ofrece de serie
- Diseño vectorial en tiempo real — varios diseñadores a la vez en el mismo archivo, cursores visibles, comentarios contextuales sobre las capas.
- Componentes y bibliotecas compartidas — cree sistemas de diseño y publíquelos en bibliotecas compartidas entre proyectos.
- Entrega a desarrollo nativa — inspector CSS, exportación de assets, anotaciones y medidas de espaciado generadas a partir de los diseños.
- Prototipado interactivo — enlace boards con transiciones y simule la navegación sin salir de la herramienta.
- Maquetación flexible — auto layouts, cuadrículas CSS y restricciones de redimensionado comparables a las de Figma.
- Formatos abiertos — exportación
.penpot(archivo completo) y exportación SVG por board, legible en Inkscape o en cualquier editor vectorial. - Servidor MCP — el servicio
penpot-mcpexpone sus archivos a los asistentes compatibles con MCP (véase el recuadro dedicado más abajo).
Arquitectura: una pila Docker, un único punto de entrada HTTP
Penpot es una pila de varios contenedores. El Compose publicado por el proyecto declara, en la versión 2.18, ocho servicios: penpot-frontend, penpot-backend, penpot-admin-console, penpot-mcp, penpot-exporter, penpot-postgres, penpot-valkey y penpot-mailpit. La plantilla de ServOrbit arranca un subconjunto según su versión: el número exacto se lee con docker compose ps en su VPS. La tabla siguiente da el papel de cada servicio tal como lo describe el Compose original. Solo un puerto cuenta de cara a la exposición: el frontend escucha internamente en el 8080 y el Compose lo publica en el 9001. Ponga su proxy inverso delante de ese puerto y de ningún otro.
Los servicios de la pila Penpot
Desplace la tabla
| Servicio | Papel | A tener en cuenta |
|---|---|---|
| `penpot-frontend` | Sirve la aplicación y enruta las peticiones a los demás servicios | Único servicio que se expone: puerto 9001 en el Compose original |
| `penpot-backend` | API y lógica de negocio (aplicación Java/Clojure) | Archivos (assets) en un volumen; aquí se configuran SMTP y almacenamiento |
| `penpot-exporter` | Exportaciones PNG, PDF y SVG mediante un navegador headless | Llega a la aplicación por `PENPOT_PUBLIC_URI`: se exige un certificado válido |
| `penpot-postgres` | Base de datos PostgreSQL 15: cuentas, proyectos, archivos | Hay que respaldar el volumen `penpot_postgres_v15` |
| `penpot-valkey` | Notificaciones en tiempo real (websockets) y caché | Limitado a 128 MB (`--maxmemory 128mb`) en el Compose original |
| `penpot-mcp` | Servidor MCP para asistentes de IA | Se activa con el flag `enable-mcp`, websocket `/mcp/ws` |
| `penpot-admin-console` | Consola de administración | Añadida a la pila en la 2.18, flag `enable-admin-console` |
| `penpot-mailpit` | Buzón SMTP de pruebas (interfaz en el puerto 8025) | Sustituir por un SMTP real en producción |
Requisitos cuantificados: RAM, CPU, disco, puertos
La documentación original no publica un mínimo para un equipo pequeño. Indica que 4 CPU y 16 GB de RAM bastan para servir a miles de usuarios y permite ser prudente al asignar recursos. En disco, recomienda partir de 50 a 100 GB de base de datos con tamaño elástico, lo que cubre hasta 10 editores, y después unos 5 GB más por editor adicional. El tamaño real depende del uso y de la complejidad de los archivos, no del número de cuentas. Nuestra recomendación editorial para un equipo de pocas personas: un VPS de 4 GB de RAM con un límite por servicio (sección de memoria más abajo), que deja margen para exportar archivos pesados; 2 GB bastan para una prueba. En red, abra el 80 y el 443 hacia el proxy inverso, nunca el 9001 ni el 8025 directamente. El cuerpo máximo de petición del Compose es de 367001600 bytes (350 MiB): la directiva client_max_body_size de su proxy debe acompañarlo. En el puesto de trabajo, la documentación recomienda la última versión estable de Chrome.
Despliegue en 8 pasos
Contrate un VPS de ServOrbit
Prevea 4 GB de RAM para uso en equipo y 2 GB para una prueba. Ubuntu 24.04 LTS es la plantilla por defecto. Deje al menos 50 GB de disco libre si importa archivos voluminosos.
Apunte un subdominio a su VPS
Cree un registro A para
design.your-domain.comhacia la IP del VPS. El aprovisionador de ServOrbit emite un certificado de Let's Encrypt. Un dominio con HTTPS es indispensable: Penpot emite cookies de sesiónsecurepor defecto, y la documentación original reservadisable-secure-session-cookiespara pruebas fuera de producción.Instale desde el marketplace
En la consola de ServOrbit: Marketplace, Colaboración, Penpot, Desplegar. El job de AWX arranca los contenedores, genera
PENPOT_SECRET_KEYy fijaPENPOT_PUBLIC_URIen su dominio. La interfaz responde enhttps://design.your-domain.comen unos minutos.Compruebe que todos los servicios funcionan
Conéctese por SSH y ejecute
docker compose lspara localizar el archivo Compose, y despuésdocker compose -p penpot -f docker-compose.yaml ps. Cada servicio debe estar enrunning, conpenpot-postgresypenpot-valkeyenhealthy. Los registros se leen condocker compose -p penpot -f docker-compose.yaml logs -f.Cree su cuenta
El registro está abierto por defecto. Abra
https://design.your-domain.comy pulse « Crear una cuenta »: en el Compose original la verificación por correo está desactivada (disable-email-verification), así que la cuenta queda activa de inmediato. Cree la suya enseguida, antes de que lo haga otra persona.Cierre los registros públicos
Añada el flag
disable-registrationaPENPOT_FLAGS(frontend y backend) y recree los contenedores. Las invitaciones siguen funcionando mientrasenable-login-with-passwordsiga activo. Para crear una cuenta sin invitación, ejecutedocker exec -ti penpot-penpot-backend-1 python3 manage.py create-profile: el script exige el flagenable-prepl-servery el nombre del contenedor puede variar, compruébelo condocker ps.Conecte un servidor SMTP real
Sin SMTP no sale ninguna invitación ni restablecimiento de contraseña. Consulte la sección siguiente para las variables.
Importe sus archivos de Figma
Penpot no abre directamente los archivos
.fig. La vía oficial pasa por el plugin de Figma « Penpot Exporter », que produce un archivo.zippara importar en Penpot. El procedimiento y sus límites se detallan más abajo.
Configuración posterior a la instalación: correo y almacenamiento de archivos
Para el correo, active enable-smtp en PENPOT_FLAGS e indique en el backend PENPOT_SMTP_DEFAULT_FROM, PENPOT_SMTP_DEFAULT_REPLY_TO, PENPOT_SMTP_HOST, PENPOT_SMTP_PORT (587 en el ejemplo original), PENPOT_SMTP_USERNAME, PENPOT_SMTP_PASSWORD y PENPOT_SMTP_TLS. El Compose original apunta por defecto a penpot-mailpit, que guarda los mensajes en memoria y los pierde al recrear el contenedor. En producción, retire también disable-email-verification, que la documentación desaconseja fuera de las pruebas. En cuanto a los archivos, las imágenes y clips SVG que suben los usuarios se guardan por defecto en el sistema de archivos, en el volumen penpot_assets montado en /opt/data/assets (PENPOT_OBJECTS_STORAGE_BACKEND: fs). Es posible un almacenamiento compatible con S3 con PENPOT_OBJECTS_STORAGE_BACKEND: s3, un bucket, un endpoint opcional y las variables AWS_ACCESS_KEY_ID y AWS_SECRET_ACCESS_KEY. Desde la versión 2.11.0, los antiguos nombres PENPOT_STORAGE_ASSETS_* se sustituyeron por PENPOT_OBJECTS_STORAGE_*: si reutiliza un Compose antiguo, renómbrelos.
Copia de seguridad y actualización
Una instancia de Penpot tiene dos estados que respaldar juntos: la base PostgreSQL y el volumen de archivos. La documentación original advierte de que no se puede copiar directamente la carpeta de datos de un volumen Docker y remite al procedimiento de copia de volúmenes de Docker. Nuestro enfoque: una exportación lógica de la base con docker exec penpot-penpot-postgres-1 pg_dump -U penpot penpot > penpot.sql, y luego un archivo comprimido del volumen de archivos mediante un contenedor temporal que lo monta en solo lectura. Localice los nombres de los volúmenes con docker volume ls. Haga ambas copias en el mismo momento, o la base podría referenciar archivos ausentes del archivo comprimido, y pruebe una restauración en otro VPS antes de necesitarla. Para actualizar, fije la versión con PENPOT_VERSION en lugar de seguir la última imagen, ejecute docker compose -p penpot -f docker-compose.yaml pull y después up -d, y avance en pasos pequeños: la documentación desaconseja saltar entre versiones lejanas. A 1 de noviembre de 2026, la última versión publicada es la 2.18.5. Si mantiene su propio Compose, la 2.18 añadió el servicio penpot-admin-console y la variable PENPOT_ADMIN_CONSOLE_URI en el frontend y el backend. Haga siempre una copia antes de actualizar.
Memoria: lo que recoge el hilo #3299 y cómo acotarla
La incidencia #3299 de penpot, abierta en junio de 2023, sigue abierta y recibió un mensaje en octubre de 2026. Reúne testimonios de alto consumo de RAM en instalaciones Docker: un usuario cuenta unos 20 GB ocupados tras tres o cuatro días en un servidor de 64 GB, otro más de 50 GB solicitados por una VM sin usuarios, otro 15 GB para un solo usuario con reinicio del backend cada 12 horas. Son informes individuales, no reproducidos: un miembro del equipo de Penpot responde en el hilo que tiene instalaciones Docker con mucho tráfico sin este síntoma y pide un archivo y trazas para diagnosticar. Por tanto no podemos prometer una cifra de consumo. Lo que sí podemos decir es cómo evitar que un servicio decida por sí solo: el backend es un proceso Java y, sin límite de contenedor, la máquina virtual de Java dimensiona su heap según la memoria que ve, es decir, la de todo el anfitrión. Un límite por servicio convierte una deriva silenciosa en un reinicio controlado.
Dimensionar la memoria: límite, vigilancia, reinicio programado
Un colaborador del hilo #3299 cuenta que añadió mem_limit: 12g a todos los servicios del Compose para mantener el consumo soportable. En un VPS de 4 GB, fije valores más bajos, por ejemplo mem_limit: 2g en penpot-backend y mem_limit: 1g en penpot-exporter, y deje el resto a PostgreSQL y al sistema. El script de arranque del backend añade JVM_OPTS y JAVA_OPTS a la línea de comandos de Java: puede pasar ahí -XX:MaxRAMPercentage=70, opción estándar de la JVM, pero la documentación de Penpot no describe ningún ajuste de JVM, así que pruébelo antes de producción. Vigile con docker stats --no-stream y, si el backend deriva pese al límite, programe un reinicio nocturno (docker compose -p penpot -f docker-compose.yaml restart penpot-backend): los colaboradores reconectan sus websockets. Valkey ya está limitado a 128 MB en el Compose original. Si se alcanza el límite con demasiada frecuencia, es la señal para elegir una oferta de VPS con más RAM, no para subir el límite a ciegas.
Importar sus archivos desde Figma
Al contrario de lo que a veces se lee, Penpot no importa un archivo .fig. El proyecto mantiene un plugin de Figma, « Penpot Exporter », que convierte un archivo de Figma en un .zip importable. En Figma, abra el archivo, luego Resources, Plugins, busque « Penpot Exporter » y lance la exportación. En Penpot, abra el menú de tres puntos de un proyecto o de los borradores, elija « Import Penpot files » y seleccione el .zip. Según el README del plugin, se trasladan las formas básicas, los vectores, los frames y secciones (boards en Penpot), los grupos y máscaras, los textos, rellenos, trazos, sombras, componentes e instancias, auto layouts, variantes y bibliotecas de colores y tipografías. No se trasladan los ajustes de prototipado. Los archivos muy voluminosos siguen siendo un punto difícil, porque la exportación recorre cada nodo bajo los límites de la API de Figma, y algunos renderizados pueden diferir ligeramente. Importe primero un archivo de prueba, compare componentes y fuentes, y después migre el resto. Las fuentes personalizadas se suben a Penpot.
Integrar Penpot en su flujo de trabajo con Git
Penpot no guarda sus diseños como archivos de texto en un repositorio: la fuente de verdad es la base PostgreSQL. Sin embargo, dos exportaciones encajan con Git. El archivo .penpot sirve de copia portátil de un archivo. La exportación SVG de un board produce texto legible que puede subir a Gitea, por ejemplo para los iconos e ilustraciones de un sistema de diseño. Una pull request muestra entonces el diff del SVG y su pipeline de CI puede detectar un cambio inesperado. Este enfoque sigue siendo una convención de equipo: supone volver a exportar tras cada cambio, algo que un script o una revisión de diseño pueden recordarle.
Penpot MCP: dirija sus diseños desde un asistente de IA
El Compose original incluye un servicio penpot-mcp, activado por el flag enable-mcp, y su proxy inverso debe retransmitir el websocket /mcp/ws además de /ws/notifications. Un cliente compatible con MCP puede entonces conectarse a su instancia. Reserve este acceso a cuentas de confianza y sírvalo por HTTPS. Pruebe primero con un archivo borrador y generalice si el resultado le convence.
Resolución de problemas: los errores realmente informados
- Banner « Something wrong has happened » o cookie
auth-tokenrechazada — informado en un servidor al que se accedía por HTTP desde la red local. Respuesta de un miembro del equipo de Penpot: las cookies sonsecurepor defecto, así que frontend y backend deben servirse por HTTPS. Sirva la instancia con un certificado válido y fijePENPOT_PUBLIC_URIen la URL exacta. - Error interno tras unos clics en el registro o el inicio de sesión — informado con
disable-secure-session-cookiesen un acceso HTTP público. Mismo remedio: HTTPS. El flag no es una solución de producción. WebSocket connection to 'wss://…/ws/notifications…' failed: Invalid frame header— informado justo después de iniciar sesión, con la interfaz bloqueada, detrás de Nginx. La respuesta dada en la comunidad es retransmitir/ws/notificationscon las cabecerasUpgradeyConnectionhacia el puerto 9001. El hilo no confirma que eso resolviera el caso del autor.net::ERR_CERT_AUTHORITY_INVALIDen los registros depenpot-exporter— la exportación falla. El exportador carga la aplicación mediantePENPOT_PUBLIC_URI: con un certificado autofirmado o no reconocido, no puede validar la conexión. Use un certificado de una autoridad reconocida.- Exportación a PDF que caduca sin mensaje claro — informado en una instalación manual donde el exportador recibía
PENPOT_PUBLIC_URI=http://localhost. El exportador debe poder alcanzar la URL pública de la aplicación, no una dirección local a su propio contenedor. - No se puede iniciar sesión y no hay pista — compruebe primero
docker compose -p penpot -f docker-compose.yaml ps, luego los registros del servicio afectado y la consola del navegador (F12), que muestra la versión exacta de Penpot y las peticiones con error.