---
title: "Cómo Autoalojar Stirling PDF (Docker, Traefik, Dokploy)"
description: "Autoaloja Stirling PDF con Docker para unir, dividir, convertir y proteger PDFs de forma privada. Guía paso a paso con Traefik, Dokploy, API y configuración MCP."
date: 2025-07-30
categories: ["self-hosting"]
tags: ["self-hosted","docker","stirling-pdf"]
---

import Button from "@components/widgets/Button.astro";
import Notice from "@components/widgets/Notice.astro";
import ListCheck from "@components/widgets/ListCheck.astro";
import Accordion from "@components/widgets/Accordion.astro";

Los documentos PDF están en todas partes: contratos, facturas, informes, formularios escaneados. Manipularlos suele significar pagar por Acrobat Pro, subir archivos a alguna herramienta web de terceros o improvisar con utilidades de línea de comandos que funcionan a medias.

**Stirling PDF** es una aplicación web autoalojada que permite unir, dividir, convertir, comprimir, aplicar OCR, firmar y docenas de operaciones más sobre PDF, todo ejecutándose en tu propia infraestructura. El proyecto alcanzó la V2 a finales de 2025 con una reescritura completa del frontend en React, deshacer/rehacer con estado, aplicaciones de escritorio, un servidor MCP integrado para agentes de IA y Automate/Pipelines para encadenar operaciones. Cuenta con más de 91.000 estrellas en GitHub y más de 30 millones de descargas. El nivel autoalojado gratuito admite hasta 5 usuarios sin restricciones de funciones en las operaciones.

Esta guía recorre tres rutas de despliegue: Docker Compose independiente, Traefik con Dockge y Dokploy. Cada una se puede copiar y pegar e incluye pasos de verificación.

> Para más aplicaciones autoalojadas útiles, consulta nuestra guía sobre [contenedores Docker para servidores domésticos](https://www.bitdoze.com/es/contenedores-docker-servidor-casa/).

## ¿Qué es Stirling PDF?

**Stirling PDF** es una plataforma PDF autoalojada de núcleo abierto (open-core). El nivel gratuito te da acceso completo a más de 60 herramientas, sin créditos, sin marcas de agua y sin límites artificiales en el número de operaciones. Se ejecuta como un único contenedor Docker con un backend de procesamiento en Java, frontend en React e integraciones opcionales para Tesseract OCR, LibreOffice y PDFium.

### Capacidades clave de Stirling PDF

<ListCheck>

- Gestión de documentos: une, divide, rota, reorganiza y compara páginas PDF
- Conversión de formatos: PDF a/desde imágenes, Word, Excel, HTML, Markdown y más
- Operaciones de seguridad: añadir/eliminar contraseñas, firmas digitales, cifrado, tachado de datos
- Compresión y optimización: reduce el tamaño de los archivos manteniendo la calidad
- Integración OCR: extrae texto de documentos escaneados con Tesseract
- Gestión de metadatos: limpia, edita o elimina los metadatos del documento
- Procesamiento por lotes: maneja varios documentos simultáneamente desde la interfaz Automate/Pipeline
- Acceso API: endpoints RESTful para flujos de automatización y scripting
- Servidor MCP: expone las operaciones PDF como herramientas para agentes de IA (Claude Desktop, etc.)
- Compartición de archivos y firma en grupo: comparte documentos para firma colaborativa (alfa desde v2.9.0)
- Aplicaciones de escritorio: clientes nativos de Windows, macOS y Linux para procesamiento local

</ListCheck>

### Cómo funciona Stirling PDF

| Componente | Función | Detalles |
|-----------|----------|---------|
| Interfaz web | GUI en el navegador | Frontend React, más de 38 idiomas, modo oscuro |
| Motor de procesamiento | Núcleo PDF basado en Java | JDK 25, JPDFium para unir/dividir con bajo consumo de memoria |
| Motor OCR | Integración con Tesseract | Paquetes de idioma vía directorio tessdata |
| Conversiones de Office | LibreOffice | DOCX, XLSX, PPTX a PDF y viceversa |
| Capa API | Endpoints RESTful | Swagger UI en `/swagger-ui.html` |
| Servidor MCP | Integración con agentes de IA | `POST /mcp`, desactivado por defecto |
| Almacenamiento | Temporal + persistente | BD H2, settings.yml, backend S3 opcional |

Stirling PDF es un proyecto de código abierto. Consulta la documentación y contribuye en el [repositorio de GitHub](https://github.com/Stirling-Tools/Stirling-PDF) y el [sitio web del proyecto](https://stirling.com). La documentación completa está en [docs.stirlingpdf.com](https://docs.stirlingpdf.com/).

## Licencias: gratuita, servidor y empresarial

Stirling PDF pasó a un modelo open-core. El desglose para quienes se autoalojan:

<Notice type="info" title="Niveles de licencia">

**Gratuita (autoalojada):** Hasta 5 usuarios, las más de 60 operaciones, sin créditos ni funciones bloqueadas. Esto es lo que obtienes por defecto al desplegar con Docker. Realmente gratuita e ilimitada en operaciones.

**Server (99 $/mes o 999 $/año):** 100 usuarios (ampliables en bloques de 100), SSO OAuth2, PostgreSQL externo, tickets de soporte, integración con Google Drive.

**Enterprise (precio personalizado):** SAML2, activación de certificados en entornos aislados (air-gapped), métricas Prometheus, registros de auditoría, SLAs.

Activación: Settings → Plan (Stripe integrado en la app) o `settings.yml` → `premium.key`.

</Notice>

Para un operador en solitario o un equipo pequeño, el nivel gratuito es todo lo que necesitas. Los niveles de pago importan cuando necesitas SSO o soporte de base de datos externa.

## Requisitos previos

Antes de desplegar Stirling PDF, asegúrate de contar con lo siguiente:

<Notice type="info" title="Requisitos de recursos">

**Mínimo:** 2 núcleos de CPU, 2 GB de RAM, 10 GB de disco
**Recomendado:** 4+ núcleos de CPU, 4 GB+ de RAM, almacenamiento SSD
**Tamaño de la imagen:** La etiqueta `latest` ocupa aproximadamente 1 GB comprimida. Tenlo en cuenta para la descarga.

Las conversiones pesadas (LibreOffice) y las operaciones OCR necesitan más RAM. La variante `latest-ultra-lite` está disponible para Raspberry Pi y VPS de gama baja, pero carece de compresión, OCR y conversiones de ofimática.

</Notice>

**Variantes de imagen:**

| Variante | Etiqueta | Ideal para | Funciones ausentes |
|---------|-----|----------|-----------------|
| Estándar | `:latest` | La mayoría de despliegues | Ninguna |
| Fat | `:latest-fat` | Conversiones de alta fidelidad, fuentes extra | Mayor tamaño de imagen |
| Ultra Lite | `:latest-ultra-lite` | Raspberry Pi, VPS de gama baja | Sin compresión, OCR, conversiones de ofimática, reparación, PDF/A |

**Requisitos de infraestructura:**

- **Servidor**: Un VPS o servidor dedicado. [Hetzner VPS](https://go.bitdoze.com/hetzner) o [Hostinger VPS](https://go.bitdoze.com/hostinger-vps) funcionan bien para esto. Para instalación local, consulta [mini PCs para servidores domésticos](https://www.bitdoze.com/best-mini-pc-home-server/).
- **Docker Engine**: Última versión estable con Docker Compose v2
- **Proxy inverso** (para HTTPS): Configura un [proxy inverso Traefik en Docker](https://www.bitdoze.com/traefik-proxy-docker/) o usa Caddy. Para certificados SSL, sigue la [guía de certificado wildcard de Traefik](https://www.bitdoze.com/traefik-wildcard-certificate/).
- **Gestión de contenedores** (opcional): [Dockge](https://www.bitdoze.com/es/instalar-dockge/) para gestionar stacks o [Dokploy](https://www.bitdoze.com/dokploy-install/) para una plataforma completa
- **Dominio**: Un subdominio apuntando a tu servidor (p. ej., `pdf.yourdomain.com`)
- **Firewall**: Puerto 8080 para instalación independiente, o 443 vía proxy inverso

_Los precios de los VPS subieron en general en 2026 — si estás reconsiderando un servidor alquilado, consulta [qué cambió y cuándo gana un mini PC](/es/subidas-precios-vps/)._

## Opción de instalación 1: Docker y Docker Compose (independiente)

Esta es la ruta más sencilla. Un único contenedor, sin proxy inverso, ideal para acceso en red local o pruebas antes de añadir HTTPS.

### Paso 1: Crear la estructura del proyecto

```bash
mkdir -p ~/stirling-pdf && cd ~/stirling-pdf
```

### Paso 2: Configurar Docker Compose

Crea un archivo `docker-compose.yml`:

```yaml
services:
  stirling-pdf:
    image: docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest
    container_name: stirling-pdf
    ports:
      - "8080:8080"
    volumes:
      - ./stirling-data/tessdata:/usr/share/tessdata    # OCR language files
      - ./stirling-data/configs:/configs                # settings.yml + H2 DB (back this up!)
      - ./stirling-data/logs:/logs
      - ./stirling-data/customFiles:/customFiles
      - ./stirling-data/pipeline:/pipeline              # Automate / folder-scan configs
    environment:
      - SECURITY_ENABLELOGIN=true                       # login is ON by default
      - SECURITY_INITIALLOGIN_USERNAME=admin            # optional, first boot only
      - SECURITY_INITIALLOGIN_PASSWORD=ChangeMeNow123!  # optional, first boot only
      - SYSTEM_DEFAULTLOCALE=en-US                      # UI language (hyphenated)
      - SYSTEM_GOOGLEVISIBILITY=false                   # block search engine indexing
      - SYSTEM_MAXFILESIZE=500                          # per-file MB (1-999)
      - SPRING_SERVLET_MULTIPART_MAX_FILE_SIZE=2000MB
      - SPRING_SERVLET_MULTIPART_MAX_REQUEST_SIZE=2000MB
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/api/v1/info/status"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s
```

<Notice type="warning" title="Credenciales de inicio de sesión por defecto">

La V2 incluye el inicio de sesión activado por defecto. La cuenta por defecto es `admin` / `stirling`. Cambia la contraseña inmediatamente después del primer inicio de sesión. Algunas compilaciones fuerzan un cambio de contraseña en el primer inicio. Puedes predefinir las credenciales iniciales con `SECURITY_INITIALLOGIN_USERNAME` y `SECURITY_INITIALLOGIN_PASSWORD` (solo se respetan en el primer arranque).

</Notice>

Para acceso anónimo (sin inicio de sesión), establece `SECURITY_ENABLELOGIN=false` y `DISABLE_ADDITIONAL_FEATURES=false`.

### Paso 3: Inicializar los directorios y desplegar

```bash
mkdir -p stirling-data/{tessdata,configs,logs,customFiles,pipeline}
docker compose up -d
```

Observa los registros para confirmar el arranque:

```bash
docker compose logs -f
```

Busca `Started StirlingPDF` en la salida. Si ves advertencias de `unknown configuration key`, son variables de entorno obsoletas. Inofensivas pero ruidosas. Elimínalas de tu archivo compose.

### Paso 4: Configurar el soporte OCR (opcional)

Descarga los paquetes de idioma de Tesseract para OCR:

```bash
# English is required. Do not delete eng.traineddata
wget -P stirling-data/tessdata/ https://github.com/tesseract-ocr/tessdata/raw/main/eng.traineddata
wget -P stirling-data/tessdata/ https://github.com/tesseract-ocr/tessdata/raw/main/fra.traineddata
wget -P stirling-data/tessdata/ https://github.com/tesseract-ocr/tessdata/raw/main/deu.traineddata
wget -P stirling-data/tessdata/ https://github.com/tesseract-ocr/tessdata/raw/main/spa.traineddata
wget -P stirling-data/tessdata/ https://github.com/tesseract-ocr/tessdata/raw/main/chi_sim.traineddata
```

Reinicia el contenedor después de añadir los archivos de idioma:

```bash
docker compose restart stirling-pdf
```

### Paso 5: Verificar la instalación

- **Interfaz web**: Navega a `http://localhost:8080`
- **Comprobación de salud**: `curl http://localhost:8080/api/v1/info/status`
- **Documentación API**: Visita `http://localhost:8080/swagger-ui.html`

<Notice type="success" title="Instalación completada">

Tu instancia de Stirling PDF está en funcionamiento. Inicia sesión con tus credenciales (o `admin`/`stirling` si no las predefiniste) y cambia la contraseña inmediatamente.

</Notice>

**Fallo común:** Página de inicio de sesión en blanco tras el arranque. Revisa los registros del contenedor con `docker compose logs stirling-pdf` y asegúrate de que los directorios de volúmenes tengan los permisos correctos (`chmod -R 755 ./stirling-data`).

## Opción de instalación 2: Integración con Traefik y Dockge

Esta configuración coloca Stirling PDF detrás de Traefik con HTTPS automático vía Let's Encrypt. Dockge proporciona una interfaz web para gestionar el stack de compose.

<Notice type="info" title="Requisitos previos">

Esta configuración requiere una instalación funcional de Traefik y Dockge. Sigue la [guía de certificado wildcard de Traefik](https://www.bitdoze.com/traefik-wildcard-certificate/) para la configuración SSL.

</Notice>

### Paso 1: Verificar la configuración de red

```bash
# Check for existing Traefik network
docker network ls | grep traefik-net

# Create if it doesn't exist
docker network create traefik-net
```

### Paso 2: Configuración de Docker Compose

Crea un `docker-compose.yml` con etiquetas de Traefik:

```yaml
services:
  stirling-pdf:
    image: docker.stirlingpdf.com/stirlingtools/stirling-pdf:latest
    container_name: stirling-pdf
    volumes:
      - ./stirling-data/tessdata:/usr/share/tessdata
      - ./stirling-data/configs:/configs
      - ./stirling-data/logs:/logs
      - ./stirling-data/customFiles:/customFiles
      - ./stirling-data/pipeline:/pipeline
    environment:
      - SECURITY_ENABLELOGIN=true
      - SECURITY_INITIALLOGIN_USERNAME=admin
      - SECURITY_INITIALLOGIN_PASSWORD=ChangeMeNow123!
      - SYSTEM_DEFAULTLOCALE=en-US
      - SYSTEM_GOOGLEVISIBILITY=false
      - SYSTEM_MAXFILESIZE=500
      - SYSTEM_ROOTURIPATH=/
      - SPRING_SERVLET_MULTIPART_MAX_FILE_SIZE=2000MB
      - SPRING_SERVLET_MULTIPART_MAX_REQUEST_SIZE=2000MB
    networks:
      - traefik-net
    restart: unless-stopped
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.stirling-pdf.rule=Host(`pdf.yourdomain.com`)"
      - "traefik.http.routers.stirling-pdf.entrypoints=https"
      - "traefik.http.routers.stirling-pdf.tls=true"
      - "traefik.http.routers.stirling-pdf.tls.certresolver=letsencrypt"
      - "traefik.http.services.stirling-pdf.loadbalancer.server.port=8080"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/api/v1/info/status"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s

networks:
  traefik-net:
    external: true
```

Nota: La personalización de la app (nombre, descripción, logo) ahora se configura dentro de la aplicación en Settings → UI, no mediante variables de entorno. Las antiguas variables `UI_APPNAME` y `UI_HOMEDESCRIPTION` se eliminaron en la V2.

### Paso 3: Desplegar con Dockge

1. Accede a tu panel de Dockge (normalmente `https://dockge.yourdomain.com`)
2. Haz clic en "New Stack" y asígnale el nombre `stirling-pdf`
3. Pega la configuración de Docker Compose anterior
4. Actualiza `pdf.yourdomain.com` en las etiquetas de Traefik con tu dominio real
5. Haz clic en deploy y monitoriza los registros

### Paso 4: Configuración de DNS

Apunta tu subdominio al servidor:

| Tipo de registro | Nombre | Valor | TTL |
|-------------|------|-------|-----|
| A | pdf | ip-de-tu-servidor | 300 |

O usa un CNAME si tu dominio ya resuelve:

| Tipo de registro | Nombre | Valor | TTL |
|-------------|------|-------|-----|
| CNAME | pdf | yourdomain.com | 300 |

<Notice type="warning" title="Propagación de DNS">

Los cambios de DNS pueden tardar entre 5 y 15 minutos en propagarse. Espera antes de verificar el acceso HTTPS.

</Notice>

### Paso 5: Verificar el acceso HTTPS

Una vez propagado el DNS:

- **HTTPS**: Navega a `https://pdf.yourdomain.com`
- **Certificado SSL**: Comprueba que el certificado de Let's Encrypt sea válido (haz clic en el icono del candado en tu navegador)
- **Documentación API**: Visita `https://pdf.yourdomain.com/swagger-ui.html`

## Opción de instalación 3: Despliegue con Dokploy

Dokploy proporciona una interfaz gráfica con gestión automatizada de certificados SSL. Funciona bien si prefieres hacer clic en lugar de escribir.

### Paso 1: Configuración de la plataforma Dokploy

Si Dokploy aún no está instalado, sigue la guía de [instalación y configuración de Dokploy](https://www.bitdoze.com/dokploy-install/).

### Paso 2: Crear el proyecto Stirling PDF

1. Accede a tu panel de Dokploy
2. Haz clic en "New Project" y asígnale el nombre `stirling-pdf`
3. Selecciona **"Compose"** como tipo de aplicación. No uses la plantilla integrada de Stirling PDF, que puede estar fijada a una versión antigua de la V1

![Formulario de creación de servicio de Dokploy mostrando la selección del tipo de aplicación compose](@assets/images/25/07/dokploy-createservice.png)

### Paso 3: Configuración de variables de entorno

Establece estas variables de entorno en Dokploy:

| Variable | Valor | Descripción |
|----------|-------|-------------|
| `SECURITY_ENABLELOGIN` | `true` | Activa el inicio de sesión (por defecto en V2) |
| `SECURITY_INITIALLOGIN_USERNAME` | `admin` | Nombre de usuario admin inicial (solo primer arranque) |
| `SECURITY_INITIALLOGIN_PASSWORD` | `ChangeMeNow123!` | Contraseña inicial (solo primer arranque) |
| `SYSTEM_DEFAULTLOCALE` | `en-US` | Idioma de la interfaz |
| `SYSTEM_GOOGLEVISIBILITY` | `false` | Bloquea la indexación en buscadores |
| `SYSTEM_MAXFILESIZE` | `500` | Tamaño máximo de archivo en MB |

Usa esto en la configuración compose de Dokploy:

```yaml
environment:
  - SECURITY_ENABLELOGIN=${SECURITY_ENABLELOGIN}
  - SECURITY_INITIALLOGIN_USERNAME=${SECURITY_INITIALLOGIN_USERNAME}
  - SECURITY_INITIALLOGIN_PASSWORD=${SECURITY_INITIALLOGIN_PASSWORD}
  - SYSTEM_DEFAULTLOCALE=${SYSTEM_DEFAULTLOCALE}
  - SYSTEM_GOOGLEVISIBILITY=${SYSTEM_GOOGLEVISIBILITY}
  - SYSTEM_MAXFILESIZE=${SYSTEM_MAXFILESIZE}
```

### Paso 4: Configuración de dominio y SSL

1. Navega a la sección "Domains" de tu proyecto Dokploy
2. Añade tu dominio: `pdf.yourdomain.com`
3. Activa la generación de certificados SSL/TLS
4. Activa la renovación automática de certificados
5. Configura la redirección de HTTP a HTTPS

![Panel de configuración de dominio de Dokploy con el interruptor SSL activado](@assets/images/25/07/dokploy-domain.png)

### Paso 5: Desplegar y monitorizar

1. Haz clic en el botón "Deploy" en Dokploy
2. Monitoriza los registros de despliegue en busca de errores
3. Verifica que el indicador de salud muestre verde
4. Accede a tu instancia y prueba una operación PDF

![Panel de despliegue de Dokploy mostrando los registros de compilación y el estado](@assets/images/25/07/dokploy-deploy.png)

<Button text="Desplegar con Dokploy" size="lg" color="green" variant="solid" icon="arrow-right" iconPosition="right" />

## Actualización de V1 a V2

Si ejecutas una instalación antigua de V1 (0.4x), esto es lo que debes saber antes de actualizar:

<Notice type="warning" title="Migración de V1 a V2">

**Haz primero una copia de seguridad.** Detén el contenedor y comprime con tar tu directorio `configs/`. Contiene el archivo de la base de datos H2.

```bash
docker compose stop stirling-pdf
tar -czf stirling-v1-backup-$(date +%Y%m%d).tar.gz ./stirling-data/configs
```

**Qué cambia:**
- Los ajustes migran automáticamente. El esquema de la BD H2 se actualiza en el primer arranque
- Los usuarios deben volver a iniciar sesión una vez (cambió el formato JWT)
- Las variables de entorno obsoletas (`DOCKER_ENABLE_SECURITY`, `LANGS`, `UI_APPNAME`, `UI_HOMEDESCRIPTION`, `INSTALL_BOOK_AND_ADVANCED_HTML_OPS`) generan advertencias de `unknown configuration key`. Inofensivas pero ruidosas. Elimínalas.
- Las personalizaciones de plantillas Thymeleaf en `customFiles/templates/` ya no funcionan (reescritura en React). Las sustituciones estáticas en `customFiles/static/` sí siguen funcionando.
- El registro de imágenes por defecto cambió a `docker.stirlingpdf.com/stirlingtools/stirling-pdf`

Actualiza la etiqueta de la imagen y el archivo compose, luego ejecuta `docker compose up -d`. Revisa los registros en busca de mensajes de migración.

</Notice>

## Autenticación y gestión de usuarios

La V2 tiene el inicio de sesión activado por defecto.

**Credenciales por defecto:** `admin` / `stirling`. Cámbialas inmediatamente tras el primer inicio de sesión.

**Predefinir credenciales iniciales** (solo primer arranque, mediante variables de entorno):

```yaml
environment:
  - SECURITY_INITIALLOGIN_USERNAME=myadmin
  - SECURITY_INITIALLOGIN_PASSWORD=YourSecurePassword123!
```

Solo se respetan en el primer arranque. Después, gestiona los usuarios desde la interfaz de administración.

**Roles:** Los usuarios administradores pueden gestionar todos los ajustes y usuarios. Los usuarios normales obtienen acceso a las operaciones PDF según la configuración.

**Claves API:** Cada usuario puede generar una clave API personal desde Account → Settings. Para automatización, define una clave API global:

```yaml
environment:
  - SECURITY_CUSTOMGLOBALAPIKEY=your-long-random-key-here
```

**Bloqueo de inicio de sesión:** Por defecto, las cuentas se bloquean tras 5 intentos fallidos. Configúralo con:

```yaml
environment:
  - SECURITY_LOGINATTEMPTCOUNT=5       # set -1 to disable lockout
  - SECURITY_LOGINRESETTIMEMINUTES=120  # lockout duration
```

**SSO:** OAuth2 está disponible en el nivel Server (99 $/mes). SAML2 requiere Enterprise. Para un operador en solitario en el nivel gratuito, quédate con cuentas locales.

**Modo anónimo** (sin inicio de sesión en absoluto):

```yaml
environment:
  - SECURITY_ENABLELOGIN=false
  - DISABLE_ADDITIONAL_FEATURES=false
```

Para despliegues en producción, lee nuestra guía sobre [gestión de secretos en Docker Compose](https://www.bitdoze.com/docker-compose-secrets/) para evitar poner contraseñas en texto plano.

## Integración API y automatización

Stirling PDF expone una API REST. Con el inicio de sesión activado, todas las llamadas a la API requieren autenticación.

### Autenticación de la API

Obtén tu clave API desde Account → Settings en la interfaz web, o define una clave global con `SECURITY_CUSTOMGLOBALAPIKEY`. Pásala como cabecera:

```
X-API-KEY: your-api-key
```

La documentación de la API está disponible en `/swagger-ui.html` (también accesible desde Settings → API Documentation). El registro Scalar en línea está en [registry.scalar.com/@stirlingpdf](https://registry.scalar.com/@stirlingpdf).

### Ejemplo: PDF a imágenes

```bash
curl -X POST "https://pdf.yourdomain.com/api/v1/convert/pdf-to-img" \
  -H "X-API-KEY: your-api-key" \
  -H "Content-Type: multipart/form-data" \
  -F "fileInput=@document.pdf" \
  -F "imageFormat=PNG" \
  -F "singleOrMultiple=multiple"
```

### Ejemplo: Pipeline (OCR + compresión en una llamada)

El sistema Pipeline/Automate permite encadenar varias operaciones en una única llamada a la API:

```bash
curl -X POST "https://pdf.yourdomain.com/api/v1/pipeline/handleData" \
  -H "X-API-KEY: your-api-key" \
  -F "fileInput=@scan.pdf" \
  -F 'json={"name":"OCR-compress","pipeline":[
        {"operation":"/api/v1/misc/ocr-pdf","parameters":{"languages":["eng"],"ocrType":"skip-text"}},
        {"operation":"/api/v1/misc/compress-pdf","parameters":{"optimizeLevel":2}}]}' \
  --output result.pdf
```

<Notice type="warning" title="Gestión de errores del pipeline">

Los errores del pipeline actualmente se colapsan en un HTTP 200 con cuerpo vacío. Verifica siempre que la salida empiece con `%PDF-` (o `PK` para formatos basados en ZIP). Si obtienes un archivo vacío, revisa los registros del contenedor para encontrar el error real.

</Notice>

Para procesamiento asíncrono, añade `?async=true` a la URL del pipeline y consulta `GET /api/v1/general/job/{id}` para el estado.

### Integración con flujos de n8n

Conecta Stirling PDF con [n8n autoalojado](https://www.bitdoze.com/es/automatizacion-n8n-autoalojado/) para flujos de procesamiento de documentos:

1. **Disparador**: Recepción de un adjunto por correo o archivo depositado en una carpeta vigilada
2. **Proceso**: Una única llamada al pipeline para OCR + compresión + conversión
3. **Almacenar**: Guarda el resultado en tu sistema de gestión documental

Una única llamada al pipeline reemplaza lo que antes requería más de 5 nodos de API encadenados. Para uniones simples sin interfaz, también puedes usar [pdfunite desde la línea de comandos de Linux](https://www.bitdoze.com/pdf-merge-linux-cmd/).

## Servidor MCP para agentes de IA

Stirling PDF incluye un servidor MCP (Model Context Protocol) integrado que expone las operaciones PDF como herramientas para agentes de IA. Es útil si estás construyendo flujos de trabajo de IA que necesitan procesar documentos.

<Notice type="info" title="¿Qué es MCP?">

MCP es un protocolo que permite a asistentes de IA como Claude usar herramientas externas. El servidor MCP de Stirling PDF permite a un agente de IA unir, dividir, convertir, comprimir y proteger PDFs sin escribir código de API. Consulta nuestra [introducción al Model Context Protocol](https://www.bitdoze.com/es/introduccion-mcp-principiantes/) para más contexto.

</Notice>

**Activa el servidor MCP** en tu archivo compose:

```yaml
environment:
  - MCP_ENABLED=true
  - MCP_AUTH_MODE=apikey
  - MCP_ALLOWEDOPERATIONS=stirling_pages,stirling_convert,stirling_misc,stirling_security
```

Grupos de herramientas disponibles: `stirling_pages` (unir/dividir/rotar), `stirling_convert` (conversiones de formato), `stirling_misc` (comprimir/OCR/reparar), `stirling_security` (contraseñas/firmas), `stirling_upload`, `stirling_download`.

**Configuración de Claude Desktop:** Añade esto a tu `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "stirling-pdf": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://pdf.yourdomain.com/mcp",
        "--header",
        "X-API-KEY: your-api-key"
      ]
    }
  }
}
```

Los límites de petición y respuesta son de 10 MB por defecto. El servidor MCP no incluye un motor de IA. Expone las operaciones PDF como herramientas que los agentes de IA externos pueden invocar.

## Buenas prácticas de seguridad y protección de datos

Stirling PDF ha tenido problemas de seguridad reales. Esto es lo que necesitas saber.

### Protección SSRF

La conversión de URL a PDF está desactivada por defecto (`system.enableUrlToPDF: false`) por el riesgo de SSRF. Si la activas, la protección SSRF está activada por defecto en nivel MEDIUM (bloquea RFC1918, localhost, link-local y endpoints de metadatos de la nube). Establécela en MAX para el modo de solo lista de permitidos:

```yaml
# In settings.yml
system:
  enableUrlToPDF: true
  urlToPdfProtection: MAX
  allowedDomains:
    - "trusted-domain.com"
```

### Avisos de seguridad

Stirling PDF ha tenido varios avisos de seguridad. Los principales:

| Fecha | Severidad | Problema | CVE | Corregido en |
|------|----------|-------|-----|----------|
| ago 2025 | Alta | SSRF a través de endpoints de conversión | CVE-2025-55150, CVE-2025-55151 | V1 v1.1.0 |
| mar 2026 | Alta | Path traversal en markdown-to-PDF | GHSA-wccq-mg6x-2w22 | V2 |
| mar 2026 | Moderada | XSS almacenado vía exportación EML | GHSA-xmhg-fv84-jgfc | V2 |
| jul 2026 | Alta | XSS almacenado en Info Summary | GHSA-qc47-qgh9-xj63 | V2.14.2 |
| jul 2026 | Alta | Divulgación de claves API vía Pipeline | GHSA-3xxh-mm3g-c9w5 | V2.14.2 |

<Notice type="warning" title="Ejecuta siempre la última versión">

Las correcciones de seguridad solo se publican en la última versión. No hay backports a versiones anteriores. Fija una etiqueta específica en producción (p. ej., `v2.14.3`), pero actualiza rápidamente cuando salgan versiones de seguridad. Las versiones se publican de 2 a 4 veces por semana.

</Notice>

### Seguridad de red y acceso

- **Bloquea la indexación en buscadores**: `SYSTEM_GOOGLEVISIBILITY=false` (ya configurado en los ejemplos de compose anteriores)
- **Desactiva endpoints sin usar**: Configura `endpoints.toRemove` en `settings.yml` para deshabilitar endpoints de la API que no utilices
- **Solo HTTPS**: Ejecuta siempre detrás de un proxy inverso con TLS. Nunca expongas el puerto 8080 directamente a internet
- **Limitación de tasa**: Bloqueo por intentos de inicio de sesión más [integración con fail2ban](https://docs.stirlingpdf.com/Configuration/Security/Fail2Ban/) para protección contra fuerza bruta

## Almacenamiento y copias de seguridad

### Qué respaldar

Los datos críticos residen en estas ubicaciones (todas dentro de tus volúmenes montados):

| Ruta | Contenido | Prioridad |
|------|----------|----------|
| `configs/stirling-pdf-DB-*.mv.db` | Base de datos H2 (usuarios, ajustes, historial) | Crítica |
| `configs/settings.yml` | Configuración de la aplicación | Crítica |
| `customFiles/` | Plantillas personalizadas y sustituciones estáticas | Alta |
| `tessdata/` | Paquetes de idioma OCR | Media (redescargable) |
| `pipeline/` | Configuraciones de flujos Automate | Media |

### Procedimiento de copia de seguridad

```bash
# Stop the container for a consistent snapshot
docker compose stop stirling-pdf

# Create a compressed backup
tar -czf stirling-backup-$(date +%Y%m%d-%H%M%S).tar.gz \
  -C ./stirling-data configs customFiles tessdata pipeline

# Restart
docker compose start stirling-pdf
```

### Procedimiento de restauración

```bash
# Stop the container
docker compose stop stirling-pdf

# Extract backup (overwrites current data)
tar -xzf stirling-backup-YYYYMMDD-HHMMSS.tar.gz -C ./stirling-data

# Verify critical files exist
ls -la ./stirling-data/configs/stirling-pdf-DB-*.mv.db
ls -la ./stirling-data/configs/settings.yml

# Restart
docker compose start stirling-pdf
```

### Almacenamiento S3 (opcional)

La V2.12+ admite almacenamiento compatible con S3 para subidas y artefactos. Es útil para configuraciones multiservidor o cuando quieres almacenamiento duradero separado del host del contenedor. Se configura en `settings.yml` en la sección de almacenamiento. Los niveles Server y Enterprise también admiten PostgreSQL externo en lugar de la base de datos H2 embebida.

## Rendimiento y gestión de recursos

### Guía de dimensionamiento

| Especificaciones del servidor | Tamaño máx. de archivo | Caso de uso |
|-------------|--------------|----------|
| 2 CPU / 2-4GB RAM | 200-500 MB | Uso personal, documentos ocasionales |
| 4 CPU / 8GB RAM | 1000 MB | Equipo pequeño, procesamiento habitual |
| 8+ CPU / 16GB+ RAM | 2000 MB | Procesamiento pesado por lotes, escaneos grandes |

La V2.12.0 introdujo JPDFium para las operaciones de unir y dividir, usando hasta un 99 % menos de memoria que el motor anterior. La V2.14.3 corrigió fallos al procesar PDFs de más de 2 GB.

### Límites de recursos de Docker

Establece límites estrictos para evitar que un proceso desbocado tumbe tu servidor:

```yaml
services:
  stirling-pdf:
    # ... other configuration
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 4G
        reservations:
          cpus: '1.0'
          memory: 2G
```

Para ajustar la memoria, define `JAVA_TOOL_OPTIONS=-Xmx2g` para limitar el heap de la JVM.

### Monitorización y comprobaciones de salud

El endpoint de salud `/api/v1/info/status` siempre es accesible sin autenticación. Úsalo con Uptime Kuma, Beszel o cualquier herramienta de monitorización que admita comprobaciones de salud HTTP.

Las estadísticas de uso están disponibles en `/api/v1/info/requests/all` (peticiones totales) y `/api/v1/info/requests/unique` (peticiones únicas).

## Solución de problemas comunes

<Accordion label="Página de inicio de sesión en blanco tras una instalación nueva" group="faq" expanded="true">

Normalmente significa que el contenedor arrancó pero el frontend no pudo inicializarse. Comprueba:

1. Registros del contenedor: `docker compose logs stirling-pdf`
2. Permisos de volúmenes: `chmod -R 755 ./stirling-data`
3. Memoria suficiente: el contenedor necesita al menos 2 GB. Compruébalo con `docker stats`

</Accordion>

<Accordion label="Advertencias de unknown configuration key al arrancar" group="faq">

Son variables de entorno obsoletas de la V1. Las más habituales:
- `DOCKER_ENABLE_SECURITY` — eliminada en V2 (la autenticación está integrada)
- `LANGS` — reemplazada por `SYSTEM_DEFAULTLOCALE`
- `UI_APPNAME` / `UI_HOMEDESCRIPTION` — ahora se configuran dentro de la app (Settings → UI)
- `INSTALL_BOOK_AND_ADVANCED_HTML_OPS` — la imagen `latest` ya incluye LibreOffice

Elimínalas de tu archivo compose. Las advertencias son inofensivas pero ensucian los registros.

</Accordion>

<Accordion label="Sesiones de usuarios cerradas tras actualizar" group="faq">

La V2 cambió el formato del token JWT. Todos los usuarios deben volver a iniciar sesión una vez tras actualizar desde V1. Es un comportamiento esperado, no un error.

</Accordion>

<Accordion label="Las plantillas personalizadas no se cargan" group="faq">

La V2 reemplazó el motor de plantillas Thymeleaf por React. Las plantillas personalizadas en `customFiles/templates/` ya no funcionan. Las sustituciones de archivos estáticos en `customFiles/static/` sí siguen funcionando. Consulta la [documentación de migración](https://docs.stirlingpdf.com/Migration/Overview/) para más detalles.

</Accordion>

<Accordion label="El pipeline devuelve una respuesta vacía" group="faq">

Los errores del pipeline se colapsan en un HTTP 200 con cuerpo vacío. Comprueba que:
1. Tu salida empiece con `%PDF-` (o `PK` para formatos ZIP)
2. La clave API tenga permisos suficientes
3. El archivo de entrada no esté corrupto
4. Revisa los registros del contenedor para ver el mensaje de error real

</Accordion>

<Accordion label="HTTP 431 durante el inicio de sesión SSO" group="faq">

Si obtienes un HTTP 431 (Request Header Fields Too Large) durante el inicio de sesión OAuth2/SSO, aumenta el tamaño de cabecera de Jetty:

```yaml
environment:
  - SERVER_JETTY_MAX_HTTP_REQUEST_HEADER_SIZE=16384
```

</Accordion>

<Notice type="info" title="Depuración">

Activa el registro detallado definiendo `SYSTEM_LOGFILE=/logs/stirling.log` en tus variables de entorno. Revisa el archivo de registro para errores a nivel de aplicación.

</Notice>

## Mantenimiento y actualizaciones

### Procedimiento de actualización

```bash
cd ~/stirling-pdf

# Pull the latest image
docker compose pull

# Recreate the container
docker compose up -d

# Clean up old images
docker image prune -f
```

**Fijar la versión:** En producción, considera fijar una etiqueta específica (p. ej., `docker.stirlingpdf.com/stirlingtools/stirling-pdf:v2.14.3`) en lugar de `:latest`. Esto evita roturas sorpresa por actualizaciones automáticas. Cuando estés listo para actualizar, cambia la etiqueta y ejecuta `docker compose pull && docker compose up -d`.

**Haz copia de seguridad antes de actualizaciones importantes.** La propia versión v2.12.0 recomendaba respaldar antes de actualizar. Las versiones se publican de 2 a 4 veces por semana e incluyen correcciones de seguridad — suscríbete al [feed de versiones de GitHub](https://github.com/Stirling-Tools/Stirling-PDF/releases.atom) para estar al tanto.

Para actualizaciones automatizadas de contenedores, considera [autoactualizar contenedores Docker con Tugtainer](https://www.bitdoze.com/es/tugtainer-autoactualizacion-docker/).

### Calendario de mantenimiento

<ListCheck>

- **Semanal**: Monitoriza el uso de disco, comprueba el estado de salud del contenedor
- **Mensual**: Actualiza la imagen de Docker, revisa los registros en busca de errores o advertencias de seguridad
- **Trimestral**: Revisa los límites de recursos, audita cuentas de usuario y claves API
- **Antes de actualizaciones importantes**: Respalda `configs/`, `customFiles/`, `tessdata/`, `pipeline/`

</ListCheck>

## Conclusión

Autoalojar Stirling PDF te da una plataforma de procesamiento de PDF privada y capaz que se ejecuta en tu propia infraestructura. La reescritura de la V2 trajo un frontend moderno en React, procesamiento PDFium de bajo consumo de memoria, un servidor MCP integrado para la integración con agentes de IA y Automate/Pipelines para encadenar operaciones.

<ListCheck>

- **Control de datos**: Los documentos nunca salen de tu servidor — sin subidas a terceros, sin compromisos de privacidad
- **Rentable**: El nivel autoalojado gratuito cubre hasta 5 usuarios con las más de 60 operaciones
- **Límites configurables**: Los límites de tamaño de archivo, número de usuarios y funciones son ajustables
- **Automatización API y MCP**: API REST para scripting, MCP para agentes de IA, Pipelines para encadenar operaciones
- **Seguridad multicapa**: Inicio de sesión, claves API, protección SSRF, limitación de tasa, HTTPS
- **Escalable**: Desde una Raspberry Pi (imagen ultra-lite) hasta un servidor potente manejando PDFs de 2 GB

</ListCheck>

Empieza con la Opción 1 (Docker Compose independiente) para estar en marcha en 5 minutos. Añade Traefik cuando necesites HTTPS. Usa Dokploy si quieres una interfaz gráfica. Las aplicaciones de escritorio son un extra para procesamiento local en tus propias máquinas.

<Button text="Empieza con Stirling PDF" size="xl" color="red" variant="solid" icon="arrow-right" iconPosition="right" />

Explora nuestras guías sobre [orquestación de contenedores Docker con Dockge](https://www.bitdoze.com/es/instalar-dockge/), [configuración de proxy inverso Traefik](https://www.bitdoze.com/traefik-proxy-docker/) y [gestión de la plataforma Dokploy](https://www.bitdoze.com/dokploy-install/).