mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
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.
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
---
|
||||
description: "Monorepo-struktur, app- och paketarkitektur, förfrågningslivscykel och resursavtryck för SnapOtter."
|
||||
i18n_output_hash: bafad20476af
|
||||
i18n_source_hash: a53946e760b0
|
||||
i18n_source_hash: 50e076925c4b
|
||||
i18n_provenance: human
|
||||
i18n_output_hash: 4691aa895e15
|
||||
i18n_hash_version: 2
|
||||
---
|
||||
|
||||
# Arkitektur {#architecture}
|
||||
@@ -52,7 +53,7 @@ Delade TypeScript-typer, konstanter (som `APP_VERSION` och verktygsdefinitioner)
|
||||
|
||||
### API (`apps/api`) {#api-apps-api}
|
||||
|
||||
En Fastify v5-server som exponerar 241 verktygsrutter över fem modaliteter (image, video, audio, PDF, file) och som hanterar:
|
||||
En Fastify v5-server som exponerar 243 verktygsrutter över fem modaliteter (image, video, audio, PDF, file) och som hanterar:
|
||||
- Filuppladdningar, hantering av tillfällig arbetsyta och beständig fillagring
|
||||
- Användarens filbibliotek (`user_files`-tabellen): en sparad ändring lagras som standard som en oberoende ny fil, eller som en förälderlänkad version när du skriver över originalet. Det registrerar vilka verktyg som tillämpades (`toolChain`) och får en autogenererad miniatyrbild för Files-sidan
|
||||
- Verktygsexekvering (dirigerar varje verktygsförfrågan till bildmotorn eller AI-bryggan)
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
---
|
||||
description: "Alla SnapOtter-miljövariabler med standardvärden. Konfigurera autentisering, lagring, AI-modeller, analys med mera."
|
||||
i18n_source_hash: 8e9e9ca2840c
|
||||
i18n_source_hash: 25970c776f7c
|
||||
i18n_provenance: human
|
||||
i18n_output_hash: 891cb14c17a5
|
||||
i18n_output_hash: 2ecff13095a6
|
||||
i18n_hash_version: 2
|
||||
---
|
||||
|
||||
# Konfiguration {#configuration}
|
||||
@@ -19,28 +20,51 @@ All konfiguration görs via miljövariabler. Varje variabel har ett vettigt stan
|
||||
| `RATE_LIMIT_PER_MIN` | `1000` | Maximalt antal förfrågningar per minut per IP. Sätt till 0 för att inaktivera hastighetsbegränsning. |
|
||||
| `CORS_ORIGIN` | (tom) | Kommaseparerade tillåtna ursprung för CORS, eller tom för endast samma ursprung. |
|
||||
| `LOG_LEVEL` | `info` | Loggutförlighet. En av: `fatal`, `error`, `warn`, `info`, `debug`, `trace`. |
|
||||
| `TRUST_PROXY` | `true` | Lita på `X-Forwarded-For`-huvuden från en omvänd proxy. Sätt till `false` om du inte är bakom en proxy. |
|
||||
| `TRUST_PROXY` | `loopback,linklocal,uniquelocal` | Vilka motparter som får sätta klientens IP via `X-Forwarded-For`. Standardvärdet tror bara på en motpart i ett privat nät, så en omvänd proxy på ett Docker-nätverk eller i ett LAN är betrodd medan en publik klients förfalskade huvud inte är det. Sätt `true` bara när en proxy du själv styr står framför på en publik adress. |
|
||||
|
||||
### Autentisering {#authentication}
|
||||
|
||||
De två booleska värdena nedan accepterar bara `true` och `false`. Allt annat, `1` eller `yes` eller `on`, klarar inte valideringen och servern avslutas innan den börjar lyssna.
|
||||
|
||||
| Variabel | Standard | Beskrivning |
|
||||
|---|---|---|
|
||||
| `AUTH_ENABLED` | `false` | Sätt till `true` för att kräva inloggning. Docker-avbildningen har som standard `true`. |
|
||||
| `AUTH_ENABLED` | `true` | Kräver inloggning. Sätt till `false` för att köra helt utan konton, vilket ger varje förfrågan adminrättigheter, så håll det till ett betrott nätverk. |
|
||||
| `DEFAULT_USERNAME` | `admin` | Användarnamn för det initiala admin-kontot. Används endast vid första körningen. |
|
||||
| `DEFAULT_PASSWORD` | `admin` | Lösenord för det initiala admin-kontot. Ändra detta efter första inloggningen. |
|
||||
| `MAX_USERS` | `0` (obegränsat) | Maximalt antal registrerade användarkonton. Sätt till 0 för obegränsat. |
|
||||
| `SESSION_DURATION_HOURS` | `168` | Livslängd för inloggningssession i timmar (standard är 7 dagar). |
|
||||
| `SKIP_MUST_CHANGE_PASSWORD` | - | Sätt till valfritt icke-tomt värde för att kringgå den tvingade uppmaningen om lösenordsbyte vid första inloggningen |
|
||||
| `SKIP_MUST_CHANGE_PASSWORD` | `false` | Sätt till `true` för att hoppa över den tvingade uppmaningen om lösenordsbyte vid första inloggningen. |
|
||||
|
||||
### Lagring {#storage}
|
||||
|
||||
| Variabel | Standard | Beskrivning |
|
||||
|---|---|---|
|
||||
| `STORAGE_MODE` | `local` | `local` eller `s3`. S3/MinIO kräver en licens med funktionen s3_storage. |
|
||||
| `DATABASE_URL` | `postgres://snapotter:snapotter@postgres:5432/snapotter` | PostgreSQL-anslutningssträng. |
|
||||
| `REDIS_URL` | `redis://redis:6379` | Redis-anslutningssträng (används för BullMQ-jobbköer). |
|
||||
| `WORKSPACE_PATH` | `./tmp/workspace` | Katalog för tillfälliga filer under bearbetning. Rensas automatiskt. |
|
||||
| `FILES_STORAGE_PATH` | `./data/files` | Katalog för beständiga användarfiler (uppladdade bilder, sparade resultat). |
|
||||
| `STORAGE_MODE` | `local` | `local` eller `s3`. S3 och MinIO kräver en licens med funktionen s3_storage plus `S3_*`-variablerna nedan. |
|
||||
| `DATABASE_URL` | `postgres://snapotter:snapotter@localhost:5432/snapotter` | PostgreSQL-anslutningssträng. Compose-stacken pekar den mot sin `postgres`-tjänst; lämna den osatt (tillsammans med `REDIS_URL`) för att få inbäddat läge. |
|
||||
| `REDIS_URL` | `redis://localhost:6379` | Redis-anslutningssträng (används för BullMQ-jobbköer). Compose pekar den mot sin `redis`-tjänst. |
|
||||
| `WORKSPACE_PATH` | `./tmp/workspace` | Katalog för tillfälliga filer under bearbetning. Rensas automatiskt. Avbildningen sätter `/tmp/workspace`. |
|
||||
| `FILES_STORAGE_PATH` | `./data/files` | Katalog för beständiga användarfiler (uppladdade bilder, sparade resultat). Avbildningen sätter `/data/files`. |
|
||||
|
||||
### S3-objektlagring {#s3-object-storage}
|
||||
|
||||
Läses bara när `STORAGE_MODE=s3`. Missar du någon av de tre obligatoriska misslyckas starten med namnet på variabeln du utelämnade.
|
||||
|
||||
| Variabel | Standard | Beskrivning |
|
||||
|---|---|---|
|
||||
| `S3_BUCKET` | (tom) | Bucket som håller uppladdningar och utdata. Obligatorisk. |
|
||||
| `S3_ACCESS_KEY_ID` | (tom) | Åtkomstnyckel. Obligatorisk. I containern kan du montera den i stället, via `S3_ACCESS_KEY_ID_FILE`. |
|
||||
| `S3_SECRET_ACCESS_KEY` | (tom) | Hemlig nyckel. Obligatorisk. Samma filkonvention: `S3_SECRET_ACCESS_KEY_FILE`. |
|
||||
| `S3_REGION` | `us-east-1` | Bucketens region. |
|
||||
| `S3_ENDPOINT` | (tom) | Egen endpoint för MinIO, R2, Backblaze och andra S3-kompatibla lagringar. Tom betyder AWS. |
|
||||
| `S3_FORCE_PATH_STYLE` | `false` | Sätt till `true` för MinIO och allt annat som vill ha `endpoint/bucket/key` i stället för adressering via virtuell värd. |
|
||||
| `S3_PREFIX` | (tom) | Nyckelprefix, så att en bucket kan rymma flera instanser. |
|
||||
|
||||
### Kryptering i vila {#encryption-at-rest}
|
||||
|
||||
| Variabel | Standard | Beskrivning |
|
||||
|---|---|---|
|
||||
| `DATA_ENCRYPTION_KEY` | (tom) | 64 hexadecimala tecken (32 byte). Krypterar känsliga inställningar som lagras i databasen. Allt som inte är 64 hexadecimala tecken avvisas vid start. |
|
||||
| `DATA_ENCRYPTION_KEY_PREVIOUS` | (tom) | Nyckeln du roterar bort från, samma format. Sätt båda under en rotation så att befintliga rader fortfarande går att dekryptera, och ta sedan bort den här. |
|
||||
|
||||
### Inbäddat läge {#embedded-mode}
|
||||
|
||||
@@ -59,16 +83,15 @@ Telemetrinotering: inbäddat läge ärver avbildningens analysstandard som all a
|
||||
|
||||
| Variabel | Standard | Beskrivning |
|
||||
|---|---|---|
|
||||
| `MAX_UPLOAD_SIZE_MB` | `100` | Maximal filstorlek per uppladdning i megabyte. Sätt till 0 för obegränsat. |
|
||||
| `MAX_BATCH_SIZE` | `100` | Maximalt antal filer i en enda batchförfrågan. Sätt till 0 för obegränsat. |
|
||||
| `MAX_UPLOAD_SIZE_MB` | `0` (obegränsat) | Maximal filstorlek per uppladdning i megabyte. Sätt till 0 för obegränsat. Den publicerade avbildningen levereras med `0`; ett bygge från källkoden börjar på 100. |
|
||||
| `MAX_BATCH_SIZE` | `0` (obegränsat) | Maximalt antal filer i en enda batchförfrågan. Sätt till 0 för obegränsat. Den publicerade avbildningen levereras med `0`; ett bygge från källkoden börjar på 100. |
|
||||
| `CONCURRENT_JOBS` | `0` (auto) | Antal batchjobb som körs parallellt. Sätt till 0 för att detektera automatiskt baserat på tillgängliga CPU-kärnor. |
|
||||
| `MAX_MEGAPIXELS` | `0` (obegränsat) | Maximal bildupplösning tillåten i megapixlar. Sätt till 0 för obegränsat. |
|
||||
| `MAX_WORKER_THREADS` | `0` (auto) | Maximalt antal worker-trådar för bildbehandling. Sätt till 0 för att detektera automatiskt baserat på tillgängliga CPU-kärnor. |
|
||||
| `PROCESSING_TIMEOUT_S` | `0` (ingen gräns) | Maximal bearbetningstid per förfrågan i sekunder. Sätt till 0 för ingen timeout. |
|
||||
| `MAX_PIPELINE_STEPS` | `20` | Maximalt antal steg i en pipeline. Sätt till 0 för ingen gräns. |
|
||||
| `MAX_CANVAS_PIXELS` | `0` (ingen gräns) | Maximal arbetsytestorlek i pixlar för utdatabilder. Sätt till 0 för ingen gräns. |
|
||||
| `MAX_SVG_SIZE_MB` | `0` (obegränsat) | Maximal SVG-filstorlek i megabyte. Sätt till 0 för obegränsat. |
|
||||
| `MAX_SPLIT_GRID` | `100` | Maximal rutnätsdimension för verktyget för bilddelning. |
|
||||
| `MAX_SVG_SIZE_MB` | `50` | Största SVG som accepteras före sanering, i megabyte. `0` beter sig annorlunda här än i raderna omkring. Det tar bort storleksgränsen före parsning helt i stället för att höja den, så låt den här vara satt. |
|
||||
| `MAX_PDF_PAGES` | `0` (obegränsat) | Maximalt antal PDF-sidor för PDF-till-bild-konvertering. Sätt till 0 för obegränsat. |
|
||||
|
||||
### Rensning {#cleanup}
|
||||
@@ -82,7 +105,7 @@ Telemetrinotering: inbäddat läge ärver avbildningens analysstandard som all a
|
||||
|
||||
| Variabel | Standard | Beskrivning |
|
||||
|---|---|---|
|
||||
| `DEFAULT_THEME` | `light` | Standardtema för nya sessioner. `light` eller `dark`. |
|
||||
| `DEFAULT_THEME` | `light` | Standardtema för nya sessioner. `light`, `dark` eller `system`. |
|
||||
| `DEFAULT_LOCALE` | `en` | Standardgränssnittsspråk. |
|
||||
| `DEFAULT_TOOL_VIEW` | `sidebar` | Standardverktygslayout. `sidebar` eller `fullscreen`. |
|
||||
|
||||
@@ -124,13 +147,13 @@ services:
|
||||
image: postgres:17-alpine
|
||||
environment:
|
||||
POSTGRES_USER: snapotter
|
||||
POSTGRES_PASSWORD: snapotter
|
||||
POSTGRES_PASSWORD: snapotter # Ändra detta för icke-lokala distributioner
|
||||
POSTGRES_DB: snapotter
|
||||
volumes:
|
||||
- SnapOtter-pgdata:/var/lib/postgresql/data
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U snapotter"]
|
||||
test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 12
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
---
|
||||
description: "Så bidrar du till SnapOtter. Buggrapporter, funktionsförslag, pull requests och CLA-krav."
|
||||
i18n_source_hash: 528802503035
|
||||
i18n_source_hash: 6c920a5f83e0
|
||||
i18n_provenance: human
|
||||
i18n_output_hash: f8b510a1881a
|
||||
i18n_output_hash: b0a61ebb3e0d
|
||||
i18n_hash_version: 2
|
||||
---
|
||||
|
||||
# Bidra {#contributing}
|
||||
@@ -53,7 +54,7 @@ Om du bidrar för din arbetsgivares räkning och din arbetsgivare behåller de i
|
||||
|
||||
### Förutsättningar {#prerequisites}
|
||||
|
||||
- Node.js 22+
|
||||
- Node.js 22.22+
|
||||
- pnpm 9+
|
||||
- Python 3.11+ (endast för AI-verktyg)
|
||||
- Docker (valfritt, för fullständig integrationstestning)
|
||||
@@ -71,7 +72,7 @@ docker compose -f docker-compose.dev.yml up -d
|
||||
# Install dependencies
|
||||
pnpm install
|
||||
|
||||
# Start dev servers (web on :1349, API on :13490)
|
||||
# Start dev servers (web on :1351, API on :13490)
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
---
|
||||
description: "PostgreSQL-databasschema, tabeller, migrationer och säkerhetskopieringsprocedurer för SnapOtter."
|
||||
i18n_source_hash: 50d5d4f220cf
|
||||
i18n_provenance: human
|
||||
i18n_output_hash: 0751b689f6eb
|
||||
i18n_source_hash: a68264552836
|
||||
i18n_provenance: machine
|
||||
i18n_output_hash: a6882b6004eb
|
||||
i18n_hash_version: 2
|
||||
---
|
||||
|
||||
# Databas {#database}
|
||||
@@ -145,6 +146,17 @@ Logg över säkerhetsrelevanta åtgärder.
|
||||
| `details` | jsonb | Åtgärdsspecifika data |
|
||||
| `createdAt` | timestamp | Åtgärdstidpunkt |
|
||||
|
||||
### user_preferences {#user-preferences}
|
||||
|
||||
Gränssnittstillstånd per användare, nycklat på inställningens namn. Lagrar startsidans fästa verktyg, som skrivs via `PUT /api/v1/preferences`.
|
||||
|
||||
| Kolumn | Typ | Anmärkningar |
|
||||
|---|---|---|
|
||||
| `userId` | text | FK till users, kaskaderande borttagning. Primärnyckel tillsammans med `key` |
|
||||
| `key` | text | Inställningens namn. Primärnyckel tillsammans med `userId` |
|
||||
| `value` | jsonb | Inställningens innehåll |
|
||||
| `updatedAt` | timestamp | Senaste skrivning |
|
||||
|
||||
## Migrationer {#migrations}
|
||||
|
||||
Drizzle sköter schemamigrationer. Migrationsfiler ligger i `apps/api/drizzle/`. Under utveckling:
|
||||
@@ -157,29 +169,37 @@ npx drizzle-kit migrate # apply pending migrations
|
||||
|
||||
I produktion tillämpas väntande migrationer automatiskt vid uppstart.
|
||||
|
||||
## Säkerhetskopiering och återställning {#backup-and-restore}
|
||||
## Säkerhetskopiera och återställa {#backup-and-restore}
|
||||
|
||||
Den relationella databasen ligger i Postgres-containerns `SnapOtter-pgdata`-volym, inte i appens `/data`-volym.
|
||||
Relationsdatabasen finns i Postgres-behållarens `SnapOtter-pgdata`-volym, inte appens `/data`-volym.
|
||||
|
||||
**Alternativ 1: pg_dump (rekommenderas)**
|
||||
**Logisk säkerhetskopiering med validering (rekommenderas)**
|
||||
|
||||
```bash
|
||||
# Dump the database while the stack is running
|
||||
docker exec SnapOtter-postgres pg_dump -U snapotter snapotter > backup.sql
|
||||
# Dump into PostgreSQL's portable custom archive format
|
||||
docker exec SnapOtter-postgres \
|
||||
pg_dump --format=custom --no-owner -U snapotter snapotter > snapotter.dump
|
||||
test -s snapotter.dump
|
||||
docker exec -i SnapOtter-postgres pg_restore --list < snapotter.dump >/dev/null
|
||||
|
||||
# Restore into a fresh database
|
||||
cat backup.sql | docker exec -i SnapOtter-postgres psql -U snapotter snapotter
|
||||
# Restore into a fresh/disposable target first and fail on the first SQL error
|
||||
docker exec -i SnapOtter-postgres \
|
||||
pg_restore --exit-on-error --clean --if-exists --no-owner \
|
||||
-U snapotter -d snapotter < snapotter.dump
|
||||
```
|
||||
|
||||
**Alternativ 2: Volymsnapshot**
|
||||
Denna databasdump innehåller inte sparade biblioteksobjekt i `/data/files` eller hållbart BullMQ-tillstånd i Redis. Säkerhetskopiera och återställ dem med den samordnade proceduren i [Säkerhet och härdning](/sv/guide/security#backup-and-recovery).
|
||||
|
||||
**Önblicksbild av kall volym**
|
||||
|
||||
```bash
|
||||
# Stop the stack, then snapshot the pgdata volume
|
||||
docker compose down
|
||||
docker run --rm -v SnapOtter-pgdata:/data -v $(pwd)/backup:/backup \
|
||||
alpine tar czf /backup/snapotter-pgdata.tar.gz -C /data .
|
||||
# Stop every service first, then use your storage platform to snapshot the
|
||||
# PostgreSQL, app-data, and Redis volumes as one crash-consistent set.
|
||||
docker compose -f docker/docker-compose.yml stop
|
||||
```
|
||||
|
||||
Kopiera inte en live PostgreSQL-datakatalog med `tar`. Komponera prefix volymnamn efter projekt, så lös de monterade volym-ID:n från `docker inspect` eller din lagringsplattform istället för att anta den bokstavliga etiketten `SnapOtter-pgdata`.
|
||||
|
||||
### Migrera från 1.x (SQLite) {#migrating-from-1-x-sqlite}
|
||||
|
||||
Uppgradering från SnapOtter 1.x har sin egen guide: se [Uppgradera från 1.x till 2.0](./upgrading). Kort sagt, återanvänd din befintliga `/data`-volym så upptäcker och importerar 2.0 automatiskt `/data/snapotter.db` vid första uppstarten (eller ställ in `SQLITE_MIGRATE_PATH` för att peka på den explicit). Säkerhetskopiera hela `/data`-volymen först, inte bara `snapotter.db`: 1.x använder SQLite WAL-läge, så en stoppad container lämnar ofta det mesta av sina data i `snapotter.db-wal` bredvid en nästan tom `snapotter.db`.
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
---
|
||||
description: "Distribuera SnapOtter till produktion med Docker. Hårdvarukrav, GPU-konfiguration och konfigurationer för omvänd proxy för Nginx, Traefik och Cloudflare."
|
||||
i18n_output_hash: c280952d9d27
|
||||
i18n_source_hash: 98172965118b
|
||||
i18n_source_hash: 2a722f86da75
|
||||
i18n_provenance: human
|
||||
i18n_output_hash: 9438460845c1
|
||||
i18n_hash_version: 2
|
||||
---
|
||||
|
||||
# Distribution {#deployment}
|
||||
@@ -47,7 +48,7 @@ services:
|
||||
# - MAX_USERS=0 # Max user accounts
|
||||
|
||||
# --- Networking ---
|
||||
# - TRUST_PROXY=true # Trust X-Forwarded-For headers (set false if not behind a proxy)
|
||||
# - TRUST_PROXY=loopback,linklocal,uniquelocal # Which peers may set the client IP via X-Forwarded-For (default shown)
|
||||
|
||||
# --- Bind mount permissions ---
|
||||
# - PUID=1000 # Match your host user's UID (run: id -u)
|
||||
@@ -82,7 +83,7 @@ services:
|
||||
- SnapOtter-pgdata:/var/lib/postgresql/data
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U snapotter"]
|
||||
test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 12
|
||||
@@ -170,13 +171,13 @@ services:
|
||||
container_name: SnapOtter-postgres
|
||||
environment:
|
||||
POSTGRES_USER: snapotter
|
||||
POSTGRES_PASSWORD: snapotter
|
||||
POSTGRES_PASSWORD: snapotter # Ändra detta för icke-lokala distributioner
|
||||
POSTGRES_DB: snapotter
|
||||
volumes:
|
||||
- SnapOtter-pgdata:/var/lib/postgresql/data
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U snapotter"]
|
||||
test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 12
|
||||
@@ -207,13 +208,17 @@ volumes:
|
||||
docker compose -f docker-compose-gpu.yml up -d
|
||||
```
|
||||
|
||||
Kontrollera CUDA-identifiering i loggarna:
|
||||
### Verifiera GPU-acceleration {#verify-gpu-acceleration}
|
||||
|
||||
Kontrollera CUDA-detektering i loggarna:
|
||||
|
||||
```bash
|
||||
docker logs SnapOtter 2>&1 | head -20
|
||||
# Look for: [gpu] CUDA available via torch
|
||||
```
|
||||
|
||||
Om AI-verktyg körs på CPU trots att `--gpus all` och NVIDIA Container Toolkit är korrekt konfigurerade, installera om det berörda paketet (till exempel bakgrundsborttagning) från **Inställningar → AI-funktioner**. Installationsprogrammet återställer GPU-bygget av ONNX Runtime, vilket enbart CPU-bygge som dras in av ett annat paket (som transkription) annars kan skugga i den delade AI-miljön. Om ominstallation från användargränssnittet inte återställer GPU på en äldre bild, se den manuella reparationen i [utgåva #490](https://github.com/snapotter-hq/SnapOtter/issues/490).
|
||||
|
||||
## Hårdvarukrav {#hardware-requirements}
|
||||
|
||||
Dessa siffror kommer från benchmarktester över en rad system, från en modern amd64-arbetsstation med en NVIDIA RTX 4070 ner till en Raspberry Pi, där hela verktygskatalogen kördes på var och en och Docker-resursgränserna svepte över värdena för att hitta det verkliga golvet.
|
||||
@@ -436,11 +441,11 @@ Startfelet namnger det exakta UID:t som ska användas, så den snabbaste vägen
|
||||
| `AUTH_ENABLED` | `true` | Aktivera/inaktivera inloggningskrav |
|
||||
| `DEFAULT_USERNAME` | `admin` | Ursprungligt administratörsanvändarnamn |
|
||||
| `DEFAULT_PASSWORD` | `admin` | Ursprungligt administratörslösenord (tvingad ändring vid första inloggningen) |
|
||||
| `MAX_UPLOAD_SIZE_MB` | `100` | Uppladdningsgräns per fil |
|
||||
| `MAX_BATCH_SIZE` | `100` | Max antal filer per batchförfrågan |
|
||||
| `MAX_UPLOAD_SIZE_MB` | `0` (obegränsat) | Uppladdningsgräns per fil i MB. Avbilden levereras med `0`; ett bygge från källkoden börjar på 100 |
|
||||
| `MAX_BATCH_SIZE` | `0` (obegränsat) | Max antal filer per batchförfrågan. Avbilden levereras med `0`; ett bygge från källkoden börjar på 100 |
|
||||
| `RATE_LIMIT_PER_MIN` | `1000` | API-förfrågningar per minut per IP (ange 0 för att inaktivera) |
|
||||
| `MAX_USERS` | `0` (obegränsat) | Maximalt antal användarkonton |
|
||||
| `TRUST_PROXY` | `true` | Lita på X-Forwarded-For-huvuden från omvänd proxy |
|
||||
| `TRUST_PROXY` | `loopback,linklocal,uniquelocal` | Vilka motparter som får sätta klientens IP via `X-Forwarded-For`. Endast privata nät som standard |
|
||||
| `PUID` | `999` | Kör som detta UID (för bind-monteringsbehörigheter) |
|
||||
| `PGID` | `999` | Kör som detta GID (för bind-monteringsbehörigheter) |
|
||||
| `LOG_LEVEL` | `info` | Loggutförlighet: fatal, error, warn, info, debug, trace |
|
||||
@@ -483,7 +488,13 @@ curl http://localhost:1349/api/v1/health
|
||||
|
||||
## Omvänd proxy {#reverse-proxy}
|
||||
|
||||
SnapOtter anger `TRUST_PROXY=true` som standard så att hastighetsbegränsning och loggning använder den verkliga klient-IP:n från `X-Forwarded-For`-huvuden.
|
||||
`TRUST_PROXY` är som standard `loopback,linklocal,uniquelocal`, så SnapOtter tror på `X-Forwarded-For` bara från en motpart i ett privat nät. En omvänd proxy på samma värd, på ett Docker-nätverk eller i ditt LAN är betrodd direkt, vilket gör att hastighetsbegränsningen, brute force-spärren vid inloggning, granskningsloggen och enterprise-utgåvans IP-tillåtlista alla ser den verkliga klient-IP:n utan någon konfiguration.
|
||||
|
||||
Sätt `TRUST_PROXY=true` bara när proxyn framför når SnapOtter från en **publik** adress, till exempel en molnlastbalanserare i ett annat nät. På en direkt exponerad instans gör det värdet `request.ip` styrbart av en angripare, eftersom den som roterar huvudet får en ny hink för hastighetsbegränsning vid varje förfrågan.
|
||||
|
||||
Två saker är värda att veta innan du börjar mäta klient-IP:n. Docker Desktop på macOS och Windows betjänar en publicerad port via en proxy i användarrymden som skriver om varje källadress till VM-gatewayen `192.168.65.1`, så där återfår inget värde på `TRUST_PROXY` den verkliga klienten; kör allt som vetter mot internet på Linux. Och på alla plattformar ses en publicerad port som nås över `localhost` som bryggans gateway i stället för som din klient, så ett test mot localhost säger ingenting om hur en verklig klient tillskrivs. Hela tabellen över `TRUST_PROXY`-värden och förbehållet om Docker Desktop finns i [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md#client-ip-resolution-trust_proxy).
|
||||
|
||||
Två saker spelar roll för varje proxy nedan: tillåt stora begäranden (uppladdningar) och buffra inte svar. En svarsbuffrande proxy bryter SSE-förloppet och, mer synligt, gör att en stor filnedladdning "startar men slutar aldrig", eftersom proxyn håller hela filen innan den skickas vidare. SnapOtter skickar `X-Accel-Buffering: no` vid nedladdningar så nginx streamar dem även om buffring lämnas på någon annanstans, men andra proxyservrar än nginx behöver explicit inaktivera svarsbuffring (visas i varje konfiguration nedan). Om en nedladdning stannar halvvägs är en buffrande proxy framför det första att kontrollera.
|
||||
|
||||
### Nginx {#nginx}
|
||||
|
||||
@@ -505,7 +516,7 @@ server {
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# SSE support (batch progress, feature install progress)
|
||||
# Strömma svar istället för buffring: behövs för SSE-förlopp (batch, AI, funktionsinstallationer) och för stora filnedladdningar.
|
||||
proxy_buffering off;
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
@@ -549,7 +560,7 @@ images.example.com {
|
||||
}
|
||||
```
|
||||
|
||||
`flush_interval -1` inaktiverar svarsbuffring, vilket krävs för SSE-förloppshändelser (batchbearbetning, AI-verktyg, funktionsinstallationer). De utökade timeouterna gör att stora filuppladdningar kan slutföras utan att Caddy stänger anslutningen för tidigt.
|
||||
`flush_interval -1` inaktiverar svarsbuffring, vilket krävs för SSE-förloppshändelser (batchbearbetning, AI-verktyg, funktionsinstallationer) och för att ladda ner stora filer att strömma igenom istället för att stanna. De utökade tidsgränserna gör att uppladdningar av stora filer kan slutföras utan att Caddy stänger anslutningen i förtid.
|
||||
|
||||
### Cloudflare Tunnels {#cloudflare-tunnels}
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
---
|
||||
description: "Lokal utvecklingskonfiguration, kommandon, kodkonventioner och hur du lägger till ett nytt verktyg i SnapOtter."
|
||||
i18n_source_hash: cb03724d2829
|
||||
i18n_provenance: human
|
||||
i18n_output_hash: cc3f339d18f1
|
||||
i18n_source_hash: 56acc1bf9a9b
|
||||
i18n_provenance: machine
|
||||
i18n_output_hash: e95aa750ab7c
|
||||
i18n_hash_version: 2
|
||||
---
|
||||
|
||||
# Utvecklarguide {#developer-guide}
|
||||
@@ -11,12 +12,12 @@ Så ställer du in en lokal utvecklingsmiljö och bidrar med kod till SnapOtter.
|
||||
|
||||
## Förutsättningar {#prerequisites}
|
||||
|
||||
- [Node.js](https://nodejs.org/) 22+
|
||||
- [Node.js](https://nodejs.org/) 22.22+
|
||||
- [pnpm](https://pnpm.io/) 9+ (`corepack enable && corepack prepare pnpm@latest --activate`)
|
||||
- [Docker](https://www.docker.com/) (krävs för lokal Postgres + Redis, containerbyggen och AI-funktioner)
|
||||
- Git
|
||||
|
||||
Python 3.10+ behövs bara om du arbetar med AI/ML-sidovagnen (bakgrundsborttagning, uppskalning, OCR).
|
||||
Python 3.11+ behövs bara om du arbetar med AI/ML-sidovagnen (bakgrundsborttagning, uppskalning, OCR).
|
||||
|
||||
## Konfiguration {#setup}
|
||||
|
||||
@@ -32,10 +33,10 @@ Detta startar två utvecklingsservrar:
|
||||
|
||||
| Tjänst | URL | Anmärkningar |
|
||||
|----------|--------------------------|------------------------------------|
|
||||
| Frontend | http://localhost:1349 | Vite-utvecklingsserver, proxar /api |
|
||||
| Frontend | http://localhost:1351 | Vite-utvecklingsserver, proxar /api |
|
||||
| Backend | http://localhost:13490 | Fastify API (nås via proxy) |
|
||||
|
||||
Öppna http://localhost:1349 i din webbläsare. Logga in med `admin` / `admin`. Du kommer att uppmanas att byta lösenord vid första inloggningen.
|
||||
Öppna http://localhost:1351 i din webbläsare. Logga in med `admin` / `admin`. Du kommer att uppmanas att byta lösenord vid första inloggningen.
|
||||
|
||||
## Projektstruktur {#project-structure}
|
||||
|
||||
@@ -220,6 +221,17 @@ Använd BuildKit-cache-monteringar för snabbare ombyggen:
|
||||
DOCKER_BUILDKIT=1 docker build -f docker/Dockerfile -t snapotter:latest .
|
||||
```
|
||||
|
||||
## Släpp versionsdomäner {#release-version-domains}
|
||||
|
||||
SnapOtter har avsiktligt tre versionsdomäner. Kopiera inte en domän till en annan under en release:
|
||||
|
||||
- Applikationsversionen täcker rotmanifestet, alla privata arbetsytepaket och `APP_VERSION`. Semantic-release tillhandahåller detta värde, och `pnpm version:sync <version>` uppdaterar varje arbetsyta innan en applikationsrelease.
|
||||
- OpenAPI `info.version` är det stabila offentliga API-stora kontraktet. Alla lokaliserade specifikationer stannar på `<major>.0.0` för kompatibla programversioner och ändras endast när API-kontraktet flyttas till en ny huvudversion.
|
||||
- `docker/feature-manifest.json` behåller `imageVersion: 2.0.0` som den oföränderliga äldre lagringsperioden för funktionspaket. Dessa v2-arkivsökvägar är inte programpaketversioner. Exakt OCR använder runtime-format v3 och registrerar applikationsversionens ursprung separat.
|
||||
|
||||
`tests/unit/infra/release-version-policy.test.ts` upprätthåller dessa gränser. En ny versionsdomän eller migrering måste uppdatera det kontraktet och den relevanta artefaktmigreringsdesignen tillsammans.
|
||||
De oberoende API och äldre paketvärden finns i `config/release-version-policy.json`; Synkronisering av programversion får aldrig skriva om den policyfilen implicit.
|
||||
|
||||
## Miljövariabler {#environment-variables}
|
||||
|
||||
Se [Konfigurationsguiden](/sv/guide/configuration) för den fullständiga listan. Viktiga för utveckling:
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
---
|
||||
description: "SnapOtters Docker-avbildningstaggar, GPU-benchmarks, versionslåsning och stöd för flera plattformar för AMD64 och ARM64."
|
||||
i18n_output_hash: 498e06cec10c
|
||||
i18n_source_hash: fda322e78b4b
|
||||
i18n_source_hash: 566e20ca07fc
|
||||
i18n_provenance: human
|
||||
i18n_output_hash: ce454ce73d46
|
||||
i18n_hash_version: 2
|
||||
---
|
||||
|
||||
# Docker-avbildning {#docker-image}
|
||||
@@ -93,13 +94,13 @@ services:
|
||||
image: postgres:17-alpine
|
||||
environment:
|
||||
POSTGRES_USER: snapotter
|
||||
POSTGRES_PASSWORD: snapotter
|
||||
POSTGRES_PASSWORD: snapotter # Ändra detta för icke-lokala distributioner
|
||||
POSTGRES_DB: snapotter
|
||||
volumes:
|
||||
- SnapOtter-pgdata:/var/lib/postgresql/data
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U snapotter"]
|
||||
test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 12
|
||||
@@ -140,9 +141,9 @@ För NVIDIA CUDA-acceleration via Docker Compose lägger du till deploy-avsnitte
|
||||
| Tagg | Beskrivning |
|
||||
|-----|------------|
|
||||
| `latest` | Senaste utgåvan |
|
||||
| `1.11.0` | Exakt version |
|
||||
| `1.11` | Senaste patch i 1.11.x |
|
||||
| `1` | Senaste minor i 1.x |
|
||||
| `2.1.0` | Exakt version |
|
||||
| `2.1` | Senaste patch i 2.1.x |
|
||||
| `2` | Senaste minor i 2.x |
|
||||
|
||||
## Plattformar {#platforms}
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
---
|
||||
description: "Installera SnapOtter med Docker i ett enda kommando. Inkluderar Docker Compose-konfiguration, byggande från källkod och en fullständig funktionsöversikt."
|
||||
i18n_output_hash: 4b247783a830
|
||||
i18n_source_hash: 68bf7f60b68d
|
||||
i18n_provenance: human
|
||||
i18n_source_hash: 8040133a6982
|
||||
i18n_provenance: machine
|
||||
i18n_output_hash: 2dc08df1543e
|
||||
i18n_hash_version: 2
|
||||
---
|
||||
|
||||
# Kom igång {#getting-started}
|
||||
@@ -17,7 +18,7 @@ Utforska hela gränssnittet på [demo.snapotter.com](https://demo.snapotter.com)
|
||||
docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest
|
||||
```
|
||||
|
||||
Denna enda container kör allt den behöver: utan `DATABASE_URL` angivet startar den sin egen PostgreSQL och Redis på loopback-gränssnittet (inbäddat läge) och håller all data i `SnapOtter-data`-volymen. Det är det snabbaste sättet att prova SnapOtter eller att själv hosta i ett hemmalabb. För produktion, kör [Docker Compose](#docker-compose)-stacken nedan, som håller PostgreSQL och Redis i sina egna containrar. Inbäddat läge körs som root (standardvärdet) och stängs av automatiskt så snart du anger `DATABASE_URL`.
|
||||
Denna enda behållare kör allt den behöver: utan `DATABASE_URL`-uppsättning startar den sin egen PostgreSQL och Redis på loopback-gränssnittet (inbäddat läge) och behåller all data i `SnapOtter-data`-volymen. Det är det snabbaste sättet att prova SnapOtter eller självvärd på ett homelab. För produktion, använd [kanoniska Docker Compose-stacken](#docker-compose), som håller PostgreSQL och Redis i sina egna behållare. Inbäddat läge körs som root (standard) och stängs av automatiskt så snart du ställer in `DATABASE_URL`.
|
||||
|
||||
Installerar du på en Raspberry Pi, en gammal bärbar dator eller en liten VPS? Se [Resurssnåla installationer](/sv/guide/low-resource) för en anpassad genomgång och vad du kan förvänta dig av begränsad hårdvara.
|
||||
|
||||
@@ -40,7 +41,7 @@ Lägg till `--gpus all` för NVIDIA CUDA-accelererad bakgrundsborttagning, uppsk
|
||||
docker run -d --name SnapOtter -p 1349:1349 --gpus all -v SnapOtter-data:/data snapotter/snapotter:latest
|
||||
```
|
||||
|
||||
Kräver [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html). Faller tillbaka till CPU automatiskt när CUDA inte är tillgängligt. Intel/AMD iGPU-acceleration via VA-API, Quick Sync eller OpenCL stöds inte för AI-inferens i dagsläget. Se [Docker-taggar](/sv/guide/docker-tags) för benchmarktester.
|
||||
Kräver [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html). Faller tillbaka till CPU automatiskt när CUDA inte är tillgänglig. Intel/AMD iGPU-acceleration genom VA-API, Quick Sync eller OpenCL stöds inte för AI-inferens idag. Se [Docker Tags](/sv/guide/docker-tags) för riktmärken. Om AI-verktyg körs på CPU trots `--gpus all`, se [Verifiera GPU-acceleration](/sv/guide/deployment#verify-gpu-acceleration).
|
||||
:::
|
||||
|
||||
::: details Även på GHCR
|
||||
@@ -53,65 +54,31 @@ Båda registren publicerar samma avbildning vid varje utgåva.
|
||||
|
||||
## Docker Compose {#docker-compose}
|
||||
|
||||
```yaml
|
||||
services:
|
||||
SnapOtter:
|
||||
image: snapotter/snapotter:latest # or ghcr.io/snapotter-hq/snapotter:latest
|
||||
ports:
|
||||
- "1349:1349"
|
||||
volumes:
|
||||
- SnapOtter-data:/data
|
||||
environment:
|
||||
- AUTH_ENABLED=true
|
||||
- DEFAULT_USERNAME=admin
|
||||
- DEFAULT_PASSWORD=admin
|
||||
- DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter
|
||||
- REDIS_URL=redis://redis:6379
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
Använd produktionsfilen som underhålls och testas med varje release istället för att kopiera ett förkortat Compose-exempel från den här sidan:
|
||||
|
||||
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"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 12
|
||||
```bash
|
||||
install -d -m 700 snapotter && cd snapotter
|
||||
curl --proto '=https' --tlsv1.2 -fsSLo docker-compose.yml \
|
||||
https://raw.githubusercontent.com/snapotter-hq/SnapOtter/v2.1.0/docker/docker-compose.yml
|
||||
|
||||
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
|
||||
# Keep generated service credentials out of shell history and world-readable files.
|
||||
umask 077
|
||||
POSTGRES_PASSWORD="$(openssl rand -hex 32)"
|
||||
REDIS_PASSWORD="$(openssl rand -hex 32)"
|
||||
printf 'POSTGRES_PASSWORD=%s\nREDIS_PASSWORD=%s\n' \
|
||||
"$POSTGRES_PASSWORD" "$REDIS_PASSWORD" > .env
|
||||
|
||||
volumes:
|
||||
SnapOtter-data:
|
||||
SnapOtter-pgdata:
|
||||
SnapOtter-redisdata:
|
||||
docker compose -f docker-compose.yml pull
|
||||
docker compose -f docker-compose.yml up -d --no-build
|
||||
```
|
||||
|
||||
Se [Konfiguration](/sv/guide/configuration) för alla miljövariabler.
|
||||
Den kanoniska [`docker/docker-compose.yml`](https://github.com/snapotter-hq/SnapOtter/blob/v2.1.0/docker/docker-compose.yml) inkluderar alla fyra körtidsvolymer, hälsokontroller, resursgränser, hållbar Redis-konfiguration, fästa databas/cache-bilder och den aktuella behållarhärdningen. Ändra standardlösenordet för administratören direkt efter första inloggningen. För en reproducerbar distribution, fäst SnapOtter-applikationsbilden till releasetaggen eller sammanfattningen du verifierade istället för att följa `latest`.
|
||||
|
||||
Se [Configuration](/sv/guide/configuration) för alla miljövariabler och [Security & Hardening](/sv/guide/security) för hemligheter, nätverkspolicy och säkerhetskopieringsvägledning.
|
||||
|
||||
## Bygg från källkod {#build-from-source}
|
||||
|
||||
**Förutsättningar:** Node.js 22+, pnpm 9+, Docker (för Postgres + Redis), Python 3.10+ (för AI-funktioner), Git.
|
||||
**Förutsättningar:** Node.js 22.22+, pnpm 9+, Docker (för Postgres + Redis), Python 3.11+ (för AI-funktioner), Git.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/snapotter-hq/SnapOtter.git
|
||||
@@ -121,7 +88,7 @@ pnpm install
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
- Frontend: [http://localhost:1349](http://localhost:1349)
|
||||
- Frontend: [http://localhost:1351](http://localhost:1351)
|
||||
- Backend: [http://localhost:13490](http://localhost:13490)
|
||||
|
||||
## Vad du kan göra {#what-you-can-do}
|
||||
@@ -130,11 +97,11 @@ pnpm dev
|
||||
|
||||
| Modalitet | Antal | Exempelverktyg |
|
||||
|----------|-------|---------------|
|
||||
| **Bild** | 105 | Ändra storlek, beskär, komprimera, konvertera, ta bort bakgrund, uppskala, OCR, vattenmärke, collage, färglägg, GIF-verktyg, formatförinställningar |
|
||||
| **Bild** | 107 | Ändra storlek, beskär, komprimera, konvertera, ta bort bakgrund, uppskala, OCR, vattenmärke, collage, färglägg, GIF-verktyg, formatförinställningar |
|
||||
| **Video** | 57 | Klipp, beskär, komprimera, konvertera, slå samman, extrahera ljud, autotextning, video till GIF, ändra storlek, stabilisera, formatförinställningar |
|
||||
| **Ljud** | 27 | Klipp, slå samman, konvertera, normalisera, brusreducering, transkribera, tonhöjdsskift, tona, ringsignalsskapare, formatförinställningar |
|
||||
| **PDF / dokument** | 42 | Slå samman, dela, komprimera, OCR, vattenmärke, redigera bort, Word till PDF, Excel till PDF, rotera, skydda, reparera |
|
||||
| **Filer** | 10 | CSV till JSON, JSON till XML, slå samman CSV-filer, dela CSV, skapa ZIP, extrahera ZIP, diagramskapare, YAML/JSON |
|
||||
| **PDF / dokument** | 29 | Slå samman, dela, komprimera, OCR, vattenmärke, redigera bort, Word till PDF, Excel till PDF, rotera, skydda, reparera |
|
||||
| **Filer** | 23 | CSV till JSON, JSON till XML, slå samman CSV-filer, dela CSV, skapa ZIP, extrahera ZIP, diagramskapare, YAML/JSON |
|
||||
|
||||
### Pipelines {#pipelines}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
---
|
||||
i18n_source_hash: f5de74aee1b9
|
||||
i18n_source_hash: 521c03a6416c
|
||||
i18n_provenance: machine
|
||||
i18n_output_hash: 4ad5655688ed
|
||||
i18n_output_hash: 7bd6ac68fdb5
|
||||
i18n_hash_version: 2
|
||||
---
|
||||
# Resurssnåla installationer {#low-resource-setups}
|
||||
|
||||
@@ -59,7 +60,7 @@ services:
|
||||
image: postgres:17-alpine
|
||||
environment:
|
||||
- POSTGRES_USER=snapotter
|
||||
- POSTGRES_PASSWORD=snapotter
|
||||
- POSTGRES_PASSWORD=snapotter # Ändra detta för icke-lokala distributioner
|
||||
- POSTGRES_DB=snapotter
|
||||
volumes:
|
||||
- ./postgres-data:/var/lib/postgresql/data
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
---
|
||||
description: "Konfigurera SCIM 2.0-provisionering för att synkronisera användare och grupper från din identitetsleverantör till SnapOtter. Täcker Okta, Azure AD / Entra ID och anpassade integrationer."
|
||||
i18n_source_hash: bbd50119ec12
|
||||
i18n_source_hash: 06ee702b386e
|
||||
i18n_provenance: human
|
||||
i18n_output_hash: 17d440079ffa
|
||||
i18n_output_hash: c9b3b79e1946
|
||||
i18n_hash_version: 2
|
||||
---
|
||||
|
||||
# SCIM-provisionering {#scim-provisioning}
|
||||
@@ -17,7 +18,7 @@ SCIM-provisionering kräver en **enterprise**-licens med funktionen `scim`. Den
|
||||
|
||||
- En körande SnapOtter-instans nåbar på en publik URL
|
||||
- En enterprise-licensnyckel med funktionen `scim`
|
||||
- Administratörsåtkomst till SnapOtter (behörigheten `users:manage` krävs för att generera eller återkalla en SCIM-token)
|
||||
- Ett inbyggt SnapOtter `admin`-konto med dess fulla effektiva behörighetsuppsättning. En delegerad anpassad roll eller en admin API-nyckel som saknar administratörsbehörighet kan inte generera eller återkalla den globala SCIM-tokenen.
|
||||
- Administratörsåtkomst till din identitetsleverantörs provisioneringsinställningar
|
||||
|
||||
## Snabbstart {#quick-start}
|
||||
@@ -34,7 +35,7 @@ Svaret innehåller token. Spara den omedelbart; den kan inte hämtas igen.
|
||||
|
||||
```json
|
||||
{
|
||||
"token": "a1b2c3d4e5f6...",
|
||||
"token": "so_scim_v2_a1b2c3d4e5f6...",
|
||||
"message": "Save this token - it cannot be retrieved again"
|
||||
}
|
||||
```
|
||||
@@ -49,15 +50,19 @@ SCIM-slutpunkter använder en dedikerad Bearer-token, separat från användarses
|
||||
|
||||
### Generera en token {#generating-a-token}
|
||||
|
||||
`POST /api/v1/enterprise/scim/token` genererar en ny SCIM-token. Denna slutpunkt kräver en giltig session med behörigheten `users:manage`.
|
||||
`POST /api/v1/enterprise/scim/token` genererar en ny SCIM-token. Eftersom token kan tillhandahålla och mutera användare över instansen, kräver denna slutpunkt den inbyggda `admin`-rollen med den fullständiga effektiva administratörsbehörighetsuppsättningen. Att ha `users:manage` i en anpassad roll är inte tillräckligt.
|
||||
|
||||
Token returneras i klartext exakt en gång. SnapOtter lagrar endast en scrypt-hash. Om du tappar bort token, återkalla den och generera en ny.
|
||||
|
||||
Endast en SCIM-token är aktiv åt gången. Att generera en ny token ersätter den föregående.
|
||||
|
||||
::: warning Återutgivning av token efter uppgradering
|
||||
Äldre oversionerade SCIM-tokens avvisas. Efter att ha uppgraderat till en version som utfärdar `so_scim_v2_...`-tokens, generera en ny token och uppdatera din identitetsleverantör innan du återupptar provisioneringen.
|
||||
:::
|
||||
|
||||
### Återkalla en token {#revoking-a-token}
|
||||
|
||||
`DELETE /api/v1/enterprise/scim/token` återkallar den aktuella SCIM-token. Denna slutpunkt kräver också `users:manage`.
|
||||
`DELETE /api/v1/enterprise/scim/token` återkallar den aktuella SCIM-tokenen. Den har samma fullständiga inbyggda administratörskrav som tokengenerering.
|
||||
|
||||
### Hastighetsbegränsning {#rate-limiting}
|
||||
|
||||
@@ -279,7 +284,7 @@ SCIM-förfrågan inkluderade inte en `Authorization: Bearer <token>`-header. Kon
|
||||
|
||||
### 401 "Invalid token" {#_401-invalid-token}
|
||||
|
||||
Token matchar inte den lagrade hashen. Detta händer om token återkallades och genererades på nytt. Uppdatera token i din IdP:s provisioneringsinställningar.
|
||||
Tokenen är felaktigt formaterad, använder det gamla oversionerade formatet eller matchar inte den lagrade hashen. Generera en aktuell `so_scim_v2_...`-token och uppdatera token i din IdP:s provisioneringsinställningar.
|
||||
|
||||
### 401 "SCIM not configured" {#_401-scim-not-configured}
|
||||
|
||||
|
||||
+90
-162
@@ -1,8 +1,9 @@
|
||||
---
|
||||
description: "Guide för säkerhetshärdning för SnapOtter. Containersäkerhet, nätverksisolering, Docker-hemligheter, Kubernetes-distribution och efterlevnadsartefakter."
|
||||
i18n_source_hash: 986f7658430c
|
||||
i18n_provenance: human
|
||||
i18n_output_hash: a8e16c353a09
|
||||
i18n_source_hash: 9ff337fa0417
|
||||
i18n_provenance: machine
|
||||
i18n_output_hash: 82c030bca91d
|
||||
i18n_hash_version: 2
|
||||
---
|
||||
|
||||
# Säkerhet och härdning {#security-hardening}
|
||||
@@ -11,133 +12,42 @@ SnapOtter bearbetar filer helt och hållet på din infrastruktur. Den skickar an
|
||||
|
||||
Containern körs som en dedikerad icke-root-användare (`snapotter`) med alla Linux-behörigheter borttagna utom den minsta uppsättning som krävs. För den fullständiga policyn för sårbarhetsrapportering och säkerhetsarkitekturen, se [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md) på GitHub.
|
||||
|
||||
## Containerhärdning {#container-hardening}
|
||||
## Behållarhärdning {#container-hardening}
|
||||
|
||||
Den [standardmässiga docker-compose.yml](https://github.com/snapotter-hq/SnapOtter/blob/main/docker/docker-compose.yml) innehåller säkerhetshärdning för produktion. Här är en genomgång av varje alternativ och varför det spelar roll:
|
||||
De kanoniska [CPU](https://github.com/snapotter-hq/SnapOtter/blob/main/docker/docker-compose.yml) och [GPU](https://github.com/snapotter-hq/SnapOtter/blob/main/docker/docker-compose-gpu.yml) Compose-filerna är källan till sanningen. Kopiera inte ett förkortat exempel till produktion; distribuera filen från releasetaggen du verifierade.
|
||||
|
||||
```yaml
|
||||
services:
|
||||
SnapOtter:
|
||||
image: snapotter/snapotter:latest
|
||||
ports:
|
||||
# Bind to localhost only for internet-facing deployments:
|
||||
- "127.0.0.1:1349:1349"
|
||||
volumes:
|
||||
- SnapOtter-data:/data
|
||||
- SnapOtter-workspace:/tmp/workspace
|
||||
environment:
|
||||
- AUTH_ENABLED=true
|
||||
- DEFAULT_PASSWORD=change-me-immediately
|
||||
- RATE_LIMIT_PER_MIN=1000
|
||||
- DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter
|
||||
- REDIS_URL=redis://redis:6379
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
Båda stackarna tillämpar följande kontroller:
|
||||
|
||||
# --- Resource limits ---
|
||||
mem_limit: 6g # Prevents runaway memory from crashing the host
|
||||
memswap_limit: 6g # No swap - fail fast instead of degrading the host
|
||||
cpus: 4 # Cap CPU usage to 4 cores
|
||||
pids_limit: 512 # Prevents fork bombs
|
||||
- Minnes-, swap-, CPU- och PID-gränser innehåller skenande inbyggd bearbetning.
|
||||
- Varje tjänst tar bort alla Linux-funktioner. Applikationen lägger endast till `CHOWN, SETUID, SETGID, DAC_OVERRIDE, FOWNER, KILL` för volymägande, enkelriktad `gosu`-identitetsminskning och graciös signalvidarebefordran. PostgreSQL och Redis får bara den delmängd som deras officiella startpunkter behöver.
|
||||
- `security_opt: [no-new-privileges:true]` förhindrar processer i applikations-, PostgreSQL- och Redis-behållare från att få ytterligare privilegier. Detta förblir kompatibelt med `gosu`: ingångspunkten börjar som root, förbereder volymerna och sjunker endast till den dedikerade `snapotter`-användaren.
|
||||
- PostgreSQL- och Redis-bildingångar fästs av sammanfattning. Applikationen bör på samma sätt fästas till en verifierad release-tagg eller sammanfattning snarare än `latest`.
|
||||
- Hälsokontroller, begränsad JSON-loggrotation, hållbar Redis AOF och omstartspolicy definieras centralt i de kanoniska filerna.
|
||||
|
||||
# --- Capability restrictions ---
|
||||
cap_drop:
|
||||
- ALL # Drop ALL Linux capabilities first
|
||||
cap_add:
|
||||
- CHOWN # Needed for volume permission setup
|
||||
- SETUID # Needed for gosu privilege drop (root -> snapotter)
|
||||
- SETGID # Needed for gosu privilege drop
|
||||
- DAC_OVERRIDE # Needed for volume permission setup
|
||||
- FOWNER # Needed for volume permission setup
|
||||
För en Internet-vänd distribution, bind port 1349 till loopback och avsluta TLS vid en bibehållen omvänd proxy. Skapa unika PostgreSQL- och Redis-uppgifter, lagra hemligheter i skyddade filer eller en hemlighetshanterare och ändra det ursprungliga administratörslösenordet omedelbart.
|
||||
|
||||
# --- Logging ---
|
||||
logging:
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "50m" # Rotate logs at 50 MB
|
||||
max-file: "5" # Keep 5 rotated log files
|
||||
### Varför `read_only` inte är inställd {#why-read-only-is-not-set}
|
||||
|
||||
# --- Health check ---
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-sf", "--max-time", "5", "http://localhost:1349/api/v1/health"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
start_period: 60s
|
||||
retries: 3
|
||||
|
||||
shm_size: "2gb" # Required for Python ML shared memory
|
||||
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"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 12
|
||||
start_period: 15s
|
||||
|
||||
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
|
||||
start_period: 10s
|
||||
|
||||
volumes:
|
||||
SnapOtter-data:
|
||||
SnapOtter-workspace:
|
||||
SnapOtter-pgdata:
|
||||
SnapOtter-redisdata:
|
||||
```
|
||||
|
||||
### Varför `no-new-privileges` inte är angivet {#why-no-new-privileges-is-not-set}
|
||||
|
||||
`security_opt: [no-new-privileges:true]` utelämnas avsiktligt. Startpunkten startar som root för att korrigera volymägarskap och släpper sedan till `snapotter`-användaren via [gosu](https://github.com/tianon/gosu), vilket kräver setuid. När privilegiesläppet är klart körs processen som `snapotter` med alla behörigheter utom de fem som listas ovan borttagna.
|
||||
|
||||
Om du använder Kubernetes eller Dockers `--user`-flagga för att köra som icke-root direkt (och kringgå gosu) är `no-new-privileges` säkert att aktivera.
|
||||
|
||||
### Varför `read_only` inte är angivet {#why-read-only-is-not-set}
|
||||
|
||||
`read_only: true` är inte angivet eftersom PUID/PGID-ommappning skriver till `/etc/passwd` och `/etc/group` vid start. Om du använder Dockers `--user`-flagga eller Kubernetes `runAsUser` i stället för PUID/PGID kan du tryggt aktivera ett skrivskyddat rot-filsystem.
|
||||
`read_only: true` är inte inställt eftersom PUID/PGID-ommappning skriver till `/etc/passwd` och `/etc/group` vid start. Om du använder Dockers `--user`-flagga eller Kubernetes `runAsUser` istället för PUID/PGID, kan du säkert aktivera ett skrivskyddat rotfilsystem.
|
||||
|
||||
## Nätverksisolering {#network-isolation}
|
||||
|
||||
Under normal drift gör containern **noll utgående nätverksanslutningar**. All filbearbetning sker lokalt med hjälp av medföljande bibliotek.
|
||||
Filbehandlingen är lokal, men en standardinstallation är **inte ett utgångsfritt system**. Anonym produktanalys använder PostHog och kraschrapportering använder Sentry när telemetri är aktiverat. Ställ in `SNAPOTTER_TELEMETRY=0` (eller inaktivera analys under Inställningar > System > Sekretess) för att stänga av båda. SnapOtter inkluderar aldrig uppladdade filer, filnamn, OCR-utdata, dokumenttext eller annat filinnehåll i dessa händelser.
|
||||
|
||||
```
|
||||
Browser --> Reverse Proxy (TLS) --> SnapOtter container --> (nothing)
|
||||
```
|
||||
Annan utgående trafik är funktionsdriven: AI-paket/modellinstallation laddar ner signerade release-ingångar; URL-import hämtar en användarbegärd offentlig URL; och explicit konfigurerade OIDC, SAML, OpenTelemetry, webhooks, S3-kompatibel lagring eller liknande integrationer kontaktar de destinationer som administratören valt. Modellnedladdningar under körning är inaktiverade som standard. Ange `SNAPOTTER_ALLOW_MODEL_DOWNLOAD=1` endast för att uttryckligen aktivera automatiska reservnedladdningar. En [offline-paketimport](/sv/guide/deployment) kan tillhandahålla AI-funktioner utan körtidsmodellutgång.
|
||||
|
||||
Det enda undantaget är **AI-modellnedladdningar**: när en användare installerar en AI-funktionsbunt via gränssnittet laddar containern ner det förbyggda buntarkivet från Hugging Face, plus några enskilda modellfiler från GitHub Releases, Google Storage och PyPI. Dessa nedladdningar sker en gång per bunt och lagras i `/data`-volymen.
|
||||
**Brandväggsrekommendationer:**
|
||||
|
||||
**Rekommendationer för brandvägg:**
|
||||
|
||||
| Scenario | Utgående regel |
|
||||
|Scenario|Utgående regel|
|
||||
|---|---|
|
||||
| Luftgapad (ingen AI) | Blockera all utgående trafik från containern |
|
||||
| AI-buntar behövs | Tillåt HTTPS till `huggingface.co`, `*.xethub.hf.co`, `cdn-lfs.huggingface.co`, `github.com`, `objects.githubusercontent.com`, `storage.googleapis.com`, `pypi.org`, `files.pythonhosted.org` under installation, blockera sedan |
|
||||
| Efter AI-installation | Blockera all utgående trafik - modeller cachas lokalt |
|
||||
|Luftgap|Ställ in `SNAPOTTER_TELEMETRY=0` och `SNAPOTTER_ALLOW_MODEL_DOWNLOAD=0`, använd offline AI-paketimport, inaktivera URL-import och externa integrationer, blockera sedan utgående|
|
||||
|Standard telemetri|Tillåt PostHog- och Sentry-slutpunkterna listade av din webbläsare/nätverksloggar; inaktivera telemetri om policyn inte tillåter dem|
|
||||
|AI-buntar behövs|Under installationen, tillåt HTTPS till `huggingface.co, *.xethub.hf.co, cdn-lfs.huggingface.co, github.com, objects.githubusercontent.com, storage.googleapis.com, pypi.org, files.pythonhosted.org`; blockera sedan dessa värdar|
|
||||
|Externa integrationer|Tillåt endast de exakt administratörskonfigurerade OIDC/SAML/OTLP/webhook/object-storage-destinationerna|
|
||||
|
||||
Buntarkiv serveras från Hugging Faces Xet-lagring, som överför via `*.xethub.hf.co`-slutpunkterna parallellt och är det som gör nedladdningar av buntar på flera GB snabba. Om din brandvägg tillåter `huggingface.co` men blockerar `*.xethub.hf.co` lyckas installationer fortfarande men faller tillbaka till en långsammare enkelströmsnedladdning, så tillåtelselista Xet-värdarna för att stanna på den snabba vägen. Helt offline-installationer kan hoppa över allt detta och använda [Offline-buntimport](/sv/guide/deployment) i stället.
|
||||
Bundle-arkiv serveras från Hugging Faces Xet-lagring, som överförs över `*.xethub.hf.co`-ändpunkterna parallellt och är det som gör nedladdningar av multi-GB-buntar snabba. Om din brandvägg tillåter `huggingface.co` men blockerar `*.xethub.hf.co`, kommer installationerna fortfarande att lyckas men faller tillbaka till en långsammare enkelströmsnedladdning, så godkännandelista Xet-värdarna för att hålla sig på den snabba vägen. Helt offlineinstallationer kan hoppa över allt detta och använda [Offline Bundle Import](/sv/guide/deployment) istället.
|
||||
|
||||
För konfiguration av omvänd proxy (Nginx, Traefik, Caddy, Cloudflare Tunnels), se [Distributionsguiden](/sv/guide/deployment#reverse-proxy).
|
||||
För omvänd proxykonfiguration (Nginx, Traefik, Caddy, Cloudflare Tunnels), se [Deployment guide](/sv/guide/deployment#reverse-proxy).
|
||||
|
||||
## Docker-hemligheter {#docker-secrets}
|
||||
|
||||
@@ -257,83 +167,101 @@ För resursdimensionering, se [Hårdvarukrav](/sv/guide/deployment#hardware-requ
|
||||
|
||||
## Säkerhetskopiering och återställning {#backup-and-recovery}
|
||||
|
||||
Beständigt tillstånd är uppdelat på två volymer:
|
||||
Produktionsstacken Compose definierar fyra volymer. Stoppa ingressen och låt aktiva jobb avslutas innan du tar en koordinerad säkerhetskopia så att PostgreSQL, Redis och filtillstånd beskriver samma tidpunkt.
|
||||
|
||||
| Volym | Innehåll | Kritisk? |
|
||||
|Volym|Innehåll|Återhämtningsbehandling|
|
||||
|---|---|---|
|
||||
| `SnapOtter-pgdata` | PostgreSQL-databas (användare, inställningar, pipelines, jobb, granskningslogg) | Ja |
|
||||
| `/data` (appvolym) | Användaruppladdade filer, AI-modeller, Python-venv | Delvis (se nedan) |
|
||||
|`SnapOtter-pgdata`|PostgreSQL-användare, inställningar, pipelines, jobb, filmetadata och granskningslogg|Kritisk; använd en felsnabb logisk dump för bärbar återställning|
|
||||
|`SnapOtter-data`|Sparade biblioteksobjekt, loggar och AI-tillstånd (`/data/files, /data/logs, /data/ai, /data/ai/venv`)|Säkerhetskopiera hela volymen; för att spara utrymme, utelämna medvetet alla AI-tillstånd och installera om dess buntar|
|
||||
|`SnapOtter-redisdata`|Redis AOF för hållbart BullMQ-kötillstånd|Säkerhetskopiera efter att ha pausat appen och tvingat `SAVE`; krävs för att återuppta köarbete exakt|
|
||||
|`SnapOtter-workspace`|Tillfälliga objektlagringsnycklar (`/tmp/workspace/uploads, /tmp/workspace/outputs`)|Säkerhetskopiera inte efter att alla jobb har tömts eller avbrutits; kassera den aldrig medan jobben är aktiva|
|
||||
|
||||
Inom `/data`-volymen:
|
||||
|
||||
| Sökväg | Innehåll | Kritisk? |
|
||||
|---|---|---|
|
||||
| `/data/uploads/`, `/data/outputs/` | Användarfiler och bearbetningsresultat | Ja |
|
||||
| `/data/ai/` | Nedladdade AI-modellfiler | Nej (kan laddas ner igen) |
|
||||
| `/data/venv/` | Python virtuell miljö | Nej (byggs om vid start) |
|
||||
Compose prefix normalt volymnamn med projektnamnet. Lös upp den verkliga källvolymen från den monterade behållaren istället för att anta att ett visningsnamn som `SnapOtter-data` är Docker-volymens namn.
|
||||
|
||||
### Databassäkerhetskopiering {#database-backup}
|
||||
|
||||
Använd `pg_dump` för att säkerhetskopiera databasen medan stacken körs:
|
||||
Använd PostgreSQL:s anpassade arkivformat och verifiera arkivet innan du behandlar säkerhetskopieringen som komplett:
|
||||
|
||||
```bash
|
||||
# Dump the database
|
||||
docker exec SnapOtter-postgres pg_dump -U snapotter snapotter > backup.sql
|
||||
docker exec SnapOtter-postgres \
|
||||
pg_dump --format=custom --no-owner -U snapotter snapotter > snapotter.dump
|
||||
test -s snapotter.dump
|
||||
docker exec -i SnapOtter-postgres pg_restore --list < snapotter.dump >/dev/null
|
||||
|
||||
# Restore into a fresh database
|
||||
cat backup.sql | docker exec -i SnapOtter-postgres psql -U snapotter snapotter
|
||||
# Restore only into a fresh/disposable target first; any SQL error fails the command.
|
||||
docker exec -i SnapOtter-postgres \
|
||||
pg_restore --exit-on-error --clean --if-exists --no-owner \
|
||||
-U snapotter -d snapotter < snapotter.dump
|
||||
```
|
||||
|
||||
Alternativt, stoppa stacken och ta en ögonblicksbild av `SnapOtter-pgdata`-volymen:
|
||||
Testa varje säkerhetskopia genom att återställa den till en isolerad stack, kontrollera databasposter och filkontrollsummor och starta programmet. Förvarets `tests/qa/backup-restore-drill.sh` automatiserar den frigöringsgrinden mot en explicit `QA_IMAGE`.
|
||||
|
||||
Om din plattform tar kraschkonsistenta volymögonblicksbilder istället, stoppa först hela stacken och ta ögonblicksbilder av alla kritiska volymer som en uppsättning. En rå PostgreSQL-datakatalogkopia från en körande behållare är inte en logisk säkerhetskopia som stöds.
|
||||
|
||||
### Säkerhetskopiering av fil och kö {#file-and-queue-backup}
|
||||
|
||||
Pausa programmet innan du registrerar fil- och kövolymer. Använd `docker inspect` för att lösa det faktiska volymnamnet, tvinga Redis att bevara sitt nuvarande tillstånd och arkivera med äganderätt och behörigheter bevarade:
|
||||
|
||||
```bash
|
||||
docker compose down
|
||||
docker run --rm -v SnapOtter-pgdata:/data -v $(pwd)/backup:/backup \
|
||||
alpine tar czf /backup/snapotter-pgdata.tar.gz -C /data .
|
||||
docker stop SnapOtter
|
||||
docker exec SnapOtter-redis redis-cli -a "$REDIS_PASSWORD" --no-auth-warning SAVE
|
||||
docker stop SnapOtter-redis
|
||||
|
||||
DATA_VOLUME="$(docker inspect SnapOtter --format '{{range .Mounts}}{{if eq .Destination "/data"}}{{.Name}}{{end}}{{end}}')"
|
||||
REDIS_VOLUME="$(docker inspect SnapOtter-redis --format '{{range .Mounts}}{{if eq .Destination "/data"}}{{.Name}}{{end}}{{end}}')"
|
||||
|
||||
install -d -m 700 backup
|
||||
docker run --rm -v "$DATA_VOLUME:/source:ro" -v "$PWD/backup:/backup" \
|
||||
alpine:3.22@sha256:14358309a308569c32bdc37e2e0e9694be33a9d99e68afb0f5ff33cc1f695dce tar czf /backup/snapotter-data.tar.gz -C /source .
|
||||
docker run --rm -v "$REDIS_VOLUME:/source:ro" -v "$PWD/backup:/backup" \
|
||||
alpine:3.22@sha256:14358309a308569c32bdc37e2e0e9694be33a9d99e68afb0f5ff33cc1f695dce tar czf /backup/snapotter-redis.tar.gz -C /source .
|
||||
sha256sum backup/snapotter-*.tar.gz > backup/SHA256SUMS
|
||||
```
|
||||
|
||||
### Säkerhetskopiering av användarfiler {#user-files-backup}
|
||||
|
||||
```bash
|
||||
# Snapshot the app data volume (excluding re-downloadable AI models)
|
||||
docker run --rm -v SnapOtter-data:/data -v $(pwd)/backup:/backup \
|
||||
alpine tar czf /backup/snapotter-files.tar.gz \
|
||||
--exclude='ai' --exclude='venv' -C /data .
|
||||
```
|
||||
|
||||
AI-modeller uppgår till ungefär 24 GB totalt över alla buntar. Eftersom de kan laddas ner igen, exkludera `/data/ai/` och `/data/venv/` från säkerhetskopior för att spara utrymme. Endast databasen och användarfilerna är kritiska.
|
||||
Starta om Redis före applikationen. Om du avsiktligt utesluter `/data/ai`, ta bort hela AI-underträdet istället för att bevara en `installed.json`-post utan dess modeller eller virtuell miljö. Håll säkerhetskopieringsfiler krypterade, åtkomstkontrollerade och åtskilda från värden som kör SnapOtter.
|
||||
|
||||
## Efterlevnadsartefakter {#compliance-artifacts}
|
||||
|
||||
Varje SnapOtter-utgåva innehåller följande säkerhetsartefakter:
|
||||
Varje SnapOtter-version innehåller följande säkerhetsartefakter:
|
||||
|
||||
| Artefakt | Format | Var du hittar den |
|
||||
| Artefakt | Formatera | Var man hittar den |
|
||||
|---|---|---|
|
||||
| SBOM (CycloneDX) | JSON | [GitHub Release](https://github.com/snapotter-hq/SnapOtter/releases)-tillgång: `snapotter-v{version}-sbom.cdx.json` |
|
||||
| SBOM (SPDX) | JSON | [GitHub Release](https://github.com/snapotter-hq/SnapOtter/releases)-tillgång: `snapotter-v{version}-sbom.spdx.json` |
|
||||
| Sårbarhetsskanning | Trivy JSON | [GitHub Release](https://github.com/snapotter-hq/SnapOtter/releases)-tillgång: `snapotter-v{version}-trivy.json` |
|
||||
| Sårbarhetsskanning | SARIF | [GitHub Security](https://github.com/snapotter-hq/SnapOtter/security)-fliken |
|
||||
| Statisk analys | CodeQL (JS/TS + Python) | [GitHub Security](https://github.com/snapotter-hq/SnapOtter/security)-fliken, körs varje vecka + per PR |
|
||||
| Beroendegranskning | GitHub-inbyggd | Kontroll per PR, misslyckas vid tillägg med hög allvarlighetsgrad |
|
||||
| Granskning av Python-beroenden | pip-audit | CI-körningslogg vid varje push |
|
||||
| Släpp ämnesbindning | Canonical JSON + GitHub intyg | [GitHub Release](https://github.com/snapotter-hq/SnapOtter/releases) tillgång: `snapotter-v{version}-release-subjects.json` |
|
||||
| Arkiv SBOM | CycloneDX och SPDX JSON | Frisläppande tillgångar: `snapotter-v{version}-archive-linux-{arch}-sbom.{cdx,spdx}.json` |
|
||||
| Bild SBOM | CycloneDX och SPDX JSON | Frisläppande tillgångar: `snapotter-v{version}-image-linux-{arch}-sbom.{cdx,spdx}.json` |
|
||||
| Sårbarhetsskanningar | Trivy JSON | Släpp tillgångar med matchande `archive-linux-{arch}`- eller `image-linux-{arch}`-prefix |
|
||||
| Sårbarhetsskanning | SARIF | Fliken [GitHub Security](https://github.com/snapotter-hq/SnapOtter/security). |
|
||||
| Statisk analys | CodeQL (JS/TS + Python) | Fliken [GitHub Security](https://github.com/snapotter-hq/SnapOtter/security), körs varje vecka + per PR |
|
||||
| Beroendegranskning | GitHub infödd | Per-PR-kontroll, misslyckas vid tillägg med hög stränghet |
|
||||
| Python beroende granskning | pip-audit | CI kör logga på varje tryck |
|
||||
| Säkerhetspolicy | Markdown | [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md) i arkivet |
|
||||
| Beroendeuppdateringar | Dependabot | Automatiserade veckovisa PR:er för npm, pip, Docker, Actions |
|
||||
| Beroendeuppdateringar | Dependabot | Automatiserade veckovisa PR för npm, pip, Docker, Actions |
|
||||
|
||||
**Köra din egen skanning:**
|
||||
**Kör din egen skanning:**
|
||||
|
||||
Ladda ner SBOM:en från utgåvan och skanna den med ditt föredragna verktyg:
|
||||
Ladda ned release-subject-manifestet och verifiera att det intygades av release-arbetsflödet:
|
||||
|
||||
```bash
|
||||
gh attestation verify snapotter-v2.1.0-release-subjects.json \
|
||||
--repo snapotter-hq/SnapOtter \
|
||||
--signer-workflow snapotter-hq/SnapOtter/.github/workflows/release.yml
|
||||
```
|
||||
|
||||
Manifestet registrerar `releaseTag`, `releaseCommit` och `workflowTriggerCommit` separat. Verifiera att `releaseCommit` är commit som tas bort från den oföränderliga taggen, verifiera sedan SHA-256-sammandraget av arkivet, bilden, SBOM eller skanningen som du konsumerar mot dess post i `subjects`. Denna distinktion är avsiktlig: att checka ut en nyskapad release-commit ändrar inte commit-identiteten i arbetsflödets OIDC-referens.
|
||||
|
||||
Du kan också skanna en nedladdad SBOM eller bilden direkt:
|
||||
|
||||
```bash
|
||||
# Scan with Grype using the CycloneDX SBOM
|
||||
grype sbom:snapotter-v1.17.2-sbom.cdx.json
|
||||
grype sbom:snapotter-v2.1.0-image-linux-amd64-sbom.cdx.json
|
||||
|
||||
# Scan with Trivy using the SPDX SBOM
|
||||
trivy sbom snapotter-v1.17.2-sbom.spdx.json
|
||||
trivy sbom snapotter-v2.1.0-image-linux-amd64-sbom.spdx.json
|
||||
|
||||
# Scan the Docker image directly
|
||||
trivy image snapotter/snapotter:1.17.2
|
||||
trivy image snapotter/snapotter:2.1.0
|
||||
```
|
||||
|
||||
::: info
|
||||
SBOM:en och sårbarhetsskanningen återspeglar den exakta avbildning som publicerats för den utgåvan. AI-modellbuntar som installeras efter distributionen ingår inte i SBOM:en eftersom de laddas ner vid körning.
|
||||
::: info
|
||||
Bild SBOMs och skanningar återspeglar den exakta arkitekturspecifika bilden som publicerats för den versionen. Arkiv SBOMs och skanningar beskriver det förbyggda arkivet separat. AI-modellpaket som installerats efter distribution ingår inte i dessa SBOMs eftersom de laddas ner under körning.
|
||||
:::
|
||||
|
||||
@@ -11,7 +11,7 @@ SnapOtter bearbetar filer över fem modaliteter: bild, video, ljud, PDF och file
|
||||
|
||||
## Bildformat {#image-formats}
|
||||
|
||||
SnapOtter stöder 55+ bildformat för inmatning och 13 format för utmatning.
|
||||
SnapOtter stöder 55+ bildformat för inmatning och 17 format för utmatning.
|
||||
|
||||
## Inmatningsformat {#input-formats}
|
||||
|
||||
@@ -104,7 +104,7 @@ SnapOtter stöder 55+ bildformat för inmatning och 13 format för utmatning.
|
||||
| PAM | .pam | Sharp (native) | Godtycklig karta |
|
||||
| PFM | .pfm | Sharp (native) | Float-karta |
|
||||
|
||||
## Utmatningsformat (13) {#output-formats-13}
|
||||
## Utmatningsformat (17) {#output-formats-13}
|
||||
|
||||
| Format | Kodare | Kvalitetskontroll | Tillgängligt i |
|
||||
|--------|---------|----------------|-------------|
|
||||
@@ -121,6 +121,10 @@ SnapOtter stöder 55+ bildformat för inmatning och 13 format för utmatning.
|
||||
| ICO | ImageMagick CLI | Förlustfri | Konverteringsverktyg |
|
||||
| JP2 | opj_compress CLI | Komprimeringsförhållande | Konverteringsverktyg |
|
||||
| QOI | Inbyggd codec | Förlustfri | Konverteringsverktyg |
|
||||
| PSD | ImageMagick CLI | Förlustfri | Konverteringsverktyg |
|
||||
| PPM | ImageMagick CLI | Förlustfri | Konverteringsverktyg |
|
||||
| EPS | ImageMagick CLI | Förlustfri | Konverteringsverktyg |
|
||||
| TGA | ImageMagick CLI | Förlustfri | Konverteringsverktyg |
|
||||
|
||||
## Videoformat {#video-formats}
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
---
|
||||
description: "Hantera användare, inbyggda och anpassade roller, behörigheter, API-nycklar, team, sessioner och granskningsloggen i SnapOtter."
|
||||
i18n_source_hash: 5e28af686c96
|
||||
i18n_source_hash: bea8955f3aff
|
||||
i18n_provenance: human
|
||||
i18n_output_hash: ce4e3c6f3ee8
|
||||
i18n_output_hash: 9af24cfc9c89
|
||||
i18n_hash_version: 2
|
||||
---
|
||||
|
||||
# Användare, roller och behörigheter {#users-roles-permissions}
|
||||
@@ -82,12 +83,12 @@ Alla 17 behörigheter. Full kontroll över instansen.
|
||||
| `pipelines:all` | Visa och hantera alla användares pipelines |
|
||||
| `settings:read` | Visa instansinställningar |
|
||||
| `settings:write` | Ändra instansinställningar |
|
||||
| `users:manage` | Skapa, uppdatera och radera användarkonton |
|
||||
| `users:manage` | Skapa och hantera användarkonton inom aktörens behörighetsgräns |
|
||||
| `teams:manage` | Skapa, uppdatera och radera team |
|
||||
| `features:manage` | Installera och hantera AI-funktionsbuntar |
|
||||
| `system:health` | Åtkomst till health- och readiness-slutpunkter |
|
||||
| `audit:read` | Visa granskningsloggen och lista roller |
|
||||
| `compliance:manage` | Hantera GDPR-livscykel och efterlevnadsfunktioner |
|
||||
| `compliance:manage` | Hantera GDPR-livscykel- och efterlevnadsfunktioner; destruktiva användaroperationer förblir auktoritetsbundna |
|
||||
| `webhooks:manage` | Konfigurera utgående webhooks |
|
||||
| `security:manage` | Hantera säkerhetsinställningar (IP-tillåtelselista, SSO-tvingande) |
|
||||
|
||||
@@ -110,15 +111,17 @@ curl -X POST http://localhost:1349/api/v1/roles \
|
||||
|
||||
Rollnamn måste vara 2-30 tecken, gemena alfanumeriska med bindestreck och understreck.
|
||||
|
||||
### Administratörsreserverade behörigheter {#admin-reserved-permissions}
|
||||
### Delegerade administrationsgränser {#delegated-administration-boundaries}
|
||||
|
||||
Tre behörigheter är reserverade för inbyggda roller och kan inte tilldelas anpassade roller:
|
||||
Alla 17 behörigheter kan delegeras genom anpassade roller, men en administrativ behörighet gör inte den rollen likvärdig med den inbyggda `admin`-rollen. Användarmutationer godkända av `users:manage`, destruktiva operationer godkända av `compliance:manage` och anpassade rollhantering auktoriserad av `security:manage` begränsas av skådespelarens nuvarande auktoritet:
|
||||
|
||||
- `compliance:manage`
|
||||
- `webhooks:manage`
|
||||
- `security:manage`
|
||||
- Inbyggda roller följer `admin` > `editor` > `user`; anpassade roller är under inbyggda roller.
|
||||
- Målets behörigheter måste innehållas av skådespelarens **effektiva** behörigheter. En scoped API-nyckel kan därför inte utöva behörigheter som utelämnas från dess scope.
|
||||
- En målrolls verktygsåtkomst ska innehållas av aktörens egen verktygsåtkomst.
|
||||
- Ett inaktiverat konto kontrolleras mot sin ursprungliga roll när den rollen registreras som `disabled:<original-role>`.
|
||||
- Att ta bort en anpassad roll kräver också behörighet att tilldela den inbyggda `user` reserv; funktionshindrade medlemmar förblir inaktiverade som `disabled:user`.
|
||||
|
||||
roles-API:et avvisar varje förfrågan som inkluderar dessa behörigheter. Endast den inbyggda `admin`-rollen har åtkomst till dem.
|
||||
Globala autentiseringsuppgifter och konfiguration är strängare: utfärdande eller återkallande av SCIM-token och import av instanskonfiguration kräver den inbyggda `admin`-rollen med fullständig effektiv administratörsbehörighet.
|
||||
|
||||
### Behörigheter på verktygsnivå {#tool-level-permissions}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user