SnapOtter memproses file sepenuhnya di infrastruktur Anda. SnapOtter mengirim analitik produk dan laporan crash yang anonim serta bebas konten secara default untuk membantu meningkatkan proyek. SnapOtter tidak pernah mengirim file Anda, nama file, isi file, output OCR, metadata gambar, atau teks dokumen. Umpan balik opsional dikirim hanya setelah pengguna mengirimkannya, hanya ketika analitik diaktifkan, dan bidang kontak disertakan hanya dengan persetujuan kontak eksplisit. Administrator dapat mematikan penangkapan analitik dan umpan balik dalam satu klik di bawah Settings > System > Privacy, tanpa rebuild diperlukan. Pemrosesan file selalu tetap di dalam kontainer Anda.
Kontainer berjalan sebagai pengguna non-root khusus (`snapotter`) dengan semua kapabilitas Linux dihapus kecuali set minimum yang diperlukan. Untuk kebijakan pengungkapan kerentanan lengkap dan arsitektur keamanan, lihat [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md) di GitHub.
File Compose [CPU](https://github.com/snapotter-hq/SnapOtter/blob/main/docker/docker-compose.yml) dan [GPU](https://github.com/snapotter-hq/SnapOtter/blob/main/docker/docker-compose-gpu.yml) kanonik adalah sumber kebenarannya. Jangan menyalin contoh yang disingkat ke dalam produksi; menyebarkan file dari tag rilis yang Anda verifikasi.
- Batas memori, swap, CPU, dan PID berisi pemrosesan asli yang tidak terkendali.
- Setiap layanan menghilangkan semua kemampuan Linux. Aplikasi hanya menambahkan kembali `CHOWN, SETUID, SETGID, DAC_OVERRIDE, FOWNER, KILL` untuk kepemilikan volume, penurunan identitas `gosu` satu arah, dan penerusan sinyal yang baik. PostgreSQL dan Redis hanya menerima subset yang dibutuhkan oleh titik masuk resmi mereka.
-`security_opt: [no-new-privileges:true]` mencegah proses dalam aplikasi, PostgreSQL, dan kontainer Redis mendapatkan hak istimewa tambahan. Ini tetap kompatibel dengan `gosu`: titik masuk dimulai sebagai root, menyiapkan volume, dan hanya turun ke pengguna `snapotter` khusus.
- Input gambar PostgreSQL dan Redis disematkan oleh intisari. Aplikasi juga harus disematkan ke tag rilis atau intisari yang terverifikasi, bukan `latest`.
- Pemeriksaan kesehatan, rotasi log JSON yang dibatasi, Redis AOF yang tahan lama, dan kebijakan mulai ulang ditentukan secara terpusat dalam file kanonik.
Untuk penerapan yang terhubung ke internet, ikat port 1349 ke loopback dan akhiri TLS pada proksi terbalik yang dikelola. Hasilkan kredensial PostgreSQL dan Redis yang unik, simpan rahasia dalam file yang dilindungi atau manajer rahasia, dan segera ubah kata sandi administrator awal.
`read_only: true` tidak disetel karena pemetaan ulang PUID/PGID menulis ke `/etc/passwd` dan `/etc/group` saat startup. Jika Anda menggunakan flag `--user` Docker atau Kubernetes `runAsUser` dan bukan PUID/PGID, Anda dapat dengan aman mengaktifkan sistem file root read-only.
Pemrosesan file bersifat lokal, namun instalasi default **bukan sistem bebas jalan keluar**. Analisis produk anonim menggunakan PostHog dan pelaporan kerusakan menggunakan Sentry saat telemetri diaktifkan. Setel `SNAPOTTER_TELEMETRY=0` (atau nonaktifkan analitik pada Pengaturan > Sistem > Privasi) untuk mematikan keduanya. SnapOtter tidak pernah menyertakan file yang diunggah, nama file, output OCR, teks dokumen, atau konten file lainnya dalam acara tersebut.
Lalu lintas keluar lainnya didorong oleh fitur: unduhan instalasi bundel/model AI, input rilis yang ditandatangani; Impor URL mengambil URL publik yang diminta pengguna; dan OIDC, SAML, OpenTelemetry, webhook, penyimpanan yang kompatibel dengan S3, atau integrasi serupa yang dikonfigurasi secara eksplisit, hubungi tujuan yang dipilih oleh administrator. Pengunduhan model saat runtime dinonaktifkan secara default. Tetapkan `SNAPOTTER_ALLOW_MODEL_DOWNLOAD=1` hanya untuk mengaktifkan pengunduhan fallback otomatis secara eksplisit. [Impor paket offline](/id/guide/deployment) dapat menyediakan fitur AI tanpa keluarnya model runtime.
|Celah udara|Setel `SNAPOTTER_TELEMETRY=0` dan `SNAPOTTER_ALLOW_MODEL_DOWNLOAD=0`, gunakan impor bundel AI offline, nonaktifkan impor URL dan integrasi eksternal, lalu blokir jalan keluar|
|Telemetri bawaan|Izinkan titik akhir PostHog dan Sentry dicantumkan oleh log browser/jaringan Anda; nonaktifkan telemetri jika kebijakan tidak mengizinkannya|
|Paket AI diperlukan|Selama instalasi, izinkan HTTPS ke `huggingface.co, *.xethub.hf.co, cdn-lfs.huggingface.co, github.com, objects.githubusercontent.com, storage.googleapis.com, pypi.org, files.pythonhosted.org`; lalu blokir host tersebut|
|Integrasi eksternal|Izinkan hanya tujuan OIDC/SAML/OTLP/webhook/penyimpanan objek yang dikonfigurasikan oleh administrator|
Arsip bundel disajikan dari penyimpanan Xet Hugging Face, yang ditransfer melalui titik akhir `*.xethub.hf.co` secara paralel dan membuat pengunduhan bundel multi-GB menjadi cepat. Jika firewall Anda mengizinkan `huggingface.co` tetapi memblokir `*.xethub.hf.co`, penginstalan masih berhasil tetapi kembali ke pengunduhan aliran tunggal yang lebih lambat, jadi izinkan host Xet untuk tetap berada di jalur cepat. Penginstalan yang sepenuhnya offline dapat melewati semua ini dan menggunakan [Impor Paket Offline](/id/guide/deployment) sebagai gantinya.
Untuk deployment produksi, hindari meneruskan secret sebagai variabel lingkungan teks biasa. Entrypoint mendukung konvensi `_FILE` Docker: mount sebuah secret sebagai file dan atur variabel `_FILE` yang sesuai ke path-nya.
Secret Docker Compose (tanpa Swarm) membutuhkan Compose v2.23 atau lebih baru.
:::
## Deployment Kubernetes {#kubernetes-deployment}
Entrypoint mendeteksi ketika kontainer sudah berjalan sebagai non-root (misalnya, melalui `runAsUser` Kubernetes) dan melewati penurunan hak istimewa gosu secara otomatis. Dalam kasus itu ia tidak dapat chown volume yang di-mount sendiri, jadi ia memverifikasi bahwa volume dapat ditulis dan keluar lebih awal dengan panduan yang dapat ditindaklanjuti jika tidak, lihat [Izin penyimpanan](/id/guide/deployment#storage-permissions) untuk penyiapan `fsGroup` dan UID asing (TrueNAS, OpenShift).
**SecurityContext Pod yang direkomendasikan:**
```yaml
apiVersion:apps/v1
kind:Deployment
metadata:
name:snapotter
spec:
replicas:1
selector:
matchLabels:
app:snapotter
template:
metadata:
labels:
app:snapotter
spec:
securityContext:
runAsNonRoot:true
runAsUser:999
runAsGroup:999
fsGroup:999
containers:
- name:snapotter
image:snapotter/snapotter:latest
ports:
- containerPort:1349
securityContext:
allowPrivilegeEscalation:false
capabilities:
drop:[ALL]
resources:
requests:
cpu:"1"
memory:2Gi
limits:
cpu:"4"
memory:6Gi
livenessProbe:
httpGet:
path:/api/v1/health
port:1349
initialDelaySeconds:60
periodSeconds:30
timeoutSeconds:5
readinessProbe:
httpGet:
path:/api/v1/health
port:1349
initialDelaySeconds:10
periodSeconds:10
timeoutSeconds:5
volumeMounts:
- name:data
mountPath:/data
- name:workspace
mountPath:/tmp/workspace
volumes:
- name:data
persistentVolumeClaim:
claimName:snapotter-data
- name:workspace
emptyDir:
medium:Memory
sizeLimit:2Gi
```
Karena `runAsUser: 999` diatur pada tingkat pod, entrypoint melewati gosu sepenuhnya. Ini memungkinkan kapabilitas `allowPrivilegeEscalation: false` dan `drop: [ALL]` tanpa konflik.
Untuk penentuan ukuran sumber daya, lihat [Persyaratan Perangkat Keras](/id/guide/deployment#hardware-requirements).
## Pencadangan dan Pemulihan {#backup-and-recovery}
Tumpukan Compose produksi mendefinisikan empat volume. Hentikan ingress dan biarkan pekerjaan aktif selesai sebelum mengambil cadangan terkoordinasi sehingga PostgreSQL, Redis, dan status file menggambarkan titik waktu yang sama.
|`SnapOtter-pgdata`|Pengguna PostgreSQL, pengaturan, saluran pipa, pekerjaan, metadata file, dan log audit|Kritis; gunakan dump logis cepat gagal untuk pemulihan portabel|
|`SnapOtter-data`|Objek perpustakaan yang disimpan, log, dan status AI (`/data/files, /data/logs, /data/ai, /data/ai/venv`)|Cadangkan seluruh volume; untuk menghemat ruang, dengan sengaja hilangkan semua status AI dan instal ulang bundelnya|
|`SnapOtter-redisdata`|Redis AOF untuk status antrean BullMQ yang tahan lama|Cadangkan setelah menjeda aplikasi dan memaksa `SAVE`; diperlukan untuk melanjutkan pekerjaan yang antri dengan tepat|
|`SnapOtter-workspace`|Kunci penyimpanan objek sementara (`/tmp/workspace/uploads, /tmp/workspace/outputs`)|Jangan membuat cadangan setelah semua pekerjaan dihentikan atau dibatalkan; jangan pernah membuangnya saat pekerjaan sedang aktif|
Biasanya menulis awalan nama volume dengan nama proyek. Selesaikan volume sumber sebenarnya dari kontainer yang terpasang alih-alih berasumsi bahwa nama tampilan seperti `SnapOtter-data` adalah nama volume Docker.
Uji setiap cadangan dengan mengembalikannya ke tumpukan terisolasi, memeriksa catatan database dan checksum file, dan memulai aplikasi. `tests/qa/backup-restore-drill.sh` repositori mengotomatiskan gerbang rilis tersebut terhadap `QA_IMAGE` eksplisit.
Jika platform Anda mengambil snapshot volume yang konsisten dengan error, hentikan seluruh tumpukan terlebih dahulu dan ambil snapshot semua volume penting sebagai satu set. Salinan direktori data PostgreSQL mentah dari kontainer yang berjalan bukan merupakan cadangan logis yang didukung.
### File dan antrian cadangan {#file-and-queue-backup}
Jeda aplikasi sebelum mengambil file dan volume antrian. Gunakan `docker inspect` untuk menyelesaikan nama volume sebenarnya, memaksa Redis untuk mempertahankan kondisinya saat ini, dan mengarsipkan dengan kepemilikan dan izin yang dipertahankan:
Mulai ulang Redis sebelum aplikasi. Jika Anda sengaja mengecualikan `/data/ai`, hapus seluruh subpohon AI daripada mempertahankan data `installed.json` tanpa model atau lingkungan virtualnya. Jaga agar file cadangan tetap terenkripsi, dikontrol aksesnya, dan terpisah dari host yang menjalankan SnapOtter.
Manifes mencatat `releaseTag`, `releaseCommit`, dan `workflowTriggerCommit` secara terpisah. Verifikasi bahwa `releaseCommit` adalah komit yang dikupas dari tag yang tidak dapat diubah, lalu verifikasi intisari SHA-256 dari arsip, gambar, SBOM, atau pindaian yang Anda gunakan terhadap entri di `subjects`. Perbedaan ini disengaja: memeriksa komit rilis yang baru dibuat tidak mengubah identitas komit dalam kredensial OIDC alur kerja.
Anda juga dapat memindai SBOM atau gambar yang diunduh secara langsung:
Gambar SBOMs dan pindaian mencerminkan gambar spesifik arsitektur yang dipublikasikan untuk rilis tersebut. Arsip SBOMs dan pindaian menjelaskan arsip bawaan secara terpisah. Bundel model AI yang diinstal setelah penerapan tidak disertakan dalam SBOMs ini karena diunduh saat runtime.