--- description: "Все переменные окружения SnapOtter со значениями по умолчанию. Настройте аутентификацию, хранилище, AI-модели, аналитику и не только." i18n_source_hash: 25970c776f7c i18n_provenance: human i18n_output_hash: e12d29a98fd6 i18n_hash_version: 2 --- # Конфигурация {#configuration} Вся конфигурация выполняется через переменные окружения. У каждой переменной есть разумное значение по умолчанию, поэтому SnapOtter работает «из коробки» без задания хотя бы одной из них. ## Переменные окружения {#environment-variables} ### Сервер {#server} | Переменная | По умолчанию | Описание | |---|---|---| | `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`, только если перед сервером стоит подконтрольный вам прокси с публичным адресом. | ### Аутентификация {#authentication} Две булевы переменные ниже принимают только `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} | Переменная | По умолчанию | Описание | |---|---|---| | `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 {#s3-object-storage} Читается, только когда задано `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` | (пусто) | Префикс ключей, чтобы один бакет мог обслуживать несколько экземпляров. | ### Шифрование данных при хранении {#encryption-at-rest} | Переменная | По умолчанию | Описание | |---|---|---| | `DATA_ENCRYPTION_KEY` | (пусто) | 64 шестнадцатеричных символа (32 байта). Шифрует конфиденциальные настройки, хранящиеся в базе данных. Всё, что не является 64 шестнадцатеричными символами, отклоняется при запуске. | | `DATA_ENCRYPTION_KEY_PREVIOUS` | (пусто) | Ключ, от которого вы уходите при ротации, в том же формате. Задайте оба на время ротации, чтобы существующие строки по-прежнему расшифровывались, а затем уберите этот. | ### Встроенный режим {#embedded-mode} Запустите образ без `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` или используйте отказ в интерфейсе администратора. ### Ограничения обработки {#processing-limits} | Переменная | По умолчанию | Описание | |---|---|---| | `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 для отсутствия ограничений. | ### Очистка {#cleanup} | Переменная | По умолчанию | Описание | |---|---|---| | `FILE_MAX_AGE_HOURS` | `72` | Как долго хранятся несохранённые результаты обработки (исходные загрузки и выводы инструментов) до автоматического удаления. Файлы, которые вы явно сохранили в библиотеку Files, не затрагиваются и хранятся, пока вы их не удалите. | | `CLEANUP_INTERVAL_MINUTES` | `60` | Как часто выполняется задача очистки. | ### Внешний вид {#appearance} | Переменная | По умолчанию | Описание | |---|---|---| | `DEFAULT_THEME` | `light` | Тема по умолчанию для новых сессий. `light`, `dark` или `system`. | | `DEFAULT_LOCALE` | `en` | Язык интерфейса по умолчанию. | | `DEFAULT_TOOL_VIEW` | `sidebar` | Макет инструментов по умолчанию. `sidebar` или `fullscreen`. | ### Права доступа Docker {#docker-permissions} | Переменная | По умолчанию | Описание | |---|---|---| | `PUID` | `999` | Запускать процесс контейнера с этим UID. Установите в соответствии с вашим пользователем хоста для смонтированных каталогов (`id -u`). | | `PGID` | `999` | Запускать процесс контейнера с этим GID. Установите в соответствии с вашей группой хоста для смонтированных каталогов (`id -g`). | ## Пример Docker {#docker-example} ```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: ``` ## Тома {#volumes} Стек Docker Compose использует четыре тома: - `/data` (app), AI-модели, виртуальное окружение Python и файлы пользователя. Смонтируйте его, чтобы сохранять загруженные файлы и установленные AI-пакеты между перезапусками. - `/tmp/workspace` (app), временное хранилище для обрабатываемых файлов. Оно может быть эфемерным, но монтирование избавляет от заполнения записываемого слоя контейнера. - `SnapOtter-pgdata` (postgres), каталог данных PostgreSQL. В нём хранятся все реляционные данные (пользователи, настройки, конвейеры, задачи, журнал аудита). Создавайте резервную копию через `pg_dump` или снимок тома. - `SnapOtter-redisdata` (redis), файл Redis только для добавления (append-only) для устойчивых очередей задач.