Saltar al contenido
Autoalojado

Auto-hospeda Pluma con Docker

Ejecuta Pluma en tu propia infraestructura. Un contenedor, un fichero compose, cinco minutos de servidor limpio a app funcionando.

Linux · 2 vCPU · 4 GBDocker + Compose v2Licencia (solo planes de pago)
Inicio rápido

Inicio rápido (5 minutos)

1

Elige un directorio

sudo mkdir -p /opt/pluma && sudo chown $USER:$USER /opt/pluma
cd /opt/pluma
2

Crea el fichero compose

Guardar como docker-compose.yml.

services:
  pluma:
    # Pin a version tag (e.g. mertdalbudak/pluma:<version>) so updates happen
    # when you decide; `latest` follows every release.
    image: mertdalbudak/pluma:latest
    container_name: pluma
    restart: unless-stopped
    env_file: .env
    ports:
      - "4100:4100"
    volumes:
      - builder-data:/app/builder/data
      # Lets the Pro+ Publish flow drive `docker buildx`. WARNING: mounting
      # the Docker socket hands the container control over the Docker host
      # (root-equivalent). Remove this line unless you use Publish, and
      # never keep it on a shared host.
      - /var/run/docker.sock:/var/run/docker.sock
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:4100/health"]
      interval: 30s
      timeout: 5s
      retries: 5

volumes:
  builder-data:
3

Crea el fichero env

Guardar como .env. Solo importan cuatro valores — el resto se genera automáticamente en el primer arranque.

# Where Pluma is reachable (use https://… when fronted by TLS).
PUBLIC_URL=http://localhost:4100

# Paid tiers: paste your license key. Free tier: leave blank.
LICENSE_KEY=

# Database (optional) — unset uses a bundled SQLite file; point at your
# own PostgreSQL to back it up and scale it yourself.
# DATABASE_URL=postgresql://USER:PASS@host:5432/pluma

# Object storage (optional) — defaults to the local data volume; set these
# for S3-compatible storage (MinIO, R2, S3, B2, …).
# STORAGE_BACKEND=s3
# S3_BUCKET=pluma
# S3_ENDPOINT=https://your-s3-endpoint
# S3_REGION=eu-central-1
# S3_ACCESS_KEY=...
# S3_SECRET_KEY=...

# Email (optional) — only for the enterprise e-signature workflow. Any SMTP
# URL works; without it /sign-requests is disabled and everything else runs
# offline.
# SMTP_URL=smtp://user:[email protected]:587
# EMAIL_FROM=Pluma <[email protected]>
# [email protected]

# Document seal for signed PDFs. A self-signed seal is generated on first use
# and kept next to the data directory; point these at a certificate from an
# Adobe-trusted CA (or a qualified seal certificate) to make PDF readers show
# the seal as trusted. PLUMA_SEAL_TSA_URL adds an RFC 3161 timestamp.
# PLUMA_SEAL_CERT_FILE=/etc/pluma/seal.crt
# PLUMA_SEAL_KEY_FILE=/etc/pluma/seal.key
# PLUMA_SEAL_NAME=Your Company Document Seal
# PLUMA_SEAL_TSA_URL=http://timestamp.digicert.com
PUBLIC_URLDónde vive la instalación
LICENSE_KEYSolo planes de pago — déjalo vacío para Free
4

Arranca la pila

docker compose up -d
docker compose logs -f pluma
5

Verifica

Si ambos endpoints responden, está activo.

curl http://127.0.0.1:4100/health
# → {"ok":true,"service":"builder"}

Abre http://your-host:4100 y regístrate con el correo definido en

Integraciones opcionales

Conecta solo lo que necesites

La instalación básica funciona sin conexión: no requiere servicios externos. Las integraciones siguientes son opcionales, se configuran mediante .env y solo activan la función con la que están asociadas.

SMTP — flujo de firma electrónica

Solo necesario para el flujo de firma electrónica en instalaciones Enterprise. Sirve cualquier URL SMTP estándar:

# ── Transactional email (optional; needed for /sign-requests) ──
SMTP_URL=smtp://user:[email protected]:587
EMAIL_FROM=Pluma <[email protected]>
[email protected]

Marca — dale tu propia imagen

Tras el primer inicio de sesión, la página Ajustes → Marca del panel te permite sustituir «Pluma» por el nombre de tu producto, poner tu propio logotipo (cabecera + correo) y favicon, definir un color de acento y añadir un pie de página legal a cada correo transaccional. Los cambios se aplican al instante: sin reinicios ni malabares con variables de entorno. Solo en autoalojado; la marca del SaaS alojado es de Pluma.

Almacenamiento de objetos — comparte el estado entre nodos

De forma predeterminada, los PDF e imágenes subidos residen en el volumen builder-data. Apunta STORAGE_BACKEND a cualquier servicio compatible con S3 (MinIO, Hetzner, R2, B2, AWS) cuando quieras escalar horizontalmente, ejecutar varias réplicas del builder o sacar el volumen de datos del host de la aplicación.

STORAGE_BACKEND=s3
S3_BUCKET=pluma
S3_ENDPOINT=https://your-s3-endpoint
S3_REGION=eu-central-1
S3_ACCESS_KEY=...
S3_SECRET_KEY=...
Actualizar

Actualizar

docker compose pull
docker compose up -d

Las migraciones de la base de datos se ejecutan automáticamente al arrancar el builder, antes de que el servidor HTTP acepte tráfico. Sin paso manual.

Notas de operación

  • Fije la imagen. Sustituya `latest` en el archivo compose por una etiqueta de versión (`mertdalbudak/pluma:<versión>`) para que las actualizaciones ocurran cuando usted lo decida. Para volver atrás, ponga la etiqueta anterior y ejecute de nuevo los dos comandos de actualización; si la versión nueva cambió el esquema de la base de datos, restaure la copia de seguridad hecha antes de actualizar.
  • Socket de Docker. El montaje opcional del socket de Docker en el archivo compose da al contenedor el control del host de Docker, en la práctica root. Omítalo salvo que use el flujo Publish, y nunca en un host compartido.
  • Latido de licencia. Los planes de pago llaman al servicio de licencias una vez al día (POST /api/v1/licenses/heartbeat en el host de licencias integrado en la imagen) con el hash de la clave y la versión del software, nada más. Si el servicio no responde, los límites de pago siguen vigentes 14 días (PLUMA_LICENSE_GRACE_DAYS) y después bajan a Free hasta que un latido tenga éxito. Las instalaciones Free nunca llaman.

¿Necesitas una licencia?

El plan Free funciona sin licencia. Los planes Advanced y Pro necesitan una clave de licencia — compra una en nuestro sitio alojado, pégala en tu .env como LICENSE_KEY y vuelve a desplegar.