Skip to content
smallPict
Mulai Gratis

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 asliPenyimpanan terenkripsi smallPictoriginals/<job_id>/<file> di bucket Anda
File teroptimasiDisajikan dari cdn.smallpict.appoptimized/<job_id>.<ext> di bucket Anda, disajikan dari domain CDN Anda
Kuota penyimpananVelocity 50 GB, Momentum 100 GBTidak dihitung. Anda membayar penyedia penyimpanan Anda.
Bandwidth CDNVelocity 30 GB/bulan, Momentum 200 GB/bulanTidak dihitung. Anda membayar penyedia CDN Anda.
TransformasiDihitung dalam paket AndaDihitung dalam paket Anda
Salinan yang disimpan smallPictYa, selama akun Anda aktifTidak ada. Hanya unggahan pemrosesan sementara, yang dihapus dalam 24 jam.
Purge cacheOtomatisOtomatis, melalui API CDN Anda
Performa, domain, dan biaya CDNsmallPictAnda. 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

  1. Anda menggunakan API Velocity atau Momentum dan masuk sebagai admin akun.
  2. Anda memiliki bucket, serta CDN yang menyajikan file dari bucket tersebut melalui HTTPS.
  3. Endpoint penyimpanan dapat dijangkau dari internet melalui HTTPS. Endpoint privat, internal, dan HTTP biasa akan ditolak.
  4. 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

  1. Buat bucket di region yang Anda inginkan, misalnya my-images di ap-southeast-1. Biarkan Block Public Access tetap aktif.
  2. 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.
  3. Opsional: domain Anda sendiri. Tambahkan nama domain alternatif (misalnya images.example.com) dan sertifikat ke distribusi, lalu arahkan record DNS ke distribusi tersebut.
  4. Buat pengguna IAM (atau role) untuk penyimpanan dengan kebijakan berikut:
JSON
{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Allow",      "Action": [        "s3:PutObject",        "s3:GetObject",        "s3:DeleteObject"      ],      "Resource": "arn:aws:s3:::my-images/*"    }  ]}
  1. Buat pengguna IAM untuk CloudFront (boleh pengguna yang sama) dengan kebijakan berikut. cloudfront:GetDistribution bersifat opsional; dengan izin ini, smallPict dapat mendeteksi domain distribusi saat Anda mengosongkan domain CDN.
JSON
{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Allow",      "Action": [        "cloudfront:CreateInvalidation",        "cloudfront:GetDistribution"      ],      "Resource": "arn:aws:cloudfront::123456789012:distribution/E2QWRUHAPOMQZL"    }  ]}
  1. Di dasbor:
    • Penyedia penyimpanan Amazon S3, bucket my-images, region ap-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.net bawaan distribusi.

B. Cloudflare R2 + Cloudflare

  1. Buat bucket R2, misalnya my-images.
  2. 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 pengembangan r2.dev untuk produksi.
  3. 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.
  4. Buat Cloudflare API token (My Profile → API Tokens) untuk zone tersebut dengan Zone → Cache Purge → Purge. Zone → Zone → Read bersifat opsional.
  5. Di dasbor:
    • Penyedia penyimpanan Cloudflare R2, bucket my-images, endpoint https://<account_id>.r2.cloudflarestorage.com (terlihat di detail S3 API bucket Anda), region auto, 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.

C. Google Cloud Storage + Cloudflare

Google Cloud Storage dihubungkan melalui XML API-nya yang kompatibel dengan S3 menggunakan kunci HMAC.

  1. Buat bucket, misalnya my-images.
  2. Buat service account dan berikan peran Storage Object User (roles/storage.objectUser) hanya pada bucket ini.
  3. Buat kunci HMAC untuk service account tersebut: Cloud Storage → Settings → Interoperability → Create a key for a service account. Salin access ID dan secret-nya.
  4. 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 kepada allUsers membuat seluruh bucket dapat dibaca, termasuk originals/. Jika file asli Anda harus tetap privat, pasang lapisan autentikasi di depannya (misalnya Cloudflare Worker yang menandatangani permintaan ke bucket).
  5. Arahkan record DNS Cloudflare yang di-proxy ke Cloud Storage, misalnya images.example.com. Namai bucket sesuai hostname dan gunakan CNAME yang di-proxy ke c.storage.googleapis.com, atau gunakan Cloudflare Origin Rule yang mengirim permintaan ke storage.googleapis.com dengan nama bucket di awal path.
  6. Buat Cloudflare API token untuk zone tersebut dengan Zone → Cache Purge → Purge (Zone → Zone → Read opsional).
  7. Di dasbor: penyedia penyimpanan Google Cloud Storage, bucket, endpoint https://storage.googleapis.com, region auto, access ID dan secret HMAC; CDN Cloudflare, zone ID, API token, dan domain CDN https://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.

PenyediaPilihan di dasborEndpointCatatan
MinIOMinIOServer Anda, mis. https://minio.example.comPermintaan path-style aktif. Server harus dapat dijangkau dari internet melalui HTTPS.
Hetzner Object StorageKustom kompatibel S3https://<location>.your-objectstorage.com
WasabiKustom kompatibel S3https://s3.<region>.wasabisys.com
Vultr Object StorageKustom kompatibel S3https://<region>.vultrobjects.com
SumoPod StorageSumoPod StorageDari dasbor penyimpanan SumoPod AndaPath-style aktif secara default.
Alibaba Cloud OSSAlibaba Cloud OSShttps://oss-<region>.aliyuncs.comHanya virtual-hosted style.
Tencent Cloud COSTencent Cloud COShttps://cos.<region>.myqcloud.comNama bucket menyertakan APPID Anda, mis. my-images-1250000000.
DigitalOcean SpacesDigitalOcean Spaceshttps://<region>.digitaloceanspaces.com
  1. Buat bucket dan kunci yang dibatasi pada bucket tersebut dengan izin put, get, dan delete pada objek (lihat Izin minimal di bawah).
  2. Buat optimized/ dapat dibaca oleh CDN Anda, misalnya dengan bucket policy yang mengizinkan s3:GetObject anonim hanya pada optimized/*. Di MinIO:
JSON
{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Allow",      "Principal": {        "AWS": [          "*"        ]      },      "Action": [        "s3:GetObject"      ],      "Resource": [        "arn:aws:s3:::my-images/optimized/*"      ]    }  ]}
  1. Tempatkan Cloudflare di depan bucket: record DNS yang di-proxy untuk images.example.com yang 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).
  2. Buat Cloudflare API token untuk zone tersebut dengan Zone → Cache Purge → Purge (Zone → Zone → Read opsional).
  3. Di dasbor: pilih penyedia dari tabel, masukkan bucket, endpoint, region (auto jika 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.

PenyediaIzin
Amazon S3s3:PutObject, s3:GetObject, s3:DeleteObject pada arn:aws:s3:::<bucket>/*
Amazon CloudFrontcloudfront:CreateInvalidation pada distribusi; cloudfront:GetDistribution opsional agar domain dapat dideteksi
Cloudflare R2R2 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 StorageKunci HMAC untuk service account dengan roles/storage.objectUser pada bucket
Alibaba Cloud OSSPengguna RAM dengan oss:PutObject, oss:GetObject, oss:DeleteObject pada bucket
Tencent Cloud COSSub-pengguna CAM dengan cos:PutObject, cos:GetObject, cos:DeleteObject pada bucket (nama bucket menyertakan APPID)
DigitalOcean SpacesAccess key Spaces yang dibatasi pada bucket dengan izin baca, tulis, dan hapus
MinIO / kustom kompatibel S3Put, 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:

  1. Penyimpanan: menulis file uji kecil di .smallpict-probe/ dalam bucket Anda, membacanya kembali, lalu menghapusnya.
  2. Cloudflare: mengirim satu purge uji untuk satu URL ke zone Anda.
  3. 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, izinkan GET dan HEAD dari origin situs Anda.

Tata letak objek dan URL

ApaKey di bucket AndaURL
File aslioriginals/<job_id>/<file>Tidak disajikan
File teroptimasioptimized/<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.app tetap 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.