Files
SnapOtter/apps/docs/vi/guide/configuration.md
T
SnapOtterandGitHub d10d0f544f fix: release QA hardening across processing, media, security, and CI gates (#649)
A release-readiness QA pass over the whole product. The commits split into
defects a user would hit and gates that were reporting green while measuring
nothing.

## Fixes that change behaviour

Rate limiting was bypassable on every install: TRUST_PROXY defaulted to true, so
request.ip came from a client-set header and a forged X-Forwarded-For got past
the login limiter. The default is now a private-network trust list.

A transient Postgres outage stranded in-flight jobs, leaving finished output on
disk with no row pointing at it. A reconciler now resolves those rows and adopts
the bytes rather than dropping the work.

A Redis connection that moved to a new address wedged every read-blocked
consumer, so completions stopped signalling while health still answered 200.
Socket timeouts plus subscriber pings recover it.

Installing more than one AI bundle left the shared venv multi-versioned and
silently broke three tools. The installer now reconciles distributions to one
version each.

Converting an image to JXL at quality 1 through 4 returned a 500, because
libjxl 0.7 rejects the distance those values compute. The quality is floored at
what the encoder honours. A missing ffmpeg was also reported to the user as a
corrupt upload; it now says the engine is unavailable.

RAW uploads reached an unpatched LibRaw on arm64, so it is built from source at
0.22.2, and the release scan was split so it can fail on an unfixed critical
instead of hiding it behind ignore-unfixed.

## Gates that could not fail

Two mutation lanes ran zero mutants because Stryker crawled the gitignored docs
build; coverage discarded its whole report on any failing test; the lint gate
skipped root tests, scripts, and two workspaces; and several generated matrices
counted a host missing ffmpeg as a passing tool. Each now measures what it
claims.

Full evidence and the outstanding release items are tracked locally and are not
part of this branch.
2026-07-27 15:37:30 +08:00

13 KiB

description, i18n_source_hash, i18n_provenance, i18n_output_hash, i18n_hash_version
description i18n_source_hash i18n_provenance i18n_output_hash i18n_hash_version
Tất cả các biến môi trường của SnapOtter kèm giá trị mặc định. Cấu hình xác thực, lưu trữ, mô hình AI, phân tích và hơn thế. 25970c776f7c human 6ca5e3aa0223 2

Cấu hình

Mọi cấu hình được thực hiện qua các biến môi trường. Mỗi biến đều có một giá trị mặc định hợp lý, nên SnapOtter hoạt động ngay từ đầu mà không cần đặt biến nào.

Các biến môi trường

Máy chủ

Biến Mặc định Mô tả
PORT 1349 Cổng máy chủ lắng nghe.
RATE_LIMIT_PER_MIN 1000 Số yêu cầu tối đa mỗi phút cho mỗi IP. Đặt thành 0 để tắt giới hạn tốc độ.
CORS_ORIGIN (trống) Danh sách các origin được phép cho CORS, phân tách bằng dấu phẩy, hoặc để trống chỉ cho phép cùng origin.
LOG_LEVEL info Mức độ chi tiết của nhật ký. Một trong: fatal, error, warn, info, debug, trace.
TRUST_PROXY loopback,linklocal,uniquelocal Những peer nào được phép đặt IP của client qua X-Forwarded-For. Giá trị mặc định chỉ tin một peer thuộc mạng riêng, nên một reverse proxy trên mạng Docker hoặc trong mạng LAN thì được tin, còn header giả mạo từ một client công khai thì không. Chỉ đặt true khi có một proxy do bạn kiểm soát đứng phía trước trên một địa chỉ công khai.

Xác thực

Hai giá trị boolean bên dưới chỉ chấp nhận truefalse. Bất kỳ giá trị nào khác, 1 hay yes hay on, đều không qua được kiểm tra và máy chủ thoát trước khi bắt đầu lắng nghe.

Biến Mặc định Mô tả
AUTH_ENABLED true Yêu cầu đăng nhập. Đặt thành false để chạy hoàn toàn không có tài khoản nào, điều này cấp quyền admin cho mọi yêu cầu, nên chỉ dùng trong một mạng đáng tin cậy.
DEFAULT_USERNAME admin Tên đăng nhập cho tài khoản admin ban đầu. Chỉ dùng ở lần chạy đầu tiên.
DEFAULT_PASSWORD admin Mật khẩu cho tài khoản admin ban đầu. Đổi mật khẩu này sau lần đăng nhập đầu.
MAX_USERS 0 (không giới hạn) Số tài khoản người dùng đã đăng ký tối đa. Đặt thành 0 để không giới hạn.
SESSION_DURATION_HOURS 168 Thời gian sống của phiên đăng nhập tính bằng giờ (mặc định là 7 ngày).
SKIP_MUST_CHANGE_PASSWORD false Đặt thành true để bỏ qua lời nhắc buộc đổi mật khẩu ở lần đăng nhập đầu.

Lưu trữ

Biến Mặc định Mô tả
STORAGE_MODE local local hoặc s3. S3 và MinIO cần một giấy phép có tính năng s3_storage cùng các biến S3_* bên dưới.
DATABASE_URL postgres://snapotter:snapotter@localhost:5432/snapotter Chuỗi kết nối PostgreSQL. Ngăn xếp Compose trỏ biến này tới dịch vụ postgres của nó; hãy để nó không được đặt (cùng với REDIS_URL) để dùng chế độ nhúng.
REDIS_URL redis://localhost:6379 Chuỗi kết nối Redis (dùng cho các hàng đợi công việc BullMQ). Compose trỏ biến này tới dịch vụ redis của nó.
WORKSPACE_PATH ./tmp/workspace Thư mục cho các tệp tạm thời trong quá trình xử lý. Được dọn dẹp tự động. Image đặt thành /tmp/workspace.
FILES_STORAGE_PATH ./data/files Thư mục cho các tệp người dùng bền vững (ảnh đã tải lên, kết quả đã lưu). Image đặt thành /data/files.

Lưu trữ đối tượng S3

Chỉ được đọc khi STORAGE_MODE=s3. Thiếu bất kỳ biến nào trong ba biến bắt buộc thì quá trình khởi động thất bại và nêu tên biến bạn đã bỏ sót.

Biến Mặc định Mô tả
S3_BUCKET (trống) Bucket chứa các tệp tải lên và đầu ra. Bắt buộc.
S3_ACCESS_KEY_ID (trống) Access key. Bắt buộc. Trong container bạn có thể gắn nó dưới dạng tệp, qua S3_ACCESS_KEY_ID_FILE.
S3_SECRET_ACCESS_KEY (trống) Secret key. Bắt buộc. Cùng quy ước tệp: S3_SECRET_ACCESS_KEY_FILE.
S3_REGION us-east-1 Vùng của bucket.
S3_ENDPOINT (trống) Endpoint tùy chỉnh cho MinIO, R2, Backblaze và các kho lưu trữ tương thích S3 khác. Để trống nghĩa là AWS.
S3_FORCE_PATH_STYLE false Đặt thành true cho MinIO và bất kỳ thứ gì khác cần endpoint/bucket/key thay vì địa chỉ kiểu virtual-host.
S3_PREFIX (trống) Tiền tố key, để một bucket có thể chứa nhiều instance.

Mã hóa khi lưu trữ

Biến Mặc định Mô tả
DATA_ENCRYPTION_KEY (trống) 64 ký tự hex (32 byte). Mã hóa các cài đặt nhạy cảm được lưu trong cơ sở dữ liệu. Bất cứ giá trị nào không phải 64 ký tự hex đều bị từ chối khi khởi động.
DATA_ENCRYPTION_KEY_PREVIOUS (trống) Khóa mà bạn đang xoay vòng để rời khỏi, cùng định dạng. Hãy đặt cả hai trong lúc xoay khóa để các hàng hiện có vẫn giải mã được, rồi bỏ khóa này đi.

Chế độ nhúng

Chạy image mà không có DATABASE_URL và không có REDIS_URL thì nó khởi động PostgreSQL 17 và Redis của riêng nó bên trong container, gắn vào loopback, với tất cả dữ liệu trên volume /data. Điều này khôi phục trải nghiệm docker run một-lệnh cho khởi động nhanh, homelab, và nâng cấp từ 1.x. Đây là một đường tiện lợi, không phải một triển khai sản xuất: đối với sản xuất, hãy chạy ngăn xếp Compose 3 container với PostgreSQL và Redis riêng. Chế độ nhúng yêu cầu chạy container với quyền root và không tương thích với các runtime dùng UID tùy ý (OpenShift, Kubernetes runAsNonRoot); hãy dùng Compose ở đó.

Biến Mặc định Mô tả
EMBEDDED auto Tự động bật khi cả DATABASE_URLREDIS_URL đều không được đặt. Đặt thành 0 để tắt nó (ứng dụng khi đó thất bại nhanh nếu không có DATABASE_URL/REDIS_URL bên ngoài nào được đặt, thay vì âm thầm khởi động một cơ sở dữ liệu trong container).
REDIS_MAXMEMORY 512mb Giới hạn bộ nhớ cho Redis nhúng (chỉ chế độ nhúng). Hãy hạ nó xuống trên các máy chủ bị hạn chế bộ nhớ như Raspberry Pi.

Nâng cấp từ 1.x: đặt snapotter.db cũ của bạn tại /data/snapotter.db trong volume và chế độ nhúng nhập nó vào PostgreSQL nhúng ở lần khởi động đầu tiên. Việc nhập chạy một lần; các lần khởi động sau bỏ qua nó.

Lưu ý về đo lường từ xa: chế độ nhúng thừa hưởng mặc định phân tích của image như mọi cấu hình khác. Image được phát hành đi kèm phân tích được bật; hãy build với --build-arg SNAPOTTER_ANALYTICS=off, hoặc dùng tùy chọn từ chối của admin trong ứng dụng, để tắt nó.

Giới hạn xử lý

Biến Mặc định Mô tả
MAX_UPLOAD_SIZE_MB 0 (không giới hạn) Kích thước tệp tối đa cho mỗi lần tải lên tính bằng megabyte. Đặt thành 0 để không giới hạn. Image được phát hành đi kèm 0; bản build từ mã nguồn bắt đầu ở 100.
MAX_BATCH_SIZE 0 (không giới hạn) Số tệp tối đa trong một yêu cầu hàng loạt. Đặt thành 0 để không giới hạn. Image được phát hành đi kèm 0; bản build từ mã nguồn bắt đầu ở 100.
CONCURRENT_JOBS 0 (tự động) Số công việc hàng loạt chạy song song. Đặt thành 0 để tự động phát hiện dựa trên số lõi CPU khả dụng.
MAX_MEGAPIXELS 0 (không giới hạn) Độ phân giải ảnh tối đa được phép tính bằng megapixel. Đặt thành 0 để không giới hạn.
MAX_WORKER_THREADS 0 (tự động) Số luồng worker tối đa cho xử lý ảnh. Đặt thành 0 để tự động phát hiện dựa trên số lõi CPU khả dụng.
PROCESSING_TIMEOUT_S 0 (không giới hạn) Thời gian xử lý tối đa cho mỗi yêu cầu tính bằng giây. Đặt thành 0 để không có thời gian chờ.
MAX_PIPELINE_STEPS 20 Số bước tối đa trong một pipeline. Đặt thành 0 để không giới hạn.
MAX_CANVAS_PIXELS 0 (không giới hạn) Kích thước khung vẽ tối đa tính bằng pixel cho các ảnh đầu ra. Đặt thành 0 để không giới hạn.
MAX_SVG_SIZE_MB 50 Tệp SVG lớn nhất được chấp nhận trước khi làm sạch, tính bằng megabyte. 0 ở đây hành xử khác với các hàng xung quanh. Nó gỡ bỏ hoàn toàn giới hạn kích thước trước khi phân tích thay vì nâng giới hạn lên, nên hãy luôn đặt giá trị cho biến này.
MAX_PDF_PAGES 0 (không giới hạn) Số trang PDF tối đa cho việc chuyển đổi PDF-to-image. Đặt thành 0 để không giới hạn.

Dọn dẹp

Biến Mặc định Mô tả
FILE_MAX_AGE_HOURS 72 Các kết quả xử lý chưa lưu (các tệp tải lên thô và đầu ra công cụ) được giữ bao lâu trước khi bị xóa tự động. Các tệp bạn lưu rõ ràng vào thư viện Files không bị ảnh hưởng và tồn tại cho đến khi bạn xóa chúng.
CLEANUP_INTERVAL_MINUTES 60 Công việc dọn dẹp chạy thường xuyên đến mức nào.

Giao diện

Biến Mặc định Mô tả
DEFAULT_THEME light Chủ đề mặc định cho các phiên mới. light, dark hoặc system.
DEFAULT_LOCALE en Ngôn ngữ giao diện mặc định.
DEFAULT_TOOL_VIEW sidebar Bố cục công cụ mặc định. sidebar hoặc fullscreen.

Quyền Docker

Biến Mặc định Mô tả
PUID 999 Chạy tiến trình container với UID này. Đặt cho khớp với người dùng host của bạn cho các bind mount (id -u).
PGID 999 Chạy tiến trình container với GID này. Đặt cho khớp với nhóm host của bạn cho các bind mount (id -g).

Ví dụ Docker

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     # Thay đổi điều này cho việc triển khai không cục bộ
      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:

Các volume

Ngăn xếp Docker Compose dùng bốn volume:

  • /data (app) - Các mô hình AI, venv Python và tệp người dùng. Gắn cái này để giữ các tệp đã tải lên và các gói AI đã cài đặt qua các lần khởi động lại.
  • /tmp/workspace (app) - Lưu trữ tạm thời cho các tệp đang được xử lý. Cái này có thể là tạm thời, nhưng gắn nó tránh làm đầy lớp có thể ghi của container.
  • SnapOtter-pgdata (postgres) - Thư mục dữ liệu PostgreSQL. Cái này chứa tất cả dữ liệu quan hệ (người dùng, cài đặt, pipeline, công việc, nhật ký kiểm toán). Sao lưu qua pg_dump hoặc ảnh chụp nhanh volume.
  • SnapOtter-redisdata (redis) - Tệp chỉ-ghi-thêm của Redis cho các hàng đợi công việc bền vững.