Gunakan Penyimpanan + CDN Sendiri
Hubungkan object storage dan CDN milik Anda sendiri di paket API Velocity dan Momentum: penyiapan per penyedia, izin minimal, pemeriksaan koneksi, dan apa yang terjadi saat Anda beralih mode.
Tersedia di: paket API Velocity dan Momentum. Tidak tersedia di Ignite (tidak memiliki CDN), di sandbox pengembang (file sandbox bersifat sementara), maupun di paket WordPress (memakai CDN smallPict terkelola).
Singkatnya: Dalam mode BYO, smallPict menulis file asli dan gambar teroptimasi Anda ke bucket Anda, dan CDN Anda yang menyajikannya. Penyimpanan dan CDN selalu terhubung bersama: Anda tidak dapat membawa salah satunya tanpa yang lain.
Apa itu BYO
Velocity dan Momentum memiliki dua mode pengiriman. Anda memilih salah satunya di Dasbor → CDN & penyimpanan.
- Terkelola (default): smallPict menyimpan file asli Anda di penyimpanan terenkripsinya (dipindahkan ke arsip jangka panjang setelah 90 hari) dan menyajikan gambar teroptimasi dari
cdn.smallpict.app. Tidak ada yang perlu disiapkan. - Gunakan penyimpanan + CDN sendiri (BYO): Anda menghubungkan bucket yang kompatibel dengan S3 di akun Anda sendiri dan CDN di akun Anda sendiri. Setiap job baru menulis file asli dan file teroptimasi ke bucket Anda, dan API mengembalikan URL di domain CDN Anda.
Aturan keterikatan ini ada karena smallPict harus dapat menjalankan kedua sisi pengiriman: menulis file dan membersihkan salinan usang dari cache. Bucket tanpa CDN membuat purge cache tidak punya tujuan; CDN tanpa bucket tidak punya apa pun untuk disajikan.
Terkelola vs. BYO
| Terkelola (default) | Gunakan penyimpanan + CDN sendiri | |
|---|---|---|
| File asli | Penyimpanan terenkripsi smallPict | originals/<job_id>/<file> di bucket Anda |
| File teroptimasi | Disajikan dari cdn.smallpict.app | optimized/<job_id>.<ext> di bucket Anda, disajikan dari domain CDN Anda |
| Kuota penyimpanan | Velocity 50 GB, Momentum 100 GB | Tidak dihitung. Anda membayar penyedia penyimpanan Anda. |
| Bandwidth CDN | Velocity 30 GB/bulan, Momentum 200 GB/bulan | Tidak dihitung. Anda membayar penyedia CDN Anda. |
| Transformasi | Dihitung dalam paket Anda | Dihitung dalam paket Anda |
| Salinan yang disimpan smallPict | Ya, selama akun Anda aktif | Tidak ada. Hanya unggahan pemrosesan sementara, yang dihapus dalam 24 jam. |
| Purge cache | Otomatis | Otomatis, melalui API CDN Anda |
| Performa, domain, dan biaya CDN | smallPict | Anda. smallPict tidak bertanggung jawab atas performa, domain, atau tagihan CDN Anda. |
Penyedia yang didukung
Penyimpanan (tersedia sekarang): Amazon S3, Cloudflare R2, Google Cloud Storage (interoperabilitas S3), Alibaba Cloud OSS, Tencent Cloud COS, DigitalOcean Spaces, SumoPod Storage, MinIO, dan layanan lain yang kompatibel dengan S3 melalui endpoint kustom (misalnya Hetzner, Vultr, atau Wasabi).
CDN (tersedia sekarang): Cloudflare dan Amazon CloudFront.
Direncanakan: Azure Blob Storage dan CDN lainnya. Anda dapat meminta akses awal di halaman Penyedia cloud.
Sebelum memulai
- Anda menggunakan API Velocity atau Momentum dan masuk sebagai admin akun.
- Anda memiliki bucket, serta CDN yang menyajikan file dari bucket tersebut melalui HTTPS.
- Endpoint penyimpanan dapat dijangkau dari internet melalui HTTPS. Endpoint privat, internal, dan HTTP biasa akan ditolak.
- Anda sudah membuat kunci terbatas untuk smallPict (lihat Izin minimal di bawah). Jangan gunakan kunci root atau admin akun Anda.
Lalu buka Dasbor → CDN & penyimpanan, pilih Gunakan penyimpanan + CDN sendiri, isi kedua bagian, lalu pilih Simpan penyimpanan + CDN. smallPict menjalankan pemeriksaan koneksi (dijelaskan di bawah) dan hanya mengalihkan Anda ke BYO jika pemeriksaan itu lulus.
Panduan penyiapan
A. Amazon S3 + Amazon CloudFront
- Buat bucket di region yang Anda inginkan, misalnya
my-imagesdiap-southeast-1. Biarkan Block Public Access tetap aktif. - Buat distribusi CloudFront dengan bucket tersebut sebagai origin. Gunakan Origin access control (OAC) agar CloudFront dapat membaca bucket sementara bucket tetap privat, lalu terapkan bucket policy yang ditawarkan CloudFront.
- Opsional: domain Anda sendiri. Tambahkan nama domain alternatif (misalnya
images.example.com) dan sertifikat ke distribusi, lalu arahkan record DNS ke distribusi tersebut. - Buat pengguna IAM (atau role) untuk penyimpanan dengan kebijakan berikut:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:DeleteObject" ], "Resource": "arn:aws:s3:::my-images/*" } ]}- Buat pengguna IAM untuk CloudFront (boleh pengguna yang sama) dengan kebijakan berikut.
cloudfront:GetDistributionbersifat opsional; dengan izin ini, smallPict dapat mendeteksi domain distribusi saat Anda mengosongkan domain CDN.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "cloudfront:CreateInvalidation", "cloudfront:GetDistribution" ], "Resource": "arn:aws:cloudfront::123456789012:distribution/E2QWRUHAPOMQZL" } ]}- Di dasbor:
- Penyedia penyimpanan Amazon S3, bucket
my-images, regionap-southeast-1, endpoint kosong (endpoint standar untuk region tersebut yang dipakai), serta access key ID dan secret penyimpanan. - CDN Amazon CloudFront, distribution ID (misalnya
E2QWRUHAPOMQZL), access key ID dan secret CloudFront, dan secara opsional domain CDN (https://images.example.com). Kosongkan domain untuk memakai domain*.cloudfront.netbawaan distribusi.
- Penyedia penyimpanan Amazon S3, bucket
B. Cloudflare R2 + Cloudflare
- Buat bucket R2, misalnya
my-images. - Hubungkan custom domain ke bucket (R2 → bucket Anda → Settings → Custom Domains), misalnya
images.example.com, pada zone di akun Cloudflare yang sama. Permintaan ke domain tersebut melewati cache Cloudflare. Jangan gunakan URL pengembanganr2.devuntuk produksi. - Buat R2 API token (R2 → Manage API tokens) dengan Object Read & Write, yang dibatasi hanya untuk bucket ini. Salin Access Key ID dan Secret Access Key yang ditampilkan.
- Buat Cloudflare API token (My Profile → API Tokens) untuk zone tersebut dengan Zone → Cache Purge → Purge. Zone → Zone → Read bersifat opsional.
- Di dasbor:
- Penyedia penyimpanan Cloudflare R2, bucket
my-images, endpointhttps://<account_id>.r2.cloudflarestorage.com(terlihat di detail S3 API bucket Anda), regionauto, serta R2 Access Key ID dan Secret Access Key. - CDN Cloudflare, zone ID (halaman Overview domain, bagian API), API token, dan domain CDN
https://images.example.com.
- Penyedia penyimpanan Cloudflare R2, bucket
C. Google Cloud Storage + Cloudflare
Google Cloud Storage dihubungkan melalui XML API-nya yang kompatibel dengan S3 menggunakan kunci HMAC.
- Buat bucket, misalnya
my-images. - Buat service account dan berikan peran Storage Object User (
roles/storage.objectUser) hanya pada bucket ini. - Buat kunci HMAC untuk service account tersebut: Cloud Storage → Settings → Interoperability → Create a key for a service account. Salin access ID dan secret-nya.
- Buat file teroptimasi dapat dibaca oleh CDN Anda. Cloudflare mengambil file dari Cloud Storage melalui HTTPS, sehingga objek di bawah
optimized/harus dapat dibaca publik. Dengan uniform bucket-level access, memberikan peran Storage Object Viewer kepadaallUsersmembuat seluruh bucket dapat dibaca, termasukoriginals/. Jika file asli Anda harus tetap privat, pasang lapisan autentikasi di depannya (misalnya Cloudflare Worker yang menandatangani permintaan ke bucket). - Arahkan record DNS Cloudflare yang di-proxy ke Cloud Storage, misalnya
images.example.com. Namai bucket sesuai hostname dan gunakan CNAME yang di-proxy kec.storage.googleapis.com, atau gunakan Cloudflare Origin Rule yang mengirim permintaan kestorage.googleapis.comdengan nama bucket di awal path. - Buat Cloudflare API token untuk zone tersebut dengan Zone → Cache Purge → Purge (Zone → Zone → Read opsional).
- Di dasbor: penyedia penyimpanan Google Cloud Storage, bucket, endpoint
https://storage.googleapis.com, regionauto, access ID dan secret HMAC; CDN Cloudflare, zone ID, API token, dan domain CDNhttps://images.example.com.
D. MinIO atau penyimpanan lain yang kompatibel dengan S3 + Cloudflare
Bagian ini mencakup MinIO dan layanan yang kompatibel dengan S3 seperti Hetzner, Wasabi, Vultr, SumoPod, Alibaba Cloud OSS, Tencent Cloud COS, dan DigitalOcean Spaces.
| Penyedia | Pilihan di dasbor | Endpoint | Catatan |
|---|---|---|---|
| MinIO | MinIO | Server Anda, mis. https://minio.example.com | Permintaan path-style aktif. Server harus dapat dijangkau dari internet melalui HTTPS. |
| Hetzner Object Storage | Kustom kompatibel S3 | https://<location>.your-objectstorage.com | |
| Wasabi | Kustom kompatibel S3 | https://s3.<region>.wasabisys.com | |
| Vultr Object Storage | Kustom kompatibel S3 | https://<region>.vultrobjects.com | |
| SumoPod Storage | SumoPod Storage | Dari dasbor penyimpanan SumoPod Anda | Path-style aktif secara default. |
| Alibaba Cloud OSS | Alibaba Cloud OSS | https://oss-<region>.aliyuncs.com | Hanya virtual-hosted style. |
| Tencent Cloud COS | Tencent Cloud COS | https://cos.<region>.myqcloud.com | Nama bucket menyertakan APPID Anda, mis. my-images-1250000000. |
| DigitalOcean Spaces | DigitalOcean Spaces | https://<region>.digitaloceanspaces.com |
- Buat bucket dan kunci yang dibatasi pada bucket tersebut dengan izin put, get, dan delete pada objek (lihat Izin minimal di bawah).
- Buat
optimized/dapat dibaca oleh CDN Anda, misalnya dengan bucket policy yang mengizinkans3:GetObjectanonim hanya padaoptimized/*. Di MinIO:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": [ "*" ] }, "Action": [ "s3:GetObject" ], "Resource": [ "arn:aws:s3:::my-images/optimized/*" ] } ]}- Tempatkan Cloudflare di depan bucket: record DNS yang di-proxy untuk
images.example.comyang mengarah ke host publik bucket. Jika penyedia membutuhkan hostname-nya sendiri dalam permintaan, tambahkan Cloudflare Origin Rule yang menulis ulang header Host (dan, untuk host path-style, menambahkan nama bucket ke path). - Buat Cloudflare API token untuk zone tersebut dengan Zone → Cache Purge → Purge (Zone → Zone → Read opsional).
- Di dasbor: pilih penyedia dari tabel, masukkan bucket, endpoint, region (
autojika penyedia tidak memilikinya) dan kunci; aktifkan permintaan path-style jika tabel menyebutkannya; lalu CDN Cloudflare, zone ID, API token, dan domain CDN.
Izin minimal
Berikan smallPict kunci yang hanya dapat melakukan apa yang dibutuhkan, pada satu bucket.
| Penyedia | Izin |
|---|---|
| Amazon S3 | s3:PutObject, s3:GetObject, s3:DeleteObject pada arn:aws:s3:::<bucket>/* |
| Amazon CloudFront | cloudfront:CreateInvalidation pada distribusi; cloudfront:GetDistribution opsional agar domain dapat dideteksi |
| Cloudflare R2 | R2 API token dengan Object Read & Write, dibatasi pada bucket |
| Cloudflare (CDN) | API token untuk zone dengan Zone → Cache Purge → Purge; Zone → Zone → Read opsional |
| Google Cloud Storage | Kunci HMAC untuk service account dengan roles/storage.objectUser pada bucket |
| Alibaba Cloud OSS | Pengguna RAM dengan oss:PutObject, oss:GetObject, oss:DeleteObject pada bucket |
| Tencent Cloud COS | Sub-pengguna CAM dengan cos:PutObject, cos:GetObject, cos:DeleteObject pada bucket (nama bucket menyertakan APPID) |
| DigitalOcean Spaces | Access key Spaces yang dibatasi pada bucket dengan izin baca, tulis, dan hapus |
| MinIO / kustom kompatibel S3 | Put, get, dan delete pada <bucket>/*; endpoint harus berupa HTTPS publik |
Pemeriksaan koneksi
Setiap kali Anda menyimpan (dan saat Anda memilih Periksa ulang), smallPict memeriksa seluruh koneksi sebelum memakainya:
- Penyimpanan: menulis file uji kecil di
.smallpict-probe/dalam bucket Anda, membacanya kembali, lalu menghapusnya. - Cloudflare: mengirim satu purge uji untuk satu URL ke zone Anda.
- CloudFront: membuat satu invalidasi uji untuk path
/.smallpict-probe/.... Invalidasi ini dihitung dalam jatah path invalidasi CloudFront Anda untuk bulan tersebut.
Jika ada langkah yang gagal, tidak ada yang dialihkan. Dasbor menampilkan alasannya di samping kolom yang bersangkutan, misalnya nama bucket atau API token. Pemeriksaan koneksi dibatasi 5 percobaan per menit.
Akses bucket untuk CDN Anda
optimized/harus dapat dibaca oleh CDN Anda: baik public-read pada prefiks tersebut, maupun akses origin CDN ke bucket privat (origin access control CloudFront, atau custom domain R2).originals/dapat tetap privat. CDN Anda tidak pernah membutuhkannya.- CORS hanya diperlukan jika browser mengambil gambar lintas origin dari JavaScript (misalnya
fetch()atau canvas). Tag<img>biasa tidak membutuhkannya. Jika Anda memerlukannya, izinkanGETdanHEADdari origin situs Anda.
Tata letak objek dan URL
| Apa | Key di bucket Anda | URL |
|---|---|---|
| File asli | originals/<job_id>/<file> | Tidak disajikan |
| File teroptimasi | optimized/<job_id>.<ext> | <cdn_domain>/optimized/<job_id>.<ext> |
Domain CDN dapat menyertakan prefiks path, misalnya https://example.com/images; URL-nya kemudian menjadi https://example.com/images/optimized/<job_id>.<ext>.
Header cache
File teroptimasi ditulis dengan Cache-Control: public, max-age=31536000, immutable. Setiap job mendapat key yang unik, sehingga hasil baru selalu memiliki URL baru dan purge jarang diperlukan. Pastikan aturan caching CDN Anda tidak menimpa header ini dengan waktu yang lebih singkat.
Purge cache
- Permintaan purge yang dibuat melalui API (
POST /v1/purge) dikirim ke CDN Anda, secara batch. - Di Cloudflare, file di-purge berdasarkan URL. "Purge all" hanya mem-purge host pengiriman dan prefiks path Anda, bukan seluruh zone Anda.
- Di CloudFront, file di-purge dengan invalidasi. "Purge all" membuat invalidasi
/*. Path invalidasi yang melebihi jatah gratis bulanan CloudFront ditagihkan oleh AWS ke akun Anda.
Beralih mode
Beralih mode tidak memindahkan file yang sudah ada. File yang sudah dikirim tetap memakai URL-nya saat ini; hanya job baru yang memakai mode baru.
- Terkelola → BYO: job baru masuk ke bucket Anda dan disajikan oleh CDN Anda. File yang sudah ada di
cdn.smallpict.apptetap di sana. - BYO → terkelola: job baru kembali memakai penyimpanan dan CDN terkelola. Pengaturan dan kunci BYO Anda tetap tersimpan tetapi tidak digunakan, sehingga Anda dapat beralih kembali tanpa memasukkannya lagi, sampai Anda memilih Putuskan.
- Putuskan: menghapus kunci dan pengaturan BYO yang tersimpan lalu mengembalikan Anda ke mode terkelola. File di bucket Anda tidak disentuh.
Saat terjadi kegagalan
- Jika smallPict tidak dapat menulis ke bucket Anda, smallPict mencoba ulang, lalu menggagalkan job dengan alasan yang dapat Anda baca di respons API.
- Dasbor menampilkan kesalahan terakhir dan waktu terjadinya, dengan tombol Periksa ulang.
- Anda menerima satu email per insiden, bukan satu per job yang gagal.
- smallPict tidak pernah beralih ke penyimpanan terkelola sebagai cadangan. File Anda tidak pernah disimpan di tempat yang tidak Anda pilih.
Keamanan
- Kunci disimpan di penyimpanan rahasia terenkripsi. Kunci tidak pernah ditampilkan lagi, tidak pernah dikembalikan oleh API, dan tidak pernah ditulis ke log.
- Untuk merotasi kunci, masukkan kunci baru lalu simpan; pemeriksaan koneksi berjalan dengan kunci baru tersebut. Biarkan kolom kunci kosong untuk mempertahankan kunci yang tersimpan.
- Endpoint penyimpanan dan CDN harus menggunakan HTTPS. Endpoint yang mengarah ke alamat privat, loopback, link-local, atau alamat internal lainnya akan ditolak.
- Gunakan kunci terpisah dan terbatas untuk smallPict, dan cabut kunci tersebut di konsol penyedia Anda jika Anda berhenti memakai BYO.