Stirling PDF в Docker Compose: готовый файл
Каждый раз, когда нужно слить два PDF в один, вытащить страницу из скана паспорта или прогнать документ через OCR, соблазн открыть очередной online-конвертер велик — но это значит загрузить чужому серверу договор, скан документа или финансовую отчётность, и вы понятия не имеете, что с файлом происходит дальше. Плюс часть таких сервисов из России работает через раз. Stirling PDF закрывает вопрос раз и навсегда: это открытый инструмент с десятками операций над PDF, который вы поднимаете у себя и используете как внутренний сервис. Ниже — рабочий docker-compose.yml, разбор образов и мест, где стоит подстелить соломки.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что такое Stirling PDF и зачем он вам
Stirling PDF — self-hosted веб-приложение с браузерным интерфейсом и REST API, которое закрывает практически весь бытовой набор операций с PDF: слияние и разбивка файлов, поворот и удаление страниц, сжатие, водяные знаки, извлечение изображений, конвертация PDF в Word/Excel/изображения и обратно, редактирование метаданных, простая защита паролем, электронная подпись полей и распознавание текста (OCR) на десятках языков, включая русский.
Кому это реально пригодится:
- бухгалтерии и юротделу, которые ежедневно сливают сканы, разбивают многостраничные акты и прогоняют документы через OCR, чтобы текст в PDF можно было искать и копировать;
- разработчикам, которым нужен PDF-движок в собственном продукте — Stirling PDF отдаёт REST API, так что операции можно дёргать из своего бэкенда или сценария в n8n, не завязываясь на платный SaaS вроде PDF.co;
- компаниям, где документы содержат персональные данные или коммерческую тайну и правило «файлы не покидают периметр» не обсуждается.
Важная оговорка сразу: Stirling PDF — это про обработку, а не про юридически значимую подпись. Функция «подписать» рисует поле подписи в документе, но не создаёт квалифицированную электронную подпись по 63-ФЗ. Если нужна именно юридически значимая e-подпись с аудитом, посмотрите в сторону Documenso в Docker Compose — это отдельный класс задачи.
Требования к серверу
Нагрузка сильно зависит от того, какими операциями вы пользуетесь. Слияние, разбивка, поворот, удаление страниц — лёгкие, почти мгновенные операции, которые не напрягают CPU. А вот OCR многостраничного скана или конвертация в DOCX/XLSX через LibreOffice — это уже кратковременные, но заметные всплески нагрузки на CPU и RAM, особенно если несколько человек одновременно грузят файлы.
| Сценарий использования | CPU | RAM | Диск |
|---|---|---|---|
| Только базовые операции (слияние, разбивка, поворот, сжатие) | 1-2 vCPU | 1-2 ГБ | 10 ГБ SSD |
| + OCR и конвертация в офисные форматы (полный образ) | 2-4 vCPU | 4 ГБ | 20-30 ГБ SSD |
| Команда 5-10 человек, регулярный OCR больших сканов | 4 vCPU | 6-8 ГБ | 40+ ГБ SSD |
ОС — Ubuntu 24.04 LTS с установленным Docker и Docker Compose plugin. Если сервер уже используется под другие сервисы в Docker, стоит свериться с чек-листом в статье про частые ошибки Docker Compose на проде — там разобраны похожие сценарии с нехваткой памяти и OOM-killer, который тихо убивает контейнер без внятной ошибки в логах.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверГотовый docker-compose.yml
Официальный образ называется stirlingtools/stirling-pdf (проект переименовывался, до этого был frooodle/s-pdf — если видите старые гайды с этим именем, просто замените на актуальное). Создайте директорию проекта:
mkdir -p /opt/stirling-pdf/{trainingData,extraConfigs,customFiles,logs,pipeline}
cd /opt/stirling-pdf
Файл .env:
# Порт приложения внутри контейнера — 8080, наружу отдаём через reverse proxy
STIRLING_TAG=latest
# Языки интерфейса и OCR (через запятую)
LANGS=en_GB,ru_RU
# Авторизация (обязательно включайте, если инстанс смотрит не только в localhost)
DOCKER_ENABLE_SECURITY=true
SECURITY_ENABLE_LOGIN=true
# Название и описание в шапке интерфейса (по желанию)
UI_APPNAME=PDF-инструменты
UI_HOMEDESCRIPTION=Внутренний сервис обработки PDF
Файл docker-compose.yml:
services:
stirling-pdf:
image: stirlingtools/stirling-pdf:${STIRLING_TAG}
restart: unless-stopped
environment:
LANGS: ${LANGS}
DOCKER_ENABLE_SECURITY: ${DOCKER_ENABLE_SECURITY}
SECURITY_ENABLE_LOGIN: ${SECURITY_ENABLE_LOGIN}
UI_APPNAME: ${UI_APPNAME}
UI_HOMEDESCRIPTION: ${UI_HOMEDESCRIPTION}
volumes:
- ./trainingData:/usr/share/tessdata
- ./extraConfigs:/configs
- ./customFiles:/customFiles
- ./logs:/logs
- ./pipeline:/pipeline
ports:
- "127.0.0.1:8080:8080"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/api/v1/info/status"]
interval: 15s
timeout: 5s
retries: 5
Порт привязан к 127.0.0.1 намеренно — наружу приложение отдаёт reverse proxy с TLS, о нём в отдельной секции. Поднимаем стек:
docker compose up -d
docker compose logs -f stirling-pdf
При SECURITY_ENABLE_LOGIN=true при первом запуске создаётся администратор — конкретный способ задать логин/пароль (переменные окружения либо генерация случайного пароля в логах) зависит от версии образа, поэтому первым делом проверьте вывод docker compose logs stirling-pdf на предмет учётных данных и сразу смените пароль в настройках профиля после входа.
Полный образ vs Lite: OCR и конвертация в другие форматы
У Stirling PDF несколько вариантов образа с разным набором зависимостей, и это критично для планирования диска и RAM:
- Полный образ (тег
latestна момент публикации) — включает Tesseract для OCR и LibreOffice для конвертации PDF в Word/Excel/PowerPoint и обратно. Занимает существенно больше места на диске, чем «облегчённые» варианты, и первый старт занимает дольше — образ разворачивает все зависимости. - Облегчённые теги (в разных релизах называются по-разному, ищите в тегах на Docker Hub слова вроде
ultra-liteилиslim) — без LibreOffice и части тяжёлых зависимостей. Если вам нужны только слияние, разбивка, поворот, сжатие и работа со страницами — берите его, старт быстрее и памяти нужно меньше.
Прежде чем фиксировать тег в проде, откройте страницу образа stirlingtools/stirling-pdf на Docker Hub и посмотрите актуальный список тегов — набор менялся между релизами.
Отдельный момент — русский язык для OCR. По умолчанию в образе может не быть языкового пакета rus, и тогда распознавание кириллицы просто не сработает. Скачайте нужный traineddata-файл и положите в смонтированную директорию:
curl -L -o /opt/stirling-pdf/trainingData/rus.traineddata \
https://github.com/tesseract-ocr/tessdata/raw/main/rus.traineddata
docker compose restart stirling-pdf
После рестарта в интерфейсе на вкладке OCR должен появиться русский язык в списке доступных.
Reverse proxy, TLS и авторизация
PDF-файлы, которые проходят через такой сервис — это часто договоры, сканы паспортов, бухгалтерские документы. Три вещи обязательны, а не опциональны:
- TLS — без него логин и пароль, а заодно и содержимое загружаемых файлов, идут в открытом виде. Проще всего поднять Caddy с автоматическим ACME:
pdf.example.com {
reverse_proxy 127.0.0.1:8080
}
Если Caddy на сервере ещё не настроен, разверните его по инструкции Caddy с авто-SSL на Ubuntu 24.04 — вместе с DNS-записью это займёт минут пятнадцать.
- Авторизация —
SECURITY_ENABLE_LOGIN=trueиз блока выше. Без неё любой, кто узнает адрес, сможет загружать и скачивать чужие документы.
- Ограничение доступа на уровне сети, если инстанс нужен только внутренней команде из 3-5 человек — держите его за VPN или ограничьте firewall (
ufw allow from <ваша подсеть> to any port 443) вместо публикации на весь интернет.
Бэкапы, обновление и автоматизация через pipeline
Сам Stirling PDF в базовой конфигурации не хранит обработанные файлы долго — вы загружаете документ, получаете результат, файл не остаётся висеть в интерфейсе неделями. Персистентные данные, которые реально нужно бэкапить — это директории, которые вы примонтировали: extraConfigs (настройки), customFiles (кастомизация интерфейса, если меняли логотип/тему) и pipeline (сохранённые сценарии автообработки). Простой скрипт для cron:
#!/bin/bash
set -e
DATE=$(date +%Y-%m-%d)
BACKUP_DIR=/opt/backups/stirling-pdf
mkdir -p "$BACKUP_DIR"
tar czf "$BACKUP_DIR/stirling_$DATE.tar.gz" \
-C /opt/stirling-pdf extraConfigs customFiles pipeline
find "$BACKUP_DIR" -mtime +14 -delete
Добавьте в crontab -e:
0 4 * * * /opt/stirling-pdf/backup.sh >> /var/log/stirling-backup.log 2>&1
Копии стоит синхронизировать за пределы сервера — например, во внешнее S3-совместимое хранилище через rclone. Если такого хранилища ещё нет, поднять своё — вопрос одного docker-compose файла, см. MinIO в Docker Compose.
Отдельно стоит упомянуть директорию pipeline — это не просто папка для бэкапа, а рабочий инструмент. В интерфейсе Stirling PDF можно собрать цепочку операций (например: OCR → сжатие → добавление водяного знака) и сохранить как pipeline-сценарий; дальше файлы, попадающие в примонтированную папку, обрабатываются автоматически по этому сценарию без похода в браузер. Удобно, если нужно интегрировать обработку PDF в существующий процесс — скажем, сканер в офисе кладёт файлы в шару, которая смонтирована как папка pipeline.
Обновление — смена тега и пересборка:
docker compose pull stirling-pdf
docker compose up -d stirling-pdf
Если у вас есть внешние интеграции через REST API (свой бэкенд или сценарий в n8n дёргает конкретные эндпоинты), перед обновлением на новую версию гляньте changelog проекта на GitHub — пути эндпоинтов и структура ответов между релизами иногда меняются, и молчаливо сломанная интеграция обнаружится не сразу, а в худший момент.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Нужно ли открывать Stirling PDF наружу, если сервис только для своей команды?
Нет. Для 3-5 человек логичнее держать его за VPN или ограничить firewall по IP-подсетям, чем публиковать на публичный домен даже с TLS и логином.
Как добавить распознавание русского текста в OCR?
Скачайте rus.traineddata с официального репозитория tesseract-ocr/tessdata и положите в смонтированную директорию /usr/share/tessdata, затем перезапустите контейнер — язык появится в списке доступных для OCR.
Чем полный образ отличается от облегчённого и что выбрать?
Полный включает LibreOffice для конвертации в Word/Excel/PowerPoint и весь набор для OCR, занимает больше места и стартует дольше. Если нужны только слияние, разбивка, сжатие и работа со страницами — облегчённый тег экономит и диск, и RAM.
Можно ли использовать Stirling PDF без веб-интерфейса, только через API?
Да, приложение отдаёт REST API — операции можно вызывать напрямую из своего бэкенда, скрипта или low-code инструмента вроде n8n, не открывая браузер вообще.
Что будет с загруженными файлами после обработки — они где-то остаются на диске?
В базовой конфигурации обработка синхронная: вы загружаете файл, получаете результат, временные файлы не предназначены для долгого хранения. Но точное поведение зависит от версии и настроек — если для вас критично гарантированное удаление, проверьте актуальную документацию проекта и логи файловой системы контейнера перед тем, как полагаться на это в продакшене.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →