Stirling-PDF es una aplicación web autoalojada para trabajar con PDF: unir, dividir, rotar, comprimir, convertir desde y hacia imágenes u Office, aplicar OCR, añadir contraseñas o marcas de agua, entre muchas otras operaciones. Como los archivos se procesan en tu servidor, los documentos no salen de tu infraestructura, a diferencia de los servicios en línea. En este tutorial desplegarás Stirling-PDF con Docker Compose en Ubuntu 24.04, activarás el inicio de sesión, añadirás el idioma español al OCR, lo publicarás con Nginx y HTTPS y probarás su API REST.

Requisitos previos

  • Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con al menos 2 GB de RAM y 2 vCPU. El OCR y las conversiones de Office consumen bastante CPU y memoria.
  • Un usuario no root con privilegios sudo.
  • Docker Engine y el plugin Docker Compose instalados desde el repositorio oficial de Docker.
  • Un subdominio (en esta guía, pdf.tu_dominio) con un registro DNS A que apunte a la IP pública del servidor.
  • UFW activo con SSH permitido.

Paso 1: Crear el directorio del proyecto

Crea el directorio del proyecto y las carpetas que se montarán en el contenedor:

mkdir -p ~/stirling-pdf/{trainingData,extraConfigs,logs}
cd ~/stirling-pdf

Cada carpeta tiene una función:

  • trainingData: modelos de idioma de Tesseract para el OCR.
  • extraConfigs: archivos de configuración (settings.yml) y la base de datos de usuarios cuando se activa el inicio de sesión.
  • logs: registros de la aplicación.

Paso 2: Crear el archivo de Docker Compose

Guarda las credenciales del administrador inicial en un archivo .env:

nano ~/stirling-pdf/.env
SECURITY_INITIALLOGIN_USERNAME=admin
SECURITY_INITIALLOGIN_PASSWORD=your_strong_password

Sustituye your_strong_password por una contraseña robusta y protege el archivo:

chmod 600 ~/stirling-pdf/.env

Crea el archivo compose.yaml:

nano ~/stirling-pdf/compose.yaml
services:
  stirling-pdf:
    image: stirlingtools/stirling-pdf:latest
    container_name: stirling-pdf
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:8080"
    volumes:
      - ./trainingData:/usr/share/tessdata
      - ./extraConfigs:/configs
      - ./logs:/logs
    env_file:
      - .env
    environment:
      - SECURITY_ENABLELOGIN=true
      - LANGS=es_ES
      - SYSTEM_DEFAULTLOCALE=es-ES

Qué hace cada ajuste:

  • stirlingtools/stirling-pdf es la imagen oficial actual. Guías antiguas usan frooodle/s-pdf, el nombre anterior.
  • SECURITY_ENABLELOGIN=true obliga a iniciar sesión. Sin él, cualquiera que llegue a la URL puede usar el servicio. SECURITY_INITIALLOGIN_USERNAME y SECURITY_INITIALLOGIN_PASSWORD solo se usan para crear el administrador en el primer arranque.
  • LANGS instala fuentes y recursos para ese idioma y SYSTEM_DEFAULTLOCALE fija el idioma de la interfaz.
  • El puerto se publica solo en 127.0.0.1: Docker se salta UFW, así que publicarlo en todas las interfaces lo expondría sin cifrar. El acceso externo irá por Nginx.

Paso 3: Arrancar Stirling-PDF

Inicia el contenedor. La primera vez tarda en descargar la imagen, que ocupa más de 1 GB:

docker compose up -d

Sigue los registros hasta que la aplicación Java termine de arrancar y pulsa Ctrl+C para salir:

docker compose logs -f stirling-pdf
stirling-pdf  | ... Started SPDFApplication in 12.345 seconds ...

Comprueba que responde en local. Con el inicio de sesión activo, la portada redirige a /login:

curl -sI http://127.0.0.1:8080 | head -n 1
HTTP/1.1 302 Found

Paso 4: Publicar Stirling-PDF con Nginx y HTTPS

Instala Nginx y Certbot:

sudo apt update
sudo apt install nginx certbot python3-certbot-nginx

Crea el bloque de servidor:

sudo nano /etc/nginx/sites-available/stirling-pdf
server {
    listen 80;
    listen [::]:80;
    server_name pdf.tu_dominio;

    client_max_body_size 200M;
    proxy_read_timeout 300s;
    proxy_send_timeout 300s;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

client_max_body_size es imprescindible: Nginx limita las subidas a 1 MB por defecto y cualquier PDF mayor fallaría con un error 413. Los tiempos de espera ampliados evitan cortes durante un OCR largo.

Activa el sitio, valida la configuración y recarga Nginx:

sudo ln -s /etc/nginx/sites-available/stirling-pdf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Abre los puertos web y solicita el certificado:

sudo ufw allow 'Nginx Full'
sudo certbot --nginx -d pdf.tu_dominio
Congratulations! You have successfully enabled HTTPS on https://pdf.tu_dominio

Abre https://pdf.tu_dominio, inicia sesión con el usuario y la contraseña del archivo .env. Si la aplicación te pide cambiar la contraseña en el primer acceso, hazlo; si no, cámbiala desde la configuración de tu cuenta.

Paso 5: Gestionar usuarios

Con el inicio de sesión activo, el administrador puede crear más cuentas desde la configuración de la cuenta, en el apartado de administración de usuarios. Cada usuario tiene un rol (administrador o usuario) y su propia clave de API.

Una vez creado el administrador y cambiada la contraseña, puedes eliminar las dos variables SECURITY_INITIALLOGIN_* del archivo .env: ya no se usan y así la contraseña inicial no queda en disco.

Paso 6: Añadir el idioma español al OCR

Stirling-PDF usa Tesseract para el OCR. La imagen trae los modelos de inglés; para reconocer texto en español descarga el modelo spa del repositorio oficial tessdata en la carpeta montada:

wget -O ~/stirling-pdf/trainingData/spa.traineddata \
  https://github.com/tesseract-ocr/tessdata/raw/main/spa.traineddata

Reinicia el contenedor para que detecte el nuevo idioma:

docker compose restart stirling-pdf

Comprueba que los modelos están disponibles dentro del contenedor:

docker compose exec stirling-pdf ls /usr/share/tessdata
eng.traineddata  osd.traineddata  spa.traineddata

En la interfaz, abre la herramienta de OCR, sube un PDF escaneado y marca el español en la lista de idiomas. El resultado es un PDF con una capa de texto que se puede buscar y copiar. Puedes seleccionar varios idiomas a la vez si el documento los mezcla, a costa de un proceso más lento.

Paso 7: Usar la API REST

Todas las herramientas de la interfaz están también disponibles como API. La documentación interactiva, con cada endpoint y sus parámetros, está en https://pdf.tu_dominio/swagger-ui/index.html.

Con el inicio de sesión activo, cada petición debe llevar la clave de API del usuario en la cabecera X-API-KEY. La encontrarás en la configuración de tu cuenta. Guárdala en una variable de la sesión:

SPDF_KEY="your_api_key"

Une dos PDF en uno. El campo fileInput se repite una vez por archivo y el orden se respeta:

curl -s -X POST https://pdf.tu_dominio/api/v1/general/merge-pdfs \
  -H "X-API-KEY: $SPDF_KEY" \
  -F "[email protected]" \
  -F "[email protected]" \
  -o facturas.pdf

Aplica OCR en español a un documento escaneado, procesando solo las páginas que aún no tienen texto:

curl -s -X POST https://pdf.tu_dominio/api/v1/misc/ocr-pdf \
  -H "X-API-KEY: $SPDF_KEY" \
  -F "[email protected]" \
  -F "languages=spa" \
  -F "ocrType=skip-text" \
  -o escaneado-ocr.pdf

Comprueba que el resultado es un PDF válido y no un mensaje de error guardado con extensión .pdf:

file facturas.pdf escaneado-ocr.pdf
facturas.pdf:      PDF document, version 1.7
escaneado-ocr.pdf: PDF document, version 1.7

Si file indica JSON text data o HTML document, abre el archivo: contiene la respuesta de error de la API, normalmente por una clave incorrecta (401) o un parámetro mal escrito. Consulta los nombres exactos de los parámetros en Swagger.

Paso 8: Actualizar y hacer copias de seguridad

La configuración, los usuarios y los modelos de OCR están en ~/stirling-pdf. Los PDF que se procesan no se guardan en el servidor. Para una copia de seguridad:

cd ~/stirling-pdf
docker compose stop
sudo tar -czf ~/stirling-pdf-backup-$(date +%F).tar.gz -C ~ stirling-pdf
docker compose start

Para actualizar a la última versión:

cd ~/stirling-pdf
docker compose pull
docker compose up -d
docker image prune -f

Solución de problemas

Error 413 al subir un archivo. El límite de Nginx es demasiado bajo. Aumenta client_max_body_size en el bloque de servidor y recarga Nginx.

Error 504 Gateway Timeout durante un OCR. El proceso tarda más que los tiempos de espera de Nginx. Aumenta proxy_read_timeout o divide el documento antes de procesarlo.

El contenedor se reinicia en bucle o se detiene al procesar archivos grandes. Falta memoria. Revisa docker compose logs stirling-pdf y sudo dmesg | grep -i oom; si el kernel ha matado el proceso, amplía la RAM del servidor.

El español no aparece en la lista de idiomas del OCR. El archivo spa.traineddata no está en ~/stirling-pdf/trainingData o el contenedor no se ha reiniciado. Comprueba el paso 6.

Conclusión

Stirling-PDF ya funciona en tu dominio con HTTPS, protegido por inicio de sesión, con OCR en español y acceso por API. Como siguientes pasos puedes crear cuentas para tu equipo, integrar la API en tus flujos de trabajo (por ejemplo, aplicar OCR a cada escaneo que llegue a una carpeta) o programar la copia de seguridad del directorio del proyecto con un temporizador de systemd.