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:
SnapOtter
2026-07-27 15:37:30 +08:00
committed by GitHub
parent bc32f86a07
commit d10d0f544f
855 changed files with 54564 additions and 13092 deletions
+9 -5
View File
@@ -27,9 +27,11 @@ curl -X POST http://localhost:1349/api/auth/login \
-d '{"username":"admin","password":"admin"}'
# Returns: {"token":"<session-token>"}
# Use token
curl http://localhost:1349/api/v1/tools/image/resize \
-H "Authorization: Bearer <session-token>"
# Use token (tool routes are POST multipart)
curl -X POST http://localhost:1349/api/v1/tools/image/resize \
-H "Authorization: Bearer <session-token>" \
-F "file=@photo.jpg" \
-F 'settings={"width":800}'
```
सेशन 7 दिनों के बाद समाप्त हो जाते हैं (`SESSION_DURATION_HOURS` के माध्यम से कॉन्फ़िगर करने योग्य)।
@@ -45,8 +47,10 @@ curl -X POST http://localhost:1349/api/v1/api-keys \
# Returns: {"key":"si_<96 hex chars>","id":"...","name":"my-script"}
# Use the key
curl http://localhost:1349/api/v1/tools/image/resize \
-H "Authorization: Bearer si_<your-key>"
curl -X POST http://localhost:1349/api/v1/tools/image/resize \
-H "Authorization: Bearer si_<your-key>" \
-F "file=@photo.jpg" \
-F 'settings={"width":800}'
```
कीज़ के आगे `si_` उपसर्ग लगा होता है और उन्हें scrypt हैश के रूप में संग्रहीत किया जाता है - कच्ची की एक बार दिखाई जाती है और फिर कभी पुनः प्राप्त नहीं की जा सकती।
+4 -3
View File
@@ -1,8 +1,9 @@
---
description: "SnapOtter की मोनोरेपो संरचना, ऐप और पैकेज आर्किटेक्चर, अनुरोध जीवनचक्र, और संसाधन फ़ुटप्रिंट।"
i18n_output_hash: c218fe161fec
i18n_source_hash: a53946e760b0
i18n_source_hash: 50e076925c4b
i18n_provenance: human
i18n_output_hash: a96e8ad45f9d
i18n_hash_version: 2
---
# Architecture {#architecture}
@@ -52,7 +53,7 @@ Python स्क्रिप्ट `packages/ai/python/` में रहती
### API (`apps/api`) {#api-apps-api}
एक Fastify v5 सर्वर जो पाँच मोडैलिटी (image, video, audio, PDF, file) में 241 टूल रूट प्रकट करता है, जो निम्न को संभालता है:
एक Fastify v5 सर्वर जो पाँच मोडैलिटी (image, video, audio, PDF, file) में 243 टूल रूट प्रकट करता है, जो निम्न को संभालता है:
- फ़ाइल अपलोड, अस्थायी वर्कस्पेस प्रबंधन, और स्थायी फ़ाइल स्टोरेज
- उपयोगकर्ता फ़ाइल लाइब्रेरी (`user_files` तालिका): सहेजा गया संपादन डिफ़ॉल्ट रूप से एक स्वतंत्र नई फ़ाइल के रूप में संग्रहीत होता है, या जब आप मूल को अधिलेखित करते हैं तो एक पैरेंट-लिंक्ड संस्करण के रूप में। यह रिकॉर्ड करता है कि कौन-से टूल लागू किए गए थे (`toolChain`) और Files पेज के लिए स्वतः-जनरेट किया गया थंबनेल प्राप्त करता है
- टूल निष्पादन (प्रत्येक टूल अनुरोध को इमेज इंजन या AI ब्रिज पर रूट करता है)
+40 -17
View File
@@ -1,8 +1,9 @@
---
description: "सभी SnapOtter एनवायरनमेंट वेरिएबल्स डिफ़ॉल्ट के साथ। auth, स्टोरेज, AI मॉडल, एनालिटिक्स, और अधिक कॉन्फ़िगर करें।"
i18n_source_hash: 8e9e9ca2840c
i18n_source_hash: 25970c776f7c
i18n_provenance: human
i18n_output_hash: 6de48963490c
i18n_output_hash: d47e121c7d0f
i18n_hash_version: 2
---
# Configuration {#configuration}
@@ -19,28 +20,51 @@ i18n_output_hash: 6de48963490c
| `RATE_LIMIT_PER_MIN` | `1000` | प्रति IP प्रति मिनट अधिकतम अनुरोध। रेट लिमिटिंग अक्षम करने के लिए 0 पर सेट करें। |
| `CORS_ORIGIN` | (empty) | CORS के लिए अल्पविराम-पृथक अनुमत मूल, या केवल-समान-मूल के लिए खाली। |
| `LOG_LEVEL` | `info` | लॉग वर्बोसिटी। इनमें से एक: `fatal`, `error`, `warn`, `info`, `debug`, `trace`। |
| `TRUST_PROXY` | `true` | एक रिवर्स प्रॉक्सी से `X-Forwarded-For` हेडर पर भरोसा करें। यदि प्रॉक्सी के पीछे नहीं है तो `false` पर सेट करें। |
| `TRUST_PROXY` | `loopback,linklocal,uniquelocal` | `X-Forwarded-For` के ज़रिए क्लाइंट IP कौन से पीयर सेट कर सकते हैं। डिफ़ॉल्ट केवल किसी निजी नेटवर्क के पीयर पर भरोसा करता है, इसलिए Docker नेटवर्क या LAN पर मौजूद रिवर्स प्रॉक्सी भरोसेमंद माना जाता है, जबकि किसी सार्वजनिक क्लाइंट का जाली हेडर नहीं। `true` तभी सेट करें जब आपके नियंत्रण वाला कोई प्रॉक्सी सार्वजनिक पते पर आगे लगा हो। |
### Authentication {#authentication}
नीचे दिए गए दोनों बूलियन केवल `true` और `false` स्वीकार करते हैं। इसके अलावा कुछ और, जैसे `1` या `yes` या `on`, सत्यापन में विफल हो जाता है और सर्वर सुनना शुरू करने से पहले ही बाहर निकल जाता है।
| Variable | Default | Description |
|---|---|---|
| `AUTH_ENABLED` | `false` | लॉगिन की आवश्यकता के लिए `true` पर सेट करें। Docker इमेज `true` पर डिफ़ॉल्ट होती है। |
| `AUTH_ENABLED` | `true` | लॉगिन अनिवार्य करें। बिना किसी अकाउंट के चलाने के लिए `false` पर सेट करें, जो हर अनुरोध को admin अधिकार देता है, इसलिए इसे किसी भरोसेमंद नेटवर्क तक ही सीमित रखें। |
| `DEFAULT_USERNAME` | `admin` | प्रारंभिक admin अकाउंट के लिए उपयोगकर्ता नाम। केवल पहली बार चलने पर उपयोग किया जाता है। |
| `DEFAULT_PASSWORD` | `admin` | प्रारंभिक admin अकाउंट के लिए पासवर्ड। पहली बार लॉगिन के बाद इसे बदलें। |
| `MAX_USERS` | `0` (unlimited) | पंजीकृत उपयोगकर्ता अकाउंट की अधिकतम संख्या। असीमित के लिए 0 पर सेट करें। |
| `SESSION_DURATION_HOURS` | `168` | घंटों में लॉगिन सत्र जीवनकाल (डिफ़ॉल्ट 7 दिन है)। |
| `SKIP_MUST_CHANGE_PASSWORD` | - | पहली बार लॉगिन पर बाध्य पासवर्ड-परिवर्तन प्रॉम्प्ट को बायपास करने के लिए किसी भी गैर-खाली मान पर सेट करें |
| `SKIP_MUST_CHANGE_PASSWORD` | `false` | पहली बार लॉगिन पर बाध्य पासवर्ड-परिवर्तन प्रॉम्प्ट को छोड़ने के लिए `true` पर सेट करें |
### Storage {#storage}
| Variable | Default | Description |
|---|---|---|
| `STORAGE_MODE` | `local` | `local` या `s3`। S3/MinIO के लिए s3_storage फ़ीचर वाले लाइसेंस की आवश्यकता होती है। |
| `DATABASE_URL` | `postgres://snapotter:snapotter@postgres:5432/snapotter` | PostgreSQL कनेक्शन स्ट्रिंग। |
| `REDIS_URL` | `redis://redis:6379` | Redis कनेक्शन स्ट्रिंग (BullMQ जॉब क्यू के लिए उपयोग की जाती है)। |
| `WORKSPACE_PATH` | `./tmp/workspace` | प्रोसेसिंग के दौरान अस्थायी फ़ाइलों के लिए डायरेक्टरी। स्वचालित रूप से साफ़ की जाती है। |
| `FILES_STORAGE_PATH` | `./data/files` | स्थायी उपयोगकर्ता फ़ाइलों (अपलोड की गई इमेज, सहेजे गए परिणाम) के लिए डायरेक्टरी। |
| `STORAGE_MODE` | `local` | `local` या `s3`। S3 और MinIO के लिए s3_storage फ़ीचर वाले लाइसेंस के साथ नीचे दिए गए `S3_*` वेरिएबल्स की भी आवश्यकता होती है। |
| `DATABASE_URL` | `postgres://snapotter:snapotter@localhost:5432/snapotter` | PostgreSQL कनेक्शन स्ट्रिंग। Compose स्टैक इसे अपनी `postgres` सेवा की ओर इंगित करता है; embedded मोड पाने के लिए इसे (`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 object storage {#s3-object-storage}
ये केवल तभी पढ़े जाते हैं जब `STORAGE_MODE=s3` हो। तीन आवश्यक वेरिएबल्स में से कोई भी छूट जाए तो स्टार्टअप विफल हो जाता है और जो वेरिएबल आपने छोड़ा उसका नाम बताता है।
| Variable | Default | Description |
|---|---|---|
| `S3_BUCKET` | (empty) | वह बकेट जो अपलोड और आउटपुट रखता है। आवश्यक। |
| `S3_ACCESS_KEY_ID` | (empty) | एक्सेस की। आवश्यक। कंटेनर में आप इसके बजाय इसे `S3_ACCESS_KEY_ID_FILE` के माध्यम से माउंट कर सकते हैं। |
| `S3_SECRET_ACCESS_KEY` | (empty) | सीक्रेट की। आवश्यक। वही फ़ाइल परिपाटी: `S3_SECRET_ACCESS_KEY_FILE`। |
| `S3_REGION` | `us-east-1` | बकेट का क्षेत्र। |
| `S3_ENDPOINT` | (empty) | MinIO, R2, Backblaze, और अन्य S3-संगत स्टोर के लिए कस्टम एंडपॉइंट। खाली का अर्थ है AWS। |
| `S3_FORCE_PATH_STYLE` | `false` | MinIO और ऐसी किसी भी अन्य चीज़ के लिए `true` पर सेट करें जो वर्चुअल-होस्ट एड्रेसिंग के बजाय `endpoint/bucket/key` चाहती है। |
| `S3_PREFIX` | (empty) | की प्रीफ़िक्स, ताकि एक ही बकेट कई इंस्टेंस रख सके। |
### Encryption at rest {#encryption-at-rest}
| Variable | Default | Description |
|---|---|---|
| `DATA_ENCRYPTION_KEY` | (empty) | 64 हेक्स वर्ण (32 बाइट)। डेटाबेस में संग्रहीत संवेदनशील सेटिंग्स को एन्क्रिप्ट करता है। जो कुछ भी 64 हेक्स वर्ण नहीं है उसे स्टार्टअप पर अस्वीकार कर दिया जाता है। |
| `DATA_ENCRYPTION_KEY_PREVIOUS` | (empty) | वह की जिससे आप रोटेट होकर दूर जा रहे हैं, वही फ़ॉर्मैट। रोटेशन के दौरान दोनों सेट करें ताकि मौजूदा पंक्तियाँ अब भी डिक्रिप्ट हों, फिर इसे हटा दें। |
### Embedded mode {#embedded-mode}
@@ -59,16 +83,15 @@ i18n_output_hash: 6de48963490c
| Variable | Default | Description |
|---|---|---|
| `MAX_UPLOAD_SIZE_MB` | `100` | मेगाबाइट में प्रति अपलोड अधिकतम फ़ाइल आकार। असीमित के लिए 0 पर सेट करें। |
| `MAX_BATCH_SIZE` | `100` | एकल बैच अनुरोध में फ़ाइलों की अधिकतम संख्या। असीमित के लिए 0 पर सेट करें। |
| `MAX_UPLOAD_SIZE_MB` | `0` (unlimited) | मेगाबाइट में प्रति अपलोड अधिकतम फ़ाइल आकार। असीमित के लिए 0 पर सेट करें। प्रकाशित इमेज `0` के साथ शिप होती है; सोर्स से बिल्ड 100 से शुरू होता है। |
| `MAX_BATCH_SIZE` | `0` (unlimited) | एकल बैच अनुरोध में फ़ाइलों की अधिकतम संख्या। असीमित के लिए 0 पर सेट करें। प्रकाशित इमेज `0` के साथ शिप होती है; सोर्स से बिल्ड 100 से शुरू होता है। |
| `CONCURRENT_JOBS` | `0` (auto) | समानांतर में चलने वाले बैच जॉब की संख्या। उपलब्ध CPU कोर के आधार पर स्वतः-पहचान के लिए 0 पर सेट करें। |
| `MAX_MEGAPIXELS` | `0` (unlimited) | मेगापिक्सेल में अनुमत अधिकतम इमेज रिज़ॉल्यूशन। असीमित के लिए 0 पर सेट करें। |
| `MAX_WORKER_THREADS` | `0` (auto) | इमेज प्रोसेसिंग के लिए अधिकतम वर्कर थ्रेड। उपलब्ध CPU कोर के आधार पर स्वतः-पहचान के लिए 0 पर सेट करें। |
| `PROCESSING_TIMEOUT_S` | `0` (no limit) | सेकंड में प्रति अनुरोध अधिकतम प्रोसेसिंग समय। बिना टाइमआउट के लिए 0 पर सेट करें। |
| `MAX_PIPELINE_STEPS` | `20` | एक पाइपलाइन में अधिकतम चरणों की संख्या। बिना सीमा के लिए 0 पर सेट करें। |
| `MAX_CANVAS_PIXELS` | `0` (no limit) | आउटपुट इमेज के लिए पिक्सेल में अधिकतम कैनवास आकार। बिना सीमा के लिए 0 पर सेट करें। |
| `MAX_SVG_SIZE_MB` | `0` (unlimited) | मेगाबाइट में अधिकतम SVG फ़ाइल आकार। असीमित के लिए 0 पर सेट करें। |
| `MAX_SPLIT_GRID` | `100` | इमेज स्प्लिट टूल के लिए अधिकतम ग्रिड आयाम। |
| `MAX_SVG_SIZE_MB` | `50` | सैनिटाइज़ करने से पहले स्वीकार किया जाने वाला सबसे बड़ा SVG, मेगाबाइट में। यहाँ `0` आसपास की पंक्तियों से अलग व्यवहार करता है। यह पार्स-पूर्व आकार सीमा को बढ़ाने के बजाय पूरी तरह हटा देता है, इसलिए इसे सेट ही रहने दें। |
| `MAX_PDF_PAGES` | `0` (unlimited) | PDF-to-image रूपांतरण के लिए PDF पृष्ठों की अधिकतम संख्या। असीमित के लिए 0 पर सेट करें। |
### Cleanup {#cleanup}
@@ -82,7 +105,7 @@ i18n_output_hash: 6de48963490c
| Variable | Default | Description |
|---|---|---|
| `DEFAULT_THEME` | `light` | नए सत्रों के लिए डिफ़ॉल्ट थीम। `light` या `dark`। |
| `DEFAULT_THEME` | `light` | नए सत्रों के लिए डिफ़ॉल्ट थीम। `light`, `dark`, या `system`। |
| `DEFAULT_LOCALE` | `en` | डिफ़ॉल्ट इंटरफ़ेस भाषा। |
| `DEFAULT_TOOL_VIEW` | `sidebar` | डिफ़ॉल्ट टूल लेआउट। `sidebar` या `fullscreen`। |
@@ -124,13 +147,13 @@ services:
image: postgres:17-alpine
environment:
POSTGRES_USER: snapotter
POSTGRES_PASSWORD: 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"]
test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"]
interval: 10s
timeout: 5s
retries: 12
+5 -4
View File
@@ -1,8 +1,9 @@
---
description: "SnapOtter में योगदान कैसे करें। बग रिपोर्ट, फ़ीचर अनुरोध, पुल रिक्वेस्ट और CLA आवश्यकताएँ।"
i18n_source_hash: 528802503035
i18n_source_hash: 6c920a5f83e0
i18n_provenance: human
i18n_output_hash: cf867a422a1c
i18n_output_hash: 2e30393617bf
i18n_hash_version: 2
---
# योगदान {#contributing}
@@ -53,7 +54,7 @@ i18n_output_hash: cf867a422a1c
### पूर्वापेक्षाएँ {#prerequisites}
- Node.js 22+
- Node.js 22.22+
- pnpm 9+
- Python 3.11+ (केवल AI टूल के लिए)
- Docker (वैकल्पिक, पूर्ण इंटीग्रेशन टेस्टिंग के लिए)
@@ -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
```
+35 -15
View File
@@ -1,8 +1,9 @@
---
description: "SnapOtter के लिए PostgreSQL डेटाबेस स्कीमा, टेबल, माइग्रेशन और बैकअप प्रक्रियाएँ।"
i18n_source_hash: 50d5d4f220cf
i18n_provenance: human
i18n_output_hash: 5592d4435806
i18n_source_hash: a68264552836
i18n_provenance: machine
i18n_output_hash: de28f97f3fab
i18n_hash_version: 2
---
# डेटाबेस {#database}
@@ -145,6 +146,17 @@ SnapOtter डेटा स्थायित्व के लिए [Drizzle ORM
| `details` | jsonb | क्रिया-विशिष्ट डेटा |
| `createdAt` | timestamp | क्रिया का समय |
### user_preferences {#user-preferences}
प्रति-उपयोगकर्ता UI स्थिति, प्राथमिकता के नाम से कुंजीबद्ध। होम पेज पर पिन किए गए टूल यहीं रखे जाते हैं, जिन्हें `PUT /api/v1/preferences` के ज़रिए लिखा जाता है।
| कॉलम | प्रकार | नोट्स |
|---|---|---|
| `userId` | text | users के लिए FK, हटाने पर कैस्केड। `key` के साथ मिलकर प्राथमिक कुंजी |
| `key` | text | प्राथमिकता का नाम। `userId` के साथ मिलकर प्राथमिक कुंजी |
| `value` | jsonb | प्राथमिकता का डेटा |
| `updatedAt` | timestamp | अंतिम लेखन समय |
## माइग्रेशन {#migrations}
Drizzle स्कीमा माइग्रेशन संभालता है। माइग्रेशन फ़ाइलें `apps/api/drizzle/` में रहती हैं। विकास के दौरान:
@@ -157,29 +169,37 @@ npx drizzle-kit migrate # apply pending migrations
प्रोडक्शन में, लंबित माइग्रेशन स्टार्टअप पर स्वचालित रूप से लागू किए जाते हैं।
## बैकअप और रिस्टोर {#backup-and-restore}
## बैकअप लें और {#backup-and-restore} को पुनर्स्थापित करें
रिलेशनल डेटाबेस Postgres कंटेनर के `SnapOtter-pgdata` वॉल्यूम में रहता है, ऐप के `/data` वॉल्यूम में नहीं।
रिलेशनल डेटाबेस पोस्टग्रेज कंटेनर के `SnapOtter-pgdata` वॉल्यूम में रहता है, ऐप के `/data` वॉल्यूम में नहीं।
**विकल्प 1: pg_dump (अनुशंसित)**
**सत्यापन के साथ तार्किक बैकअप (अनुशंसित)**
```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
```
**विकल्प 2: वॉल्यूम स्नैपशॉट**
इस डेटाबेस डंप में `/data/files` या Redis में टिकाऊ BullMQ स्थिति में सहेजे गए लाइब्रेरी ऑब्जेक्ट शामिल नहीं हैं। [सुरक्षा और हार्डनिंग](/hi/guide/security#backup-and-recovery) में समन्वित प्रक्रिया के साथ उनका बैकअप लें और पुनर्स्थापित करें।
**कोल्ड वॉल्यूम स्नैपशॉट**
```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
```
`tar` के साथ लाइव PostgreSQL डेटा निर्देशिका की प्रतिलिपि न बनाएं। प्रोजेक्ट के अनुसार उपसर्ग वॉल्यूम नाम लिखें, इसलिए शाब्दिक लेबल `SnapOtter-pgdata` मानने के बजाय `docker inspect` या अपने स्टोरेज प्लेटफ़ॉर्म से माउंटेड वॉल्यूम आईडी को हल करें।
### 1.x (SQLite) से माइग्रेट करना {#migrating-from-1-x-sqlite}
SnapOtter 1.x से अपग्रेड करने की अपनी अलग गाइड है: [Upgrading from 1.x to 2.0](./upgrading) देखें। संक्षेप में, अपने मौजूदा `/data` वॉल्यूम का पुनः उपयोग करें और 2.0 पहले बूट पर `/data/snapotter.db` का स्वतः पता लगाकर उसे इम्पोर्ट करता है (या इसे स्पष्ट रूप से इंगित करने के लिए `SQLITE_MIGRATE_PATH` सेट करें)। पहले पूरे `/data` वॉल्यूम का बैकअप लें, केवल `snapotter.db` का नहीं: 1.x SQLite WAL मोड का उपयोग करता है, इसलिए एक रुका हुआ कंटेनर अक्सर अपना अधिकांश डेटा एक लगभग-खाली `snapotter.db` के बगल में `snapotter.db-wal` में छोड़ देता है।
+24 -13
View File
@@ -1,8 +1,9 @@
---
description: "SnapOtter को Docker के साथ प्रोडक्शन में डिप्लॉय करें। हार्डवेयर आवश्यकताएँ, GPU सेटअप, और Nginx, Traefik, तथा Cloudflare के लिए रिवर्स प्रॉक्सी कॉन्फ़िग।"
i18n_output_hash: 23f4f331a239
i18n_source_hash: 98172965118b
i18n_source_hash: 2a722f86da75
i18n_provenance: human
i18n_output_hash: 839d9fc77083
i18n_hash_version: 2
---
# Deployment {#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 # गैर-स्थानीय तैनाती के लिए इसे बदलें
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
```
लॉग में CUDA डिटेक्शन की जाँच करें:
### GPU त्वरण सत्यापित करें {#verify-gpu-acceleration}
लॉग में CUDA पहचान की जाँच करें:
```bash
docker logs SnapOtter 2>&1 | head -20
# Look for: [gpu] CUDA available via torch
```
यदि `--gpus all` और NVIDIA कंटेनर टूलकिट सही तरीके से सेट होने के बावजूद AI उपकरण CPU पर चलते हैं, तो **सेटिंग्स → AI फीचर्स** से प्रभावित बंडल (उदाहरण के लिए बैकग्राउंड रिमूवल) को फिर से इंस्टॉल करें। इंस्टॉलर ONNX रनटाइम के GPU बिल्ड को पुनर्स्थापित करता है, जिसे केवल CPU बिल्ड किसी अन्य बंडल (जैसे ट्रांसक्रिप्शन) द्वारा खींचा जाता है अन्यथा साझा AI वातावरण में छाया कर सकता है। यदि यूआई से पुनः इंस्टॉल करने से पुरानी छवि पर जीपीयू बहाल नहीं होता है, तो [अंक #490](https://github.com/snapotter-hq/SnapOtter/issues/490) में मैन्युअल मरम्मत देखें।
## Hardware Requirements {#hardware-requirements}
ये संख्याएँ कई तरह के सिस्टमों पर किए गए बेंचमार्क से आती हैं, एक आधुनिक amd64 वर्कस्टेशन (NVIDIA RTX 4070 के साथ) से लेकर एक Raspberry Pi तक, जिनमें से हर एक पर पूरा टूल कैटलॉग चलाया गया और असली न्यूनतम सीमा खोजने के लिए Docker रिसोर्स लिमिट को स्वीप किया गया।
@@ -436,11 +441,11 @@ securityContext:
| `AUTH_ENABLED` | `true` | लॉगिन आवश्यकता सक्षम/अक्षम करें |
| `DEFAULT_USERNAME` | `admin` | प्रारंभिक व्यवस्थापक उपयोगकर्ता नाम |
| `DEFAULT_PASSWORD` | `admin` | प्रारंभिक व्यवस्थापक पासवर्ड (पहले लॉगिन पर बदलना अनिवार्य) |
| `MAX_UPLOAD_SIZE_MB` | `100` | प्रति-फ़ाइल अपलोड सीमा |
| `MAX_BATCH_SIZE` | `100` | प्रति बैच अनुरोध अधिकतम फ़ाइलें |
| `MAX_UPLOAD_SIZE_MB` | `0` (असीमित) | प्रति-फ़ाइल अपलोड सीमा MB में। इमेज `0` के साथ आती है; स्रोत से बनाया गया बिल्ड 100 से शुरू होता है |
| `MAX_BATCH_SIZE` | `0` (असीमित) | प्रति बैच अनुरोध अधिकतम फ़ाइलें। इमेज `0` के साथ आती है; स्रोत से बनाया गया बिल्ड 100 से शुरू होता है |
| `RATE_LIMIT_PER_MIN` | `1000` | प्रति IP प्रति मिनट API अनुरोध (अक्षम करने के लिए 0 सेट करें) |
| `MAX_USERS` | `0` (असीमित) | अधिकतम उपयोगकर्ता खाते |
| `TRUST_PROXY` | `true` | रिवर्स प्रॉक्सी से X-Forwarded-For हेडर पर भरोसा करें |
| `TRUST_PROXY` | `loopback,linklocal,uniquelocal` | `X-Forwarded-For` के ज़रिए क्लाइंट IP कौन से पीयर सेट कर सकते हैं। डिफ़ॉल्ट रूप से केवल निजी नेटवर्क |
| `PUID` | `999` | इस UID के रूप में चलाएँ (बाइंड माउंट अनुमतियों के लिए) |
| `PGID` | `999` | इस GID के रूप में चलाएँ (बाइंड माउंट अनुमतियों के लिए) |
| `LOG_LEVEL` | `info` | लॉग वर्बोसिटी: fatal, error, warn, info, debug, trace |
@@ -483,7 +488,13 @@ curl http://localhost:1349/api/v1/health
## Reverse Proxy {#reverse-proxy}
SnapOtter डिफ़ॉल्ट रूप से `TRUST_PROXY=true` सेट करता है ताकि रेट लिमिटिंग और लॉगिंग `X-Forwarded-For` हेडर से असली क्लाइंट IP का उपयोग करें।
`TRUST_PROXY` का डिफ़ॉल्ट `loopback,linklocal,uniquelocal` है, इसलिए SnapOtter `X-Forwarded-For` पर तभी भरोसा करता है जब वह किसी निजी नेटवर्क के पीयर से आया हो। उसी होस्ट पर, किसी Docker नेटवर्क पर या आपके LAN पर मौजूद रिवर्स प्रॉक्सी शुरू से ही भरोसेमंद माना जाता है, यानी रेट लिमिटिंग, लॉगिन की ब्रूट-फ़ोर्स रोक, ऑडिट लॉग और enterprise संस्करण की IP अनुमति-सूची, सभी बिना किसी कॉन्फ़िगरेशन के असली क्लाइंट IP देखते हैं।
`TRUST_PROXY=true` तभी सेट करें जब आगे लगा प्रॉक्सी SnapOtter तक किसी **सार्वजनिक** पते से पहुँचता हो, जैसे किसी दूसरे नेटवर्क का क्लाउड लोड बैलेंसर। सीधे उजागर इंस्टेंस पर यह मान `request.ip` को हमलावर के नियंत्रण में दे देता है, क्योंकि हेडर बदलता रहने वाला कॉलर हर अनुरोध पर नई रेट-लिमिट गिनती पा जाता है।
क्लाइंट IP नापने से पहले दो बातें जान लें। macOS और Windows पर Docker Desktop प्रकाशित पोर्ट को यूज़रलैंड प्रॉक्सी के ज़रिए परोसता है, जो हर स्रोत पते को VM गेटवे `192.168.65.1` में बदल देता है; वहाँ `TRUST_PROXY` का कोई भी मान असली क्लाइंट वापस नहीं ला सकता, इसलिए इंटरनेट से जुड़ी हर चीज़ Linux पर तैनात करें। और किसी भी प्लेटफ़ॉर्म पर, प्रकाशित पोर्ट तक `localhost` से पहुँचना आपके क्लाइंट के बजाय ब्रिज गेटवे के रूप में दिखता है, इसलिए localhost से किया गया परीक्षण यह नहीं बताता कि असली क्लाइंट को कैसे गिना जाएगा। `TRUST_PROXY` के मानों की पूरी तालिका और Docker Desktop से जुड़ी चेतावनी [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md#client-ip-resolution-trust_proxy) में हैं।
नीचे दी गई प्रत्येक प्रॉक्सी के लिए दो चीजें मायने रखती हैं: बड़े अनुरोध निकायों (अपलोड) की अनुमति दें, और प्रतिक्रियाओं को बफर न करें। एक प्रतिक्रिया-बफ़रिंग प्रॉक्सी SSE प्रगति को तोड़ देती है और, अधिक स्पष्ट रूप से, एक बड़ी फ़ाइल डाउनलोड को "शुरू लेकिन कभी ख़त्म नहीं" करती है, क्योंकि प्रॉक्सी इसे आगे बढ़ाने से पहले पूरी फ़ाइल को रखती है। SnapOtter डाउनलोड पर `X-Accel-Buffering: no` भेजता है इसलिए nginx उन्हें स्ट्रीम करता है, भले ही बफ़रिंग कहीं और छोड़ दी गई हो, लेकिन nginx के अलावा अन्य प्रॉक्सी को प्रतिक्रिया बफ़रिंग को स्पष्ट रूप से अक्षम करने की आवश्यकता होती है (नीचे प्रत्येक कॉन्फ़िगरेशन में दिखाया गया है)। यदि कोई डाउनलोड आंशिक रूप से रुक जाता है, तो सामने एक बफ़रिंग प्रॉक्सी जांचने वाली पहली चीज़ है।
### 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)
# बफ़रिंग के बजाय स्ट्रीम प्रतिक्रियाएँ: SSE प्रगति (बैच, AI, फ़ीचर इंस्टॉल) और बड़ी फ़ाइल डाउनलोड के लिए आवश्यक।
proxy_buffering off;
proxy_read_timeout 300s;
}
@@ -549,7 +560,7 @@ images.example.com {
}
```
`flush_interval -1` रिस्पॉन्स बफरिंग को अक्षम करता है, जो SSE प्रगति इवेंट (बैच प्रोसेसिंग, AI टूल, फीचर इंस्टॉल) के लिए आवश्यक है। विस्तारित टाइमआउट बड़ी फ़ाइल अपलोड को Caddy द्वारा कनेक्शन जल्दी बंद किए बिना पूरा होने देत है
`flush_interval -1` प्रतिक्रिया बफरिंग को अक्षम कर देता है, जो SSE प्रगति घटनाओं (बैच प्रोसेसिंग, एआई टूल्स, फीचर इंस्टॉल) और बड़ी फ़ाइल डाउनलोड को रोकने के बजाय स्ट्रीम करने के लिए आवश्यक है। विस्तारित टाइमआउट Caddy कनेक्शन को जल्दी बंद किए बिना बड़ी फ़ाइल अपलोड को पूरा करने की अनुमति देत है।
### Cloudflare Tunnels {#cloudflare-tunnels}
+19 -7
View File
@@ -1,8 +1,9 @@
---
description: "SnapOtter में स्थानीय विकास सेटअप, कमांड, कोड परंपराएँ, और एक नया टूल कैसे जोड़ें।"
i18n_source_hash: cb03724d2829
i18n_provenance: human
i18n_output_hash: c6b1b3537584
i18n_source_hash: 56acc1bf9a9b
i18n_provenance: machine
i18n_output_hash: feb4df3446de
i18n_hash_version: 2
---
# डेवलपर गाइड {#developer-guide}
@@ -11,12 +12,12 @@ i18n_output_hash: c6b1b3537584
## पूर्वापेक्षाएँ {#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/) (स्थानीय Postgres + Redis, कंटेनर बिल्ड, और AI फ़ीचर के लिए आवश्यक)
- Git
Python 3.10+ केवल तभी आवश्यक है जब आप AI/ML साइडकार (बैकग्राउंड हटाना, अपस्केलिंग, OCR) पर काम कर रहे हों।
Python 3.11+ केवल तभी आवश्यक है जब आप AI/ML साइडकार (बैकग्राउंड हटाना, अपस्केलिंग, OCR) पर काम कर रहे हों।
## सेटअप {#setup}
@@ -32,10 +33,10 @@ pnpm dev
| सेवा | URL | नोट्स |
|----------|--------------------------|------------------------------------|
| फ़्रंटएंड | http://localhost:1349 | Vite डेव सर्वर, /api को प्रॉक्सी करता है |
| फ़्रंटएंड | http://localhost:1351 | Vite डेव सर्वर, /api को प्रॉक्सी करता है |
| बैकएंड | http://localhost:13490 | Fastify API (प्रॉक्सी के माध्यम से एक्सेस) |
अपने ब्राउज़र में http://localhost:1349 खोलें। `admin` / `admin` के साथ लॉगिन करें। पहले लॉगिन पर आपको पासवर्ड बदलने के लिए कहा जाएगा।
अपने ब्राउज़र में http://localhost:1351 खोलें। `admin` / `admin` के साथ लॉगिन करें। पहले लॉगिन पर आपको पासवर्ड बदलने के लिए कहा जाएगा।
## प्रोजेक्ट संरचना {#project-structure}
@@ -220,6 +221,17 @@ docker build -f docker/Dockerfile -t snapotter:latest .
DOCKER_BUILDKIT=1 docker build -f docker/Dockerfile -t snapotter:latest .
```
## रिलीज़ संस्करण डोमेन {#release-version-domains}
SnapOtter में जानबूझकर तीन संस्करण डोमेन हैं। रिलीज़ के दौरान एक डोमेन को दूसरे में कॉपी न करें:
- एप्लिकेशन रिलीज़ संस्करण रूट मेनिफेस्ट, सभी निजी कार्यक्षेत्र पैकेज और `APP_VERSION` को कवर करता है। Semantic-release यह मान प्रदान करता है, और `pnpm version:sync <version>` एप्लिकेशन रिलीज़ से पहले प्रत्येक कार्यक्षेत्र को अपडेट करता है।
- OpenAPI `info.version` स्थिर सार्वजनिक API-प्रमुख अनुबंध है। संगत एप्लिकेशन रिलीज़ के लिए सभी स्थानीयकृत विनिर्देश `<major>.0.0` पर बने रहते हैं और केवल तभी बदलते हैं जब API अनुबंध एक नए प्रमुख संस्करण में चला जाता है।
- `docker/feature-manifest.json`, `imageVersion: 2.0.0` को अपरिवर्तनीय विरासत सुविधा-बंडल भंडारण युग के रूप में रखता है। वे v2 संग्रह पथ एप्लिकेशन पैकेज संस्करण नहीं हैं। सटीक OCR रनटाइम प्रारूप v3 का उपयोग करता है और इसके एप्लिकेशन रिलीज़ उद्गम को अलग से रिकॉर्ड करता है।
`tests/unit/infra/release-version-policy.test.ts` इन सीमाओं को लागू करता है। एक नए संस्करण डोमेन या माइग्रेशन को उस अनुबंध और प्रासंगिक आर्टिफैक्ट माइग्रेशन डिज़ाइन को एक साथ अपडेट करना होगा।
स्वतंत्र API और लीगेसी-बंडल मान `config/release-version-policy.json` में रहते हैं; एप्लिकेशन संस्करण सिंक्रोनाइज़ेशन को कभी भी उस नीति फ़ाइल को परोक्ष रूप से दोबारा नहीं लिखना चाहिए।
## एनवायरनमेंट वेरिएबल {#environment-variables}
पूर्ण सूची के लिए [Configuration guide](/hi/guide/configuration) देखें। विकास के लिए मुख्य वेरिएबल:
+8 -7
View File
@@ -1,8 +1,9 @@
---
description: "SnapOtter Docker image टैग, GPU बेंचमार्क, वर्शन पिनिंग, और AMD64 तथा ARM64 के लिए मल्टी-प्लेटफ़ॉर्म समर्थन।"
i18n_output_hash: 5b607c2591dd
i18n_source_hash: fda322e78b4b
i18n_source_hash: 566e20ca07fc
i18n_provenance: human
i18n_output_hash: 44c09e47365d
i18n_hash_version: 2
---
# Docker Image {#docker-image}
@@ -93,13 +94,13 @@ services:
image: postgres:17-alpine
environment:
POSTGRES_USER: snapotter
POSTGRES_PASSWORD: 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"]
test: ["CMD-SHELL", "pg_isready -U snapotter -d snapotter"]
interval: 10s
timeout: 5s
retries: 12
@@ -140,9 +141,9 @@ Docker Compose के माध्यम से NVIDIA CUDA acceleration के
| Tag | Description |
|-----|------------|
| `latest` | नवीनतम release |
| `1.11.0` | सटीक version |
| `1.11` | 1.11.x में नवीनतम patch |
| `1` | 1.x में नवीनतम minor |
| `2.1.0` | सटीक version |
| `2.1` | 2.1.x में नवीनतम patch |
| `2` | 2.x में नवीनतम minor |
## Platforms {#platforms}
+28 -61
View File
@@ -1,8 +1,9 @@
---
description: "SnapOtter को एक ही कमांड में Docker के साथ इंस्टॉल करें। इसमें Docker Compose सेटअप, सोर्स से बिल्ड करना, और एक पूर्ण फ़ीचर अवलोकन शामिल है।"
i18n_output_hash: bc1ecfa22bef
i18n_source_hash: 68bf7f60b68d
i18n_provenance: human
i18n_source_hash: 8040133a6982
i18n_provenance: machine
i18n_output_hash: 16dd84c66bc6
i18n_hash_version: 2
---
# Getting Started {#getting-started}
@@ -17,7 +18,7 @@ i18n_provenance: human
docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data snapotter/snapotter:latest
```
यह एकल कंटेनर वह सब कुछ चलाता है जिसकी उसे ज़रूरत है: बिना कोई `DATABASE_URL` सेट किए, यह लूपबैक इंटरफ़ेस पर अपना खुद का PostgreSQL और Redis शुरू करता है (एंबेडेड मोड) और सारा डेटा `SnapOtter-data` वॉल्यूम में रखता है। यह SnapOtter को आज़माने या किसी homelab पर सेल्फ-होस्ट करने का सबसे तेज़ तरीका है। प्रोडक्शन के लिए, नीचे दिया गया [Docker Compose](#docker-compose) स्टैक चलाएँ, जो PostgreSQL और Redis को उनके अपने कंटेनरों में रखता है। एंबेडेड मोड root के रूप में चलता है (डिफ़ॉल्ट) और जैसे ही आप `DATABASE_URL` सेट करते हैं, यह स्वचालित रूप से बंद हो जाता है।
यह एकल कंटेनर वह सब कुछ चलाता है जिसकी उसे आवश्यकता होती है: बिना किसी `DATABASE_URL` सेट क, यह लूपबैक इंटरफ़ेस (एम्बेडेड मोड) पर अपना स्वयं का PostgreSQL और Redis शुरू करता है और सभी डेटा को `SnapOtter-data` वॉल्यूम में रखता है। यह होमलैब पर SnapOtter या सेल्फ-होस्ट आज़माने का सबसे तेज़ तरीका है। उत्पादन के लिए, [कैनोनिकल डॉकर कंपोज़ स्टैक](#docker-compose) का उपयोग करें, जो PostgreSQL और Redis को अपने कंटेनर में रखता है। एंबेडेड मोड रूट (डिफ़ॉल्ट) के रूप में चलता है और जैसे ही आप `DATABASE_URL` सेट करते हैं तो स्वचालित रूप से बंद हो जाता है।
Raspberry Pi, किसी पुराने लैपटॉप, या छोटे VPS पर इंस्टॉल कर रहे हैं? ट्यून की गई वॉकथ्रू और सीमित हार्डवेयर से क्या अपेक्षा करें, इसके लिए [कम संसाधन वाले सेटअप](/hi/guide/low-resource) देखें।
@@ -40,7 +41,7 @@ NVIDIA CUDA-त्वरित पृष्ठभूमि हटाने, अ
docker run -d --name SnapOtter -p 1349:1349 --gpus all -v SnapOtter-data:/data snapotter/snapotter:latest
```
[NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) आवश्यक है। CUDA अनुपलब्ध होने पर स्वचालित रूप से CPU पर फ़ॉलबैक करता है। VA-API, Quick Sync, या OpenCL के माध्यम से Intel/AMD iGPU त्वरण आज AI इन्फ़रेंस के लिए सपोर्ट नहीं किया जाता। बेंचमार्क के लिए [Docker Tags](/hi/guide/docker-tags) देखें।
[NVIDIA कंटेनर टूलकिट](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) की आवश्यकता है। CUDA अनुपलब्ध होने पर स्वचालित रूप से CPU पर वापस आ जाता है। वीए-एपीआई, क्विक सिंक या ओपनसीएल के माध्यम से इंटेल/एएमडी आईजीपीयू त्वरण आज एआई अनुमान के लिए समर्थित नहीं है। बेंचमार्क के लिए [डॉकर टैग](/hi/guide/docker-tags) देखें। यदि `--gpus all` के बावजूद AI उपकरण CPU पर चलते हैं, तो [GPU त्वरण सत्यापित करें](/hi/guide/deployment#verify-gpu-acceleration) देखें।
:::
::: details GHCR पर भी
@@ -51,67 +52,33 @@ docker run -d --name SnapOtter -p 1349:1349 -v SnapOtter-data:/data ghcr.io/snap
दोनों रजिस्ट्री हर रिलीज़ पर वही इमेज प्रकाशित करती हैं।
:::
## Docker Compose {#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
इस पृष्ठ से संक्षिप्त कंपोज़ उदाहरण की प्रतिलिपि बनाने के बजाय प्रत्येक रिलीज़ के साथ बनाए और परीक्षण की गई उत्पादन फ़ाइल का उपयोग करें:
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
```
सभी एनवायरनमेंट वेरिएबल के लिए [Configuration](/hi/guide/configuration) देखें।
कैनोनिकल [`docker/docker-compose.yml`](https://github.com/snapotter-hq/SnapOtter/blob/v2.1.0/docker/docker-compose.yml) में सभी चार रनटाइम वॉल्यूम, स्वास्थ्य जांच, संसाधन सीमाएं, टिकाऊ रेडिस कॉन्फ़िगरेशन, पिन किए गए डेटाबेस/कैश छवियां और वर्तमान कंटेनर हार्डनिंग शामिल हैं। प्रथम लॉगिन के तुरंत बाद डिफ़ॉल्ट एडमिन पासवर्ड बदलें। प्रतिलिपि प्रस्तुत करने योग्य परिनियोजन के लिए, `latest` का अनुसरण करने के बजाय SnapOtter एप्लिकेशन छवि को रिलीज़ टैग पर पिन करें या आपके द्वारा सत्यापित डाइजेस्ट करें।
सभी पर्यावरण चर के लिए [कॉन्फ़िगरेशन](/hi/guide/configuration) और रहस्यों, नेटवर्क नीति और बैकअप मार्गदर्शन के लिए [सुरक्षा और हार्डनिंग](/hi/guide/security) देखें।
## Build from Source {#build-from-source}
**पूर्वापेक्षाएँ:** Node.js 22+, pnpm 9+, Docker (Postgres + Redis के लिए), Python 3.10+ (AI फ़ीचर के लिए), Git।
**पूर्वापेक्षाएँ:** Node.js 22.22+, pnpm 9+, Docker (Postgres + Redis के लिए), Python 3.11+ (AI फ़ीचर के लिए), Git।
```bash
git clone https://github.com/snapotter-hq/SnapOtter.git
@@ -121,7 +88,7 @@ pnpm install
pnpm dev
```
- फ़्रंटएंड: [http://localhost:1349](http://localhost:1349)
- फ़्रंटएंड: [http://localhost:1351](http://localhost:1351)
- बैकएंड: [http://localhost:13490](http://localhost:13490)
## What You Can Do {#what-you-can-do}
@@ -130,11 +97,11 @@ pnpm dev
| मोडैलिटी | संख्या | उदाहरण टूल |
|----------|-------|---------------|
| **Image** | 105 | Resize, Crop, Compress, Convert, Remove Background, Upscale, OCR, Watermark, Collage, Colorize, GIF Tools, format presets |
| **Image** | 107 | Resize, Crop, Compress, Convert, Remove Background, Upscale, OCR, Watermark, Collage, Colorize, GIF Tools, format presets |
| **Video** | 57 | Trim, Crop, Compress, Convert, Merge, Extract Audio, Auto Subtitles, Video to GIF, Resize, Stabilize, format presets |
| **Audio** | 27 | Trim, Merge, Convert, Normalize, Noise Reduction, Transcribe, Pitch Shift, Fade, Ringtone Maker, format presets |
| **PDF / Document** | 42 | Merge, Split, Compress, OCR, Watermark, Redact, Word to PDF, Excel to PDF, Rotate, Protect, Repair |
| **Files** | 10 | CSV to JSON, JSON to XML, Merge CSVs, Split CSV, Create ZIP, Extract ZIP, Chart Maker, YAML/JSON |
| **PDF / Document** | 29 | Merge, Split, Compress, OCR, Watermark, Redact, Word to PDF, Excel to PDF, Rotate, Protect, Repair |
| **Files** | 23 | CSV to JSON, JSON to XML, Merge CSVs, Split CSV, Create ZIP, Extract ZIP, Chart Maker, YAML/JSON |
### Pipelines {#pipelines}
+4 -3
View File
@@ -1,7 +1,8 @@
---
i18n_source_hash: f5de74aee1b9
i18n_source_hash: 521c03a6416c
i18n_provenance: machine
i18n_output_hash: 9e03d6f8c387
i18n_output_hash: 907011fe9063
i18n_hash_version: 2
---
# कम संसाधन वाले सेटअप {#low-resource-setups}
@@ -59,7 +60,7 @@ services:
image: postgres:17-alpine
environment:
- POSTGRES_USER=snapotter
- POSTGRES_PASSWORD=snapotter
- POSTGRES_PASSWORD=snapotter # गैर-स्थानीय तैनाती के लिए इसे बदलें
- POSTGRES_DB=snapotter
volumes:
- ./postgres-data:/var/lib/postgresql/data
+12 -7
View File
@@ -1,8 +1,9 @@
---
description: "अपने identity provider से SnapOtter में users और groups को sync करने के लिए SCIM 2.0 provisioning सेट करें। Okta, Azure AD / Entra ID, और custom integrations को कवर करता है।"
i18n_source_hash: bbd50119ec12
i18n_source_hash: 06ee702b386e
i18n_provenance: human
i18n_output_hash: cec58a6b3f0c
i18n_output_hash: 83a5e7e5383c
i18n_hash_version: 2
---
# SCIM Provisioning {#scim-provisioning}
@@ -17,7 +18,7 @@ SCIM provisioning के लिए `scim` feature वाली एक **enterpri
- एक चालू SnapOtter instance जो एक public URL पर पहुँच योग्य हो
- `scim` feature वाली एक enterprise license key
- SnapOtter तक admin access (SCIM token जनरेट या रद्द करने के लिए `users:manage` permission आवश्यक है)
- पूर्ण प्रभावी अनुमति सेट के साथ एक अंतर्निहित SnapOtter `admin` खाता। एक प्रत्यायोजित कस्टम भूमिका या एक व्यवस्थापक एपीआई कुंजी जिसमें कोई व्यवस्थापक अनुमति नहीं है, वैश्विक SCIM टोकन उत्पन्न या निरस्त नहीं कर सकता है
- आपके identity provider की provisioning settings तक admin access
## Quick start {#quick-start}
@@ -34,7 +35,7 @@ Response में token होता है। इसे तुरंत सह
```json
{
"token": "a1b2c3d4e5f6...",
"token": "so_scim_v2_a1b2c3d4e5f6...",
"message": "Save this token - it cannot be retrieved again"
}
```
@@ -49,15 +50,19 @@ SCIM endpoints एक समर्पित Bearer token का उपयोग
### Generating a token {#generating-a-token}
`POST /api/v1/enterprise/scim/token` एक नया SCIM token जनरेट करता है इस endpoint के लिए `users:manage` permission वाला एक वैध session आवश्यक है।
`POST /api/v1/enterprise/scim/token` एक नया SCIM टोकन उत्पन्न करता है। क्योंकि टोकन पूरे इंस्टेंस में उपयोगकर्ताओं को प्रावधानित और परिवर्तित कर सकता है, इस एंडपॉइंट के लिए संपूर्ण प्रभावी व्यवस्थापक अनुमति सेट के साथ अंतर्निहित `admin` भूमिका की आवश्यकता होती है। `users:manage` को कस्टम भूमिका में रखना पर्याप्त नहीं है।
Token plaintext में ठीक एक बार लौटाया जाता है। SnapOtter केवल एक scrypt hash संग्रहीत करता है। यदि आप token खो देते हैं, तो उसे रद्द करें और एक नया जनरेट करें।
एक समय में केवल एक SCIM token सक्रिय रहता है। एक नया token जनरेट करने से पिछला token बदल जाता है।
::: warning अपग्रेड के बाद टोकन पुनः जारी करना
लीगेसी अपरिवर्तित SCIM टोकन अस्वीकार कर दिए गए हैं। `so_scim_v2_...` टोकन जारी करने वाली रिलीज़ में अपग्रेड करने के बाद, एक नया टोकन जेनरेट करें और प्रावधान फिर से शुरू करने से पहले अपने पहचान प्रदाता को अपडेट करें।
:::
### Revoking a token {#revoking-a-token}
`DELETE /api/v1/enterprise/scim/token` वर्तमान SCIM token को रद्द करता है। इस endpoint के लिए भी `users:manage` आवश्यक है।
`DELETE /api/v1/enterprise/scim/token` वर्तमान SCIM टोकन को रद्द कर देता है। इसमें टोकन जेनरेशन के समान पूर्ण अंतर्निहित व्यवस्थापक आवश्यकता है।
### Rate limiting {#rate-limiting}
@@ -279,7 +284,7 @@ SCIM request में एक `Authorization: Bearer <token>` header शाम
### 401 "Invalid token" {#_401-invalid-token}
Token संग्रहीत hash से मेल नहीं खाता। यह तब होता है जब token रद्द कर दिया गया और फिर से जनरेट किया गया। अपने IdP की provisioning settings में token अपडेट करें।
टोकन विकृत है, सेवानिवृत्त अपरिवर्तित प्रारूप का उपयोग करता है, या संग्रहीत हैश से मेल नहीं खाता है। एक मौजूदा `so_scim_v2_...` टोकननरेट करें और अपने IdP की प्रोविजनिंग सेटिंग्स में टोकन को अपडेट करें।
### 401 "SCIM not configured" {#_401-scim-not-configured}
+94 -166
View File
@@ -1,8 +1,9 @@
---
description: "SnapOtter के लिए सुरक्षा हार्डनिंग गाइड। कंटेनर सुरक्षा, नेटवर्क आइसोलेशन, Docker secrets, Kubernetes डिप्लॉयमेंट, और अनुपालन आर्टिफ़ैक्ट।"
i18n_source_hash: 986f7658430c
i18n_provenance: human
i18n_output_hash: cc08062b0496
i18n_source_hash: 9ff337fa0417
i18n_provenance: machine
i18n_output_hash: 1072e94c511d
i18n_hash_version: 2
---
# Security & Hardening {#security-hardening}
@@ -11,133 +12,42 @@ SnapOtter फ़ाइलों को पूरी तरह आपके इ
कंटेनर एक समर्पित गैर-root उपयोगकर्ता (`snapotter`) के रूप में चलता है, जिसमें न्यूनतम आवश्यक सेट को छोड़कर सभी Linux क्षमताएँ हटा दी जाती हैं। पूर्ण भेद्यता प्रकटीकरण नीति और सुरक्षा आर्किटेक्चर के लिए, GitHub पर [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md) देखें।
## Container Hardening {#container-hardening}
## कंटेनर हार्डनिंग {#container-hardening}
[डिफ़ॉल्ट docker-compose.yml](https://github.com/snapotter-hq/SnapOtter/blob/main/docker/docker-compose.yml) में प्रोडक्शन सुरक्षा हार्डनिंग शामिल है। यहाँ हर विकल्प का विवरण और यह क्यों मायने रखता है:
विहित [CPU](https://github.com/snapotter-hq/SnapOtter/blob/main/docker/docker-compose.yml) और [GPU](https://github.com/snapotter-hq/SnapOtter/blob/main/docker/docker-compose-gpu.yml) कंपोज़ फ़ाइलें सत्य का स्रोत हैं। किसी संक्षिप्त उदाहरण को उत्पादन में कॉपी न करें; आपके द्वारा सत्यापित रिलीज़ टैग से फ़ाइल को तैनात करें।
```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
दोनों स्टैक निम्नलिखित नियंत्रण लागू करते हैं:
# --- 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
- मेमोरी, स्वैप, सीपीयू और पीआईडी ​​सीमाओं में अप्रचलित देशी प्रोसेसिंग शामिल है।
- प्रत्येक सेवा सभी Linux क्षमताओं को समाप्त कर देती है। एप्लिकेशन वॉल्यूम ओनरशिप, वन-वे `gosu` आइडेंटिटी ड्रॉप और ग्रेसफुल सिग्नल फ़ॉरवर्डिंग के लिए केवल `CHOWN, SETUID, SETGID, DAC_OVERRIDE, FOWNER, KILL` जोड़ता है। PostgreSQL और Redis को केवल वही उपसमुच्चय प्राप्त होता है जिसकी उनके आधिकारिक प्रवेश बिंदुओं को आवश्यकता होती है।
- `security_opt: [no-new-privileges:true]` एप्लिकेशन, PostgreSQL और Redis कंटेनरों में प्रक्रियाओं को अतिरिक्त विशेषाधिकार प्राप्त करने से रोकता है। यह `gosu` के साथ संगत रहता है: एंट्रीपॉइंट रूट के रूप में शुरू होता है, वॉल्यूम तैयार करता है, और केवल समर्पित `snapotter` उपयोगकर्ता तक पहुंचता है।
- PostgreSQL और Redis छवि इनपुट डाइजेस्ट द्वारा पिन किए गए हैं। एप्लिकेशन को `latest` के बजाय सत्यापित रिलीज़ टैग या डाइजेस्ट पर भी पिन किया जाना चाहिए।
- स्वास्थ्य जांच, बंधे हुए JSON लॉग रोटेशन, टिकाऊ Redis AOF और पुनरारंभ नीति को कैनोनिकल फ़ाइलों में केंद्रीय रूप से परिभाषित किया गया है।
# --- 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
इंटरनेट-फ़ेसिंग परिनियोजन के लिए, पोर्ट 1349 को लूपबैक से बाइंड करें और टीएलएस को एक बनाए हुए रिवर्स प्रॉक्सी पर समाप्त करें। अद्वितीय PostgreSQL और Redis क्रेडेंशियल जेनरेट करें, गुप्त फ़ाइलों या गुप्त प्रबंधक में रहस्य संग्रहीत करें, और प्रारंभिक व्यवस्थापक पासवर्ड तुरंत बदलें।
# --- Logging ---
logging:
driver: json-file
options:
max-size: "50m" # Rotate logs at 50 MB
max-file: "5" # Keep 5 rotated log files
### `read_only` {#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
`read_only: true` सेट नहीं है क्योंकि PUID/PGID रीमैपिंग स्टार्टअप पर `/etc/passwd` और `/etc/group` को लिखता है। यदि आप PUID/PGID के बजाय डॉकर के `--user` ध्वज या Kubernetes `runAsUser` का उपयोग करते हैं, तो आप सुरक्षित रूप से केवल पढ़ने योग्य रूट फ़ाइल सिस्टम को सक्षम कर सकते हैं।
shm_size: "2gb" # Required for Python ML shared memory
restart: unless-stopped
## नेटवर्क अलगाव {#network-isolation}
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
फ़ाइल प्रोसेसिंग स्थानीय है, लेकिन एक डिफ़ॉल्ट इंस्टॉलेशन **एक निकास-मुक्त सिस्टम नहीं** है। अज्ञात उत्पाद विश्लेषण पोस्टहॉग का उपयोग करते हैं और टेलीमेट्री सक्षम होने पर क्रैश रिपोर्टिंग सेंट्री का उपयोग करती है। दोनों को बंद करने के लिए `SNAPOTTER_TELEMETRY=0` सेट करें (या सेटिंग्स > सिस्टम > गोपनीयता के अंतर्गत एनालिटिक्स अक्षम करें)। SnapOtter में उन घटनाओं में कभी भी अपलोड की गई फ़ाइलें, फ़ाइल नाम, ओसीआर आउटपुट, दस्तावेज़ पाठ या अन्य फ़ाइल सामग्री शामिल नहीं होती है।
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:
```
### Why `no-new-privileges` Is Not Set {#why-no-new-privileges-is-not-set}
`security_opt: [no-new-privileges:true]` को जानबूझकर छोड़ दिया गया है। एंट्रीपॉइंट वॉल्यूम स्वामित्व ठीक करने के लिए root के रूप में शुरू होता है, फिर [gosu](https://github.com/tianon/gosu) के माध्यम से `snapotter` उपयोगकर्ता पर गिर जाता है, जिसके लिए setuid आवश्यक है। एक बार विशेषाधिकार गिरना पूरा हो जाने पर, प्रक्रिया `snapotter` के रूप में चलती है, जिसमें ऊपर सूचीबद्ध पाँच को छोड़कर सभी क्षमताएँ हटा दी जाती हैं।
यदि आप सीधे गैर-root के रूप में चलाने के लिए Kubernetes या Docker के `--user` फ़्लैग का उपयोग करते हैं (gosu को बायपास करते हुए), तो `no-new-privileges` को सक्षम करना सुरक्षित है।
### Why `read_only` Is Not Set {#why-read-only-is-not-set}
`read_only: true` सेट नहीं है क्योंकि PUID/PGID रीमैपिंग स्टार्टअप पर `/etc/passwd` और `/etc/group` पर लिखती है। यदि आप PUID/PGID के बजाय Docker के `--user` फ़्लैग या Kubernetes `runAsUser` का उपयोग करते हैं, तो आप सुरक्षित रूप से एक read-only रूट फ़ाइलसिस्टम सक्षम कर सकते हैं।
## Network Isolation {#network-isolation}
सामान्य संचालन के दौरान, कंटेनर **शून्य आउटबाउंड नेटवर्क कनेक्शन** बनाता है। सारी फ़ाइल प्रोसेसिंग बंडल की गई लाइब्रेरियों का उपयोग करके स्थानीय रूप से होती है।
```
Browser --> Reverse Proxy (TLS) --> SnapOtter container --> (nothing)
```
एकमात्र अपवाद **AI मॉडल डाउनलोड** है: जब कोई उपयोगकर्ता UI के माध्यम से एक AI फ़ीचर बंडल इंस्टॉल करता है, तो कंटेनर Hugging Face से पहले से बना बंडल आर्काइव डाउनलोड करता है, साथ ही GitHub Releases, Google Storage, और PyPI से कुछ अलग-अलग मॉडल फ़ाइलें। ये डाउनलोड प्रति बंडल एक बार होते हैं और `/data` वॉल्यूम में संग्रहीत किए जाते हैं।
अन्य आउटबाउंड ट्रैफ़िक सुविधा-संचालित है: एआई बंडल/मॉडल इंस्टॉलेशन डाउनलोड हस्ताक्षरित रिलीज़ इनपुट; यूआरएल आयात उपयोगकर्ता द्वारा अनुरोधित सार्वजनिक यूआरएल लाता है; और स्पष्ट रूप से कॉन्फ़िगर किए गए OIDC, SAML, OpenTelemetry, webhooks, S3-संगत स्टोरेज, या समान एकीकरण व्यवस्थापक द्वारा चुने गए गंतव्यों से संपर्क करते हैं। रनटाइम मॉडल डाउनलोड डिफ़ॉल्ट रूप से अक्षम हैं। स्वचालित फ़ॉलबैक डाउनलोड को स्पष्ट रूप से सक्षम करने के लिए ही `SNAPOTTER_ALLOW_MODEL_DOWNLOAD=1` सेट करें। एक [ऑफ़लाइन बंडल आयात](/hi/guide/deployment) रनटाइम मॉडल निकास के बिना एआई सुविधाओं का प्रावधान कर सकता है।
**फ़ायरवॉल अनुशंसाएँ:**
| परिदृश्य | आउटबाउंड नियम |
|परिदृश्य|आउटबाउंड नियम|
|---|---|
| Air-gapped (कोई AI नहीं) | कंटेनर से सभी आउटबाउंड ट्रैफ़िक ब्लॉक करें |
| AI बंडल आवश्यक | इंस्टॉल के दौरान `huggingface.co`, `*.xethub.hf.co`, `cdn-lfs.huggingface.co`, `github.com`, `objects.githubusercontent.com`, `storage.googleapis.com`, `pypi.org`, `files.pythonhosted.org` पर HTTPS अनुमति दें, फिर ब्लॉक करें |
| AI इंस्टॉल के बाद | सभी आउटबाउंड ट्रैफ़िक ब्लॉक करें, मॉडल स्थानीय रूप से कैश हो जाते हैं |
|हवा से ही गैप|`SNAPOTTER_TELEMETRY=0` और `SNAPOTTER_ALLOW_MODEL_DOWNLOAD=0` सेट करें, ऑफ़लाइन AI बंडल आयात का उपयोग करें, URL आयात और बाहरी एकीकरण अक्षम करें, फिर निकास को रोकें|
|डिफ़ॉल्ट टेलीमेट्री|अपने ब्राउज़र/नेटवर्क लॉग द्वारा सूचीबद्ध पोस्टहॉग और सेंट्री एंडपॉइंट अनुमति दें; यदि नीति उन्हें अनुमति नहीं देती है तो टेलीमेट्री अक्षम करें|
|एआई बंडल की जरूरत है|स्थापना के दौरान, HTTPS को `huggingface.co, *.xethub.hf.co, cdn-lfs.huggingface.co, github.com, objects.githubusercontent.com, storage.googleapis.com, pypi.org, files.pythonhosted.org` की अनुमति दें; फिर उन होस्ट्स को ब्लॉक करें|
|बाहरी एकीकरण|केवल सटीक व्यवस्थापक-कॉन्फ़िगर OIDC/SAML/OTLP/webhook/ऑब्जेक्ट-स्टोरेज गंतव्यों की अनुमति दें|
बंडल आर्काइव Hugging Face के Xet स्टोरेज से परोस जात है, जो `*.xethub.hf.co` एंडपॉइंट पर समानांतर में स्थानांतरित होता है और यही मल्टी-GB बंडल डाउनलोड को तेज़ बनाता है। यदि आपका फ़ायरवॉल `huggingface.co` की अनुमति देता है पर `*.xethub.hf.co` को ब्लॉक करता है, तो इंस्टॉल फिर भी सफल होत हैं पर एक धीम सिंगल-स्ट्रीम डाउनलोड पर फ़ॉलबैक करते है, इसलिए तेज़ रास्ते पर बने रहने के लिए Xet होस्ट को allowlist करें। पूरी तरह ऑफ़लाइन इंस्टॉल इस सबको छोड़ सकते हैं और इसके बजाय [Offline Bundle Import](/hi/guide/deployment) का उपयोग कर सकते हैं।
बंडल अभिलेखागार को हगिंग फेस के एक्सट स्टोरेज से परोस जात है, जो समानांतर में `*.xethub.hf.co` एंडपॉइंट पर स्थानांतरित होता है और यही मल्टी-जीबी बंडल डाउनलोड को तेज़ बनाता है। यदि आपका फ़ायरवॉल `huggingface.co` की अनुमति देता है लेकिन `*.xethub.hf.co` को ब्लॉक करता है, तो इंस्टॉल अभी भी सफल होत है लेकिन धीम सिंगल-स्ट्रीम डाउनलोड पर वापस आ जाता है, इसलिए तेज़ पथ पर बने रहने के लिए Xet होस्ट को अनुमति दें। पूर्णतः ऑफ़लाइन इंस्टॉल यह सब छोड़ सकते हैं और इसके बजाय [ऑफ़लाइन बंडल आयात](/hi/guide/deployment) का उपयोग कर सकते हैं।
रिवर्स प्रॉक्सी कॉन्फ़िगरेशन (Nginx, Traefik, Caddy, Cloudflare Tunnels) के लिए, [Deployment गाइड](/hi/guide/deployment#reverse-proxy) देखें।
रिवर्स प्रॉक्सी कॉन्फ़िगरेशन (Nginx, ट्रैफ़िक, Caddy, Cloudflare टनल) के लिए, [परिनियोजन गाइड](/hi/guide/deployment#reverse-proxy) देखें।
## Docker Secrets {#docker-secrets}
@@ -255,85 +165,103 @@ spec:
रिसोर्स आकार निर्धारण के लिए, [Hardware Requirements](/hi/guide/deployment#hardware-requirements) देखें।
## Backup and Recovery {#backup-and-recovery}
## बैकअप और रिकवरी {#backup-and-recovery}
स्थायी स्थिति दो वॉल्यूम में विभाजित है:
प्रोडक्शन कंपोज़ स्टैक चार खंडों को परिभाषित करता है। प्रवेश रोकें और समन्वित बैकअप लेने से पहले सक्रिय नौकरियों को समाप्त होने दें ताकि PostgreSQL, Redis और फ़ाइल स्थिति एक ही समय बिंदु का वर्णन करें।
| वॉल्यूम | सामग्री | महत्वपूर्ण? |
|आयतन|अंतर्वस्तु|पुनर्प्राप्ति उपचार|
|---|---|---|
| `SnapOtter-pgdata` | PostgreSQL डेटाबेस (उपयोगकर्ता, सेटिंग्स, पाइपलाइन, जॉब, ऑडिट लॉग) | हाँ |
| `/data` (ऐप वॉल्यूम) | उपयोगकर्ता-अपलोड की गई फ़ाइलें, AI मॉडल, Python venv | आंशिक रूप से (नीचे देखें) |
|`SnapOtter-pgdata`|PostgreSQL उपयोगकर्ता, सेटिंग्स, पाइपलाइन, नौकरियां, फ़ाइल मेटाडेटा और ऑडिट लॉग|गंभीर; पोर्टेबल पुनर्प्राप्ति के लिए फ़ेल-फ़ास्ट लॉजिकल डंप का उपयोग करें|
|`SnapOtter-data`|सहेजे गए लाइब्रेरी ऑब्जेक्ट, लॉग और AI स्थिति (`/data/files, /data/logs, /data/ai, /data/ai/venv`)|संपूर्ण वॉल्यूम का बैकअप लें; स्थान बचाने के लिए, जानबूझकर सभी AI स्थिति को छोड़ दें और उसके बंडलों को पुनः स्थापित करें|
|`SnapOtter-redisdata`|टिकाऊ बुलएमक्यू कतार स्थिति के लिए रेडिस एओएफ|ऐप को रोकने और `SAVE` को बाध्य करने के बाद बैकअप लें; पंक्तिबद्ध कार्य को ठीक से फिर से शुरू करने के लिए आवश्यक है|
|`SnapOtter-workspace`|अस्थायी वस्तु-भंडारण कुंजियाँ (`/tmp/workspace/uploads, /tmp/workspace/outputs`)|सभी कार्य ख़त्म हो जाने या रद्द हो जाने के बाद बैकअप न लें; जब नौकरियाँ सक्रिय हों तो इसे कभी न छोड़ें|
`/data` वॉल्यूम के भीतर:
प्रोजेक्ट नाम के साथ सामान्य रूप से उपसर्ग वॉल्यूम नाम लिखें। यह मानने के बजाय कि `SnapOtter-data` जैसा डिस्प्ले नाम डॉकर वॉल्यूम नाम है, माउंट किए गए कंटेनर से वास्तविक स्रोत वॉल्यूम का समाधान करें।
| पथ | सामग्री | महत्वपूर्ण? |
|---|---|---|
| `/data/uploads/`, `/data/outputs/` | उपयोगकर्ता फ़ाइलें और प्रोसेसिंग परिणाम | हाँ |
| `/data/ai/` | डाउनलोड की गई AI मॉडल फ़ाइलें | नहीं (पुनः-डाउनलोड करने योग्य) |
| `/data/venv/` | Python वर्चुअल एनवायरनमेंट | नहीं (स्टार्ट पर पुनर्निर्मित) |
### डेटाबेस बैकअप {#database-backup}
### Database backup {#database-backup}
स्टैक चलते समय डेटाबेस का बैकअप लेने के लिए `pg_dump` का उपयोग करें:
PostgreSQL के कस्टम संग्रह प्रारूप का उपयोग करें और बैकअप को पूर्ण मानने से पहले संग्रह को सत्यापित करें:
```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
```
वैकल्पिक रूप से, स्टैक बंद करे और `SnapOtter-pgdata` वॉल्यूम का स्नैपशॉट लें:
प्रत्येक बैकअप को एक अलग स्टैक में पुनर्स्थापित करके, डेटाबेस रिकॉर्ड और फ़ाइल चेकसम की जाँच करे और एप्लिकेशन शुरू करके उसका परीक्षण करें। रिपॉजिटरी का `tests/qa/backup-restore-drill.sh` उस रिलीज़ गेट को एक स्पष्ट `QA_IMAGE` के विरुद्ध स्वचालित करता है।
यदि आपका प्लेटफ़ॉर्म इसके बजाय क्रैश-संगत वॉल्यूम स्नैपशॉट लेता है, तो पहले पूरे स्टैक को रोकें और सभी महत्वपूर्ण वॉल्यूम को एक सेट के रूप में स्नैपशॉट लें। चल रहे कंटेनर से एक कच्ची PostgreSQL डेटा-निर्देशिका प्रतिलिपि समर्थित तार्किक बैकअप नहीं है।
### फ़ाइल और कतार बैकअप {#file-and-queue-backup}
फ़ाइल और क्यू वॉल्यूम कैप्चर करने से पहले एप्लिकेशन को रोकें। वास्तविक वॉल्यूम नाम को हल करने के लिए `docker inspect` का उपयोग करें, Redis को उसकी वर्तमान स्थिति को बनाए रखने के लिए बाध्य करें, और स्वामित्व और अनुमतियों को संरक्षित करके संग्रहीत करें:
```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
```
### User files backup {#user-files-backup}
एप्लिकेशन से पहले Redis को पुनरारंभ करें। यदि आप जानबूझकर `/data/ai` को बाहर करते हैं, तो `installed.json` रिकॉर्ड को उसके मॉडल या वर्चुअल वातावरण के बिना संरक्षित करने के बजाय संपूर्ण AI सबट्री को हटा दें। बैकअप फ़ाइलों को एन्क्रिप्टेड, एक्सेस-नियंत्रित और SnapOtter चलाने वाले होस्ट से अलग रखें।
```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 .
```
## अनुपालन कलाकृतियाँ {#compliance-artifacts}
सभी बंडलों में AI मॉडल कुल मिलाकर लगभग 24 GB तक होते हैं। चूँकि वे पुनः-डाउनलोड करने योग्य हैं, स्थान बचाने के लिए बैकअप से `/data/ai/` और `/data/venv/` को बाहर रखें। केवल डेटाबेस और उपयोगकर्ता फ़ाइलें महत्वपूर्ण हैं
प्रत्येक SnapOtter रिलीज़ में निम्नलिखित सुरक्षा कलाकृतियाँ शामिल हैं:
## Compliance Artifacts {#compliance-artifacts}
हर SnapOtter रिलीज़ में निम्नलिखित सुरक्षा आर्टिफ़ैक्ट शामिल होते हैं:
| आर्टिफ़ैक्ट | फ़ॉर्मैट | इसे कहाँ खोजें |
| विरूपण साक्ष्य | प्रारूप | इसे कहां खोजें |
|---|---|---|
| SBOM (CycloneDX) | JSON | [GitHub Release](https://github.com/snapotter-hq/SnapOtter/releases) एसेट: `snapotter-v{version}-sbom.cdx.json` |
| SBOM (SPDX) | JSON | [GitHub Release](https://github.com/snapotter-hq/SnapOtter/releases) एसेट: `snapotter-v{version}-sbom.spdx.json` |
| भेद्यता स्कैन | Trivy JSON | [GitHub Release](https://github.com/snapotter-hq/SnapOtter/releases) एसेट: `snapotter-v{version}-trivy.json` |
| भेद्यता स्कैन | SARIF | [GitHub Security](https://github.com/snapotter-hq/SnapOtter/security) टैब |
| स्थैतिक विश्लेषण | CodeQL (JS/TS + Python) | [GitHub Security](https://github.com/snapotter-hq/SnapOtter/security) टैब, साप्ताहिक + प्रति PR चलता है |
| निर्भरता समीक्षा | GitHub native | प्रति-PR जाँच, उच्च-गंभीरता जोड़ पर विफल |
| Python निर्भरता ऑडिट | pip-audit | हर push पर CI रन लॉग |
| सुरक्षा नीति | Markdown | रिपॉज़िटरी में [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md) |
| निर्भरता अद्यतन | Dependabot | npm, pip, Docker, Actions के लिए स्वचालित साप्ताहिक PR |
| विषय बाइंडिंग जारी करें | कैनोनिकल JSON + GitHub सत्यापन | [GitHub रिलीज़](https://github.com/snapotter-hq/SnapOtter/releases) संपत्ति: `snapotter-v{version}-release-subjects.json` |
| पुरालेख SBOM | CycloneDX और SPDX JSON | रिलीज़ परिसंपत्तियाँ: `snapotter-v{version}-archive-linux-{arch}-sbom.{cdx,spdx}.json` |
| छवि SBOM | CycloneDX और SPDX JSON | रिलीज़ परिसंपत्तियाँ: `snapotter-v{version}-image-linux-{arch}-sbom.{cdx,spdx}.json` |
| भेद्यता स्कैन | Trivy JSON | मिलान वाले `archive-linux-{arch}` या `image-linux-{arch}` उपसर्गों के साथ संपत्तियाँ जारी करें |
| भेद्यता स्कैन | SARIF | [GitHub सुरक्षा](https://github.com/snapotter-hq/SnapOtter/security) टैब |
| स्थैतिक विश्लेषण | CodeQL (JS/TS + Python) | [GitHub सुरक्षा](https://github.com/snapotter-hq/SnapOtter/security) टैब, साप्ताहिक + प्रति पीआर चलता है |
| निर्भरता की समीक्षा | GitHub मूलनिवासी | प्रति-पीआर जाँच, उच्च-गंभीरता वाले परिवर्धन पर विफल रहती है |
| Python निर्भरता ऑडिट | pip-audit | प्रत्येक पुश पर सीआई रन लॉग |
| सुरक्षा नीति | Markdown | [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md) भंडार में |
| निर्भरता अद्यतन | Dependabot | एनपीएम, पिप, Docker, क्रियाओं के लिए स्वचालित साप्ताहिक पीआर |
**अपना खुद का स्कैन चलाना:**
**अपना स्वयं का स्कैन चला रहा है:**
रिलीज़ से SBOM डाउनलोड करें और अपने पसंदीदा टूल से इसे स्कैन करें:
रिलीज़-विषय मेनिफ़ेस्ट डाउनलोड करें और सत्यापित करें कि यह रिलीज़ वर्कफ़्लो द्वारा प्रमाणित किया गया था:
```bash
gh attestation verify snapotter-v2.1.0-release-subjects.json \
--repo snapotter-hq/SnapOtter \
--signer-workflow snapotter-hq/SnapOtter/.github/workflows/release.yml
```
मेनिफेस्ट `releaseTag`, `releaseCommit` और `workflowTriggerCommit` को अलग-अलग रिकॉर्ड करता है। सत्यापित करें कि `releaseCommit` अपरिवर्तनीय टैग से निकाली गई प्रतिबद्धता है, फिर संग्रह, छवि, SBOM के SHA-256 डाइजेस्ट को सत्यापित करें, या `subjects` में इसकी प्रविष्टि के विरुद्ध आपके द्वारा उपभोग किए गए स्कैन को सत्यापित करें। यह अंतर जानबूझकर किया गया है: नव निर्मित रिलीज़ कमिट की जाँच करने से वर्कफ़्लो के OIDC क्रेडेंशियल में कमिट की पहचान नहीं बदलती है।
आप डाउनलोड किए गए SBOM या छवि को सीधे स्कैन भी कर सकते हैं:
```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 और भेद्यता स्कैन उस रिलीज़ के लिए प्रकाशित सटीक इमेज को दर्शाते हैं। डिप्लॉयमेंट के बाद इंस्टॉल किए गए AI मॉडल बंडल SBOM में शामिल नहीं होते क्योंकि वे रनटाइम पर डाउनलोड किए जाते हैं।
::: info
छवि SBOMs और स्कैन उस रिलीज़ के लिए प्रकाशित सटीक वास्तुकला-विशिष्ट छवि को दर्शाते हैं। पुरालेख SBOMs और स्कैन पूर्वनिर्मित पुरालेख का अलग से वर्णन करते हैं। तैनाती के बाद स्थापित AI मॉडल बंडल इन SBOMs में शामिल नहीं हैं क्योंकि वे रनटाइम पर डाउनलोड किए जाते हैं।
:::
+6 -2
View File
@@ -11,7 +11,7 @@ SnapOtter पाँच modalities में files process करता है: i
## Image Formats {#image-formats}
SnapOtter input के लिए 55+ image formats और output के लिए 13 formats का समर्थन करता है।
SnapOtter input के लिए 55+ image formats और output के लिए 17 formats का समर्थन करता है।
## Input Formats {#input-formats}
@@ -104,7 +104,7 @@ SnapOtter input के लिए 55+ image formats और output के लि
| PAM | .pam | Sharp (native) | Arbitrary map |
| PFM | .pfm | Sharp (native) | Float map |
## Output Formats (13) {#output-formats-13}
## Output Formats (17) {#output-formats-13}
| Format | Encoder | Quality Control | Available In |
|--------|---------|----------------|-------------|
@@ -121,6 +121,10 @@ SnapOtter input के लिए 55+ image formats और output के लि
| ICO | ImageMagick CLI | Lossless | Convert tool |
| JP2 | opj_compress CLI | Compression ratio | Convert tool |
| QOI | Inline codec | Lossless | Convert tool |
| PSD | ImageMagick CLI | Lossless | Convert tool |
| PPM | ImageMagick CLI | Lossless | Convert tool |
| EPS | ImageMagick CLI | Lossless | Convert tool |
| TGA | ImageMagick CLI | Lossless | Convert tool |
## Video Formats {#video-formats}
+13 -10
View File
@@ -1,8 +1,9 @@
---
description: "SnapOtter में उपयोगकर्ता, बिल्ट-इन और कस्टम roles, permissions, API keys, teams, sessions, और ऑडिट लॉग प्रबंधित करें।"
i18n_source_hash: 5e28af686c96
i18n_source_hash: bea8955f3aff
i18n_provenance: human
i18n_output_hash: 0afc852d07c9
i18n_output_hash: 0a6bb028b980
i18n_hash_version: 2
---
# उपयोगकर्ता, Roles और Permissions {#users-roles-permissions}
@@ -82,12 +83,12 @@ SnapOtter में तीन बिल्ट-इन roles शामिल ह
| `pipelines:all` | सभी उपयोगकर्ताओं की pipelines देखना और प्रबंधित करना |
| `settings:read` | इंस्टेंस सेटिंग्स देखना |
| `settings:write` | इंस्टेंस सेटिंग्स संशोधित करना |
| `users:manage` | उपयोगकर्ता अकाउंट बनाना, अपडेट करना, और हटाना |
| `users:manage` | अभिनेता की प्राधिकार सीमा के भीतर उपयोगकर्ता खाते बनाएं और प्रबंधित करें |
| `teams:manage` | teams बनाना, अपडेट करना, और हटाना |
| `features:manage` | AI फ़ीचर बंडल इंस्टॉल और प्रबंधित करना |
| `system:health` | health और readiness एंडपॉइंट तक पहुँचना |
| `audit:read` | ऑडिट लॉग देखना और roles सूचीबद्ध करना |
| `compliance:manage` | GDPR लाइफ़साइकल और अनुपालन फ़ीचर प्रबंधित करना |
| `compliance:manage` | जीडीपीआर जीवनचक्र और अनुपालन सुविधाओं को प्रबंधित करें; विनाशकारी उपयोगकर्ता संचालन प्राधिकार-बद्ध रहते हैं |
| `webhooks:manage` | आउटबाउंड webhooks कॉन्फ़िगर करना |
| `security:manage` | सुरक्षा सेटिंग्स प्रबंधित करना (IP allowlist, SSO प्रवर्तन) |
@@ -110,15 +111,17 @@ curl -X POST http://localhost:1349/api/v1/roles \
Role नाम 2-30 अक्षरों के होने चाहिए, लोअरकेस अल्फ़ान्यूमेरिक, हाइफ़न और अंडरस्कोर के साथ।
### एडमिन-आरक्षित permissions {#admin-reserved-permissions}
### प्रत्यायोजित प्रशासन सीमाएँ {#delegated-administration-boundaries}
तीन permissions बिल्ट-इन roles के लिए आरक्षित हैं और कस्टम roles को नहीं सौंपी जा सकतीं:
सभी 17 अनुमतियाँ कस्टम भूमिकाओं के माध्यम से सौंपी जा सकती हैं, लेकिन एक प्रशासनिक अनुमति उस भूमिका को अंतर्निहित `admin` भूमिका के बराबर नहीं बनाती है। `users:manage` द्वारा अधिकृत उपयोगकर्ता उत्परिवर्तन, `compliance:manage` द्वारा अधिकृत विनाशकारी संचालन, और `security:manage` द्वारा अधिकृत कस्टम-भूमिका प्रबंधन अभिनेता के वर्तमान अधिकार से बंधे हैं:
- `compliance:manage`
- `webhooks:manage`
- `security:manage`
- अंतर्निहित भूमिकाएँ `admin` > `editor` > `user` का अनुसरण करती हैं; कस्टम भूमिकाएँ अंतर्निहित भूमिकाओं के नीचे हैं।
- लक्ष्य की अनुमतियाँ अभिनेता की **प्रभावी** अनुमतियों में समाहित होनी चाहिए। इसलिए एक स्कोप्ड एपीआई कुंजी अपने दायरे से छोड़ी गई अनुमतियों का उपयोग नहीं कर सकती है।
- एक लक्ष्य भूमिका की टूल एक्सेस अभिनेता की अपनी टूल एक्सेस में समाहित होनी चाहिए।
- एक अक्षम खाते की जाँच उसकी मूल भूमिका के विरुद्ध की जाती है जब वह भूमिका `disabled:<original-role>` के रूप में दर्ज की जाती है।
- किसी कस्टम भूमिका को हटाने के लिए अंतर्निहित `user` फ़ॉलबैक असाइन करने के लिए प्राधिकरण की भी आवश्यकता होती है; अक्षम सदस्य `disabled:user` के रूप में अक्षम रहते हैं।
roles API इन permissions को शामिल करने वाले किसी भी अनुरोध को अस्वीकार कर देता है। केवल बिल्ट-इन `admin` role के पास इन तक पहुँच है।
वैश्विक क्रेडेंशियल और कॉन्फ़िगरेशन सख्त हैं: SCIM टोकन जारी करने या रद्द करने और इंस्टेंस कॉन्फ़िगरेशन आयात करने के लिए पूर्ण प्रभावी व्यवस्थापक प्राधिकरण के साथ अंतर्निहित `admin` भूमिका की आवश्यकता होती है।
### टूल-स्तरीय permissions {#tool-level-permissions}