Search K
Конфигурация
Вся конфигурация выполняется через переменные окружения. У каждой переменной есть разумное значение по умолчанию, поэтому SnapOtter работает «из коробки» без задания хотя бы одной из них.
Переменные окружения
Сервер
| Переменная | По умолчанию | Описание |
|---|---|---|
PORT | 1349 | Порт, который прослушивает сервер. |
RATE_LIMIT_PER_MIN | 1000 | Максимум запросов в минуту с одного IP. Установите 0, чтобы отключить ограничение частоты запросов. |
CORS_ORIGIN | (пусто) | Разделённый запятыми список разрешённых источников для CORS или пусто только для того же источника. |
LOG_LEVEL | info | Подробность журнала. Одно из: fatal, error, warn, info, debug, trace. |
TRUST_PROXY | loopback,linklocal,uniquelocal | Каким узлам разрешено задавать IP клиента через X-Forwarded-For. Значение по умолчанию верит только узлу из частной сети, поэтому обратному прокси в сети Docker или в локальной сети доверие есть, а поддельному заголовку от публичного клиента нет. Указывайте true, только если перед сервером стоит подконтрольный вам прокси с публичным адресом. |
Аутентификация
Две булевы переменные ниже принимают только true и false. Всё остальное, будь то 1, yes или on, не проходит проверку, и сервер завершает работу, не начав принимать соединения.
| Переменная | По умолчанию | Описание |
|---|---|---|
AUTH_ENABLED | true | Требовать вход. Установите false, чтобы работать вообще без учётных записей: тогда любой запрос получает права администратора, поэтому оставляйте так только в доверенной сети. |
DEFAULT_USERNAME | admin | Имя пользователя для начальной учётной записи администратора. Используется только при первом запуске. |
DEFAULT_PASSWORD | admin | Пароль для начальной учётной записи администратора. Смените его после первого входа. |
MAX_USERS | 0 (без ограничений) | Максимальное число зарегистрированных учётных записей пользователей. Установите 0 для отсутствия ограничений. |
SESSION_DURATION_HOURS | 168 | Время жизни сессии входа в часах (по умолчанию 7 дней). |
SKIP_MUST_CHANGE_PASSWORD | false | Установите true, чтобы пропустить принудительный запрос на смену пароля при первом входе. |
Хранилище
| Переменная | По умолчанию | Описание |
|---|---|---|
STORAGE_MODE | local | local или s3. Для S3 и MinIO нужна лицензия с функцией s3_storage, а также переменные S3_* ниже. |
DATABASE_URL | postgres://snapotter:snapotter@localhost:5432/snapotter | Строка подключения PostgreSQL. Стек Compose направляет её на свой сервис postgres; оставьте её незаданной (вместе с REDIS_URL), чтобы получить встроенный режим. |
REDIS_URL | redis://localhost:6379 | Строка подключения Redis (используется для очередей задач BullMQ). Compose направляет её на свой сервис redis. |
WORKSPACE_PATH | ./tmp/workspace | Каталог для временных файлов во время обработки. Очищается автоматически. В образе задан /tmp/workspace. |
FILES_STORAGE_PATH | ./data/files | Каталог для постоянных файлов пользователя (загруженные изображения, сохранённые результаты). В образе задан /data/files. |
Объектное хранилище S3
Читается, только когда задано STORAGE_MODE=s3. Пропустите любую из трёх обязательных переменных, и запуск завершится ошибкой с именем той переменной, которую вы не задали.
| Переменная | По умолчанию | Описание |
|---|---|---|
S3_BUCKET | (пусто) | Бакет, в котором хранятся загрузки и результаты. Обязательная. |
S3_ACCESS_KEY_ID | (пусто) | Ключ доступа. Обязательная. В контейнере его можно вместо этого смонтировать файлом через S3_ACCESS_KEY_ID_FILE. |
S3_SECRET_ACCESS_KEY | (пусто) | Секретный ключ. Обязательная. То же соглашение о файлах: S3_SECRET_ACCESS_KEY_FILE. |
S3_REGION | us-east-1 | Регион бакета. |
S3_ENDPOINT | (пусто) | Собственная конечная точка для MinIO, R2, Backblaze и других S3-совместимых хранилищ. Пусто означает AWS. |
S3_FORCE_PATH_STYLE | false | Установите true для MinIO и всего остального, что ожидает endpoint/bucket/key вместо адресации по виртуальному хосту. |
S3_PREFIX | (пусто) | Префикс ключей, чтобы один бакет мог обслуживать несколько экземпляров. |
Шифрование данных при хранении
| Переменная | По умолчанию | Описание |
|---|---|---|
DATA_ENCRYPTION_KEY | (пусто) | 64 шестнадцатеричных символа (32 байта). Шифрует конфиденциальные настройки, хранящиеся в базе данных. Всё, что не является 64 шестнадцатеричными символами, отклоняется при запуске. |
DATA_ENCRYPTION_KEY_PREVIOUS | (пусто) | Ключ, от которого вы уходите при ротации, в том же формате. Задайте оба на время ротации, чтобы существующие строки по-прежнему расшифровывались, а затем уберите этот. |
Встроенный режим
Запустите образ без DATABASE_URL и без REDIS_URL, и он запустит собственные PostgreSQL 17 и Redis внутри контейнера, привязанные к loopback, со всеми данными на томе /data. Это восстанавливает опыт запуска одной командой docker run для быстрого старта, домашней лаборатории и обновлений с 1.x. Это путь для удобства, а не продакшн-развёртывание: для продакшена запускайте стек из 3 контейнеров Compose с отдельными PostgreSQL и Redis. Встроенный режим требует запуска контейнера от root и несовместим со средами с произвольным UID (OpenShift, Kubernetes runAsNonRoot); там используйте Compose.
| Переменная | По умолчанию | Описание |
|---|---|---|
EMBEDDED | auto | Включается автоматически, когда и DATABASE_URL, и REDIS_URL не заданы. Установите 0, чтобы отключить (тогда приложение сразу падает, если не задана внешняя DATABASE_URL/REDIS_URL, вместо тихого запуска базы данных внутри контейнера). |
REDIS_MAXMEMORY | 512mb | Ограничение памяти для встроенного Redis (только встроенный режим). Понизьте его на хостах с ограниченной памятью, например на Raspberry Pi. |
Обновление с 1.x: положите вашу старую snapotter.db по пути /data/snapotter.db в томе, и встроенный режим импортирует её во встроенный PostgreSQL при первом запуске. Импорт выполняется один раз; последующие запуски его пропускают.
Примечание о телеметрии: встроенный режим наследует значение аналитики по умолчанию из образа, как и любая другая конфигурация. Публикуемый образ поставляется с включённой аналитикой; чтобы отключить её, соберите с --build-arg SNAPOTTER_ANALYTICS=off или используйте отказ в интерфейсе администратора.
Ограничения обработки
| Переменная | По умолчанию | Описание |
|---|---|---|
MAX_UPLOAD_SIZE_MB | 0 (без ограничений) | Максимальный размер файла на одну загрузку в мегабайтах. Установите 0 для отсутствия ограничений. Публикуемый образ поставляется со значением 0; сборка из исходников начинает со 100. |
MAX_BATCH_SIZE | 0 (без ограничений) | Максимальное число файлов в одном пакетном запросе. Установите 0 для отсутствия ограничений. Публикуемый образ поставляется со значением 0; сборка из исходников начинает со 100. |
CONCURRENT_JOBS | 0 (авто) | Число пакетных задач, выполняемых параллельно. Установите 0 для автоопределения по числу доступных ядер CPU. |
MAX_MEGAPIXELS | 0 (без ограничений) | Максимальное разрешение изображения в мегапикселях. Установите 0 для отсутствия ограничений. |
MAX_WORKER_THREADS | 0 (авто) | Максимальное число потоков-воркеров для обработки изображений. Установите 0 для автоопределения по числу доступных ядер CPU. |
PROCESSING_TIMEOUT_S | 0 (без ограничения) | Максимальное время обработки на запрос в секундах. Установите 0 для отсутствия тайм-аута. |
MAX_PIPELINE_STEPS | 20 | Максимальное число шагов в конвейере. Установите 0 для отсутствия ограничения. |
MAX_CANVAS_PIXELS | 0 (без ограничения) | Максимальный размер холста в пикселях для выходных изображений. Установите 0 для отсутствия ограничения. |
MAX_SVG_SIZE_MB | 50 | Наибольший SVG, принимаемый до очистки, в мегабайтах. Здесь 0 ведёт себя не так, как в соседних строках: он полностью снимает ограничение размера до разбора, а не поднимает его, поэтому эту переменную лучше оставить заданной. |
MAX_PDF_PAGES | 0 (без ограничений) | Максимальное число страниц PDF для преобразования PDF в изображение. Установите 0 для отсутствия ограничений. |
Очистка
| Переменная | По умолчанию | Описание |
|---|---|---|
FILE_MAX_AGE_HOURS | 72 | Как долго хранятся несохранённые результаты обработки (исходные загрузки и выводы инструментов) до автоматического удаления. Файлы, которые вы явно сохранили в библиотеку Files, не затрагиваются и хранятся, пока вы их не удалите. |
CLEANUP_INTERVAL_MINUTES | 60 | Как часто выполняется задача очистки. |
Внешний вид
| Переменная | По умолчанию | Описание |
|---|---|---|
DEFAULT_THEME | light | Тема по умолчанию для новых сессий. light, dark или system. |
DEFAULT_LOCALE | en | Язык интерфейса по умолчанию. |
DEFAULT_TOOL_VIEW | sidebar | Макет инструментов по умолчанию. sidebar или fullscreen. |
Права доступа Docker
| Переменная | По умолчанию | Описание |
|---|---|---|
PUID | 999 | Запускать процесс контейнера с этим UID. Установите в соответствии с вашим пользователем хоста для смонтированных каталогов (id -u). |
PGID | 999 | Запускать процесс контейнера с этим GID. Установите в соответствии с вашей группой хоста для смонтированных каталогов (id -g). |
Пример Docker
yaml
services:
SnapOtter:
image: snapotter/snapotter:latest
ports:
- "1349:1349"
volumes:
- SnapOtter-data:/data
- SnapOtter-workspace:/tmp/workspace
environment:
- AUTH_ENABLED=true
- DEFAULT_USERNAME=admin
- DEFAULT_PASSWORD=changeme
- DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter
- REDIS_URL=redis://redis:6379
- MAX_UPLOAD_SIZE_MB=200
- CONCURRENT_JOBS=4
- FILE_MAX_AGE_HOURS=12
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
restart: unless-stopped
postgres:
image: postgres:17-alpine
environment:
POSTGRES_USER: snapotter
POSTGRES_PASSWORD: snapotter # Измените это для нелокальных развертываний.
POSTGRES_DB: snapotter
volumes:
- SnapOtter-pgdata:/var/lib/postgresql/data
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"]
interval: 10s
timeout: 5s
retries: 12
redis:
image: redis:8-alpine
command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"]
volumes:
- SnapOtter-redisdata:/data
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 12
volumes:
SnapOtter-data:
SnapOtter-workspace:
SnapOtter-pgdata:
SnapOtter-redisdata:Тома
Стек Docker Compose использует четыре тома:
/data(app), AI-модели, виртуальное окружение Python и файлы пользователя. Смонтируйте его, чтобы сохранять загруженные файлы и установленные AI-пакеты между перезапусками./tmp/workspace(app), временное хранилище для обрабатываемых файлов. Оно может быть эфемерным, но монтирование избавляет от заполнения записываемого слоя контейнера.SnapOtter-pgdata(postgres), каталог данных PostgreSQL. В нём хранятся все реляционные данные (пользователи, настройки, конвейеры, задачи, журнал аудита). Создавайте резервную копию черезpg_dumpили снимок тома.SnapOtter-redisdata(redis), файл Redis только для добавления (append-only) для устойчивых очередей задач.
