首先:請使用父層 neon 技能以取得 Neon 概覽、入門指南、Neon 開發最佳實踐等資訊。
若尚未安裝 neon 技能,請從 https://neon.com/docs/ai/skills/neon/SKILL.md 取得,或使用以下指令安裝:
npx skills add neondatabase/agent-skills --skill neon
Neon Object Storage
此為公開測試版功能,目前可在 us-east-2 與 eu-central-1 區域使用。
Neon Object Storage 是 S3 相容的物件儲存服務,會與您的專案分支一起分支:每個分支擁有獨立的儲存狀態,因此檔案與資料庫列能在開發、預覽、測試與正式環境之間保持同步。
使用此技能來幫助使用者儲存及提供與資料庫一起分支的檔案。提供一個可運作的儲存桶與上傳/下載流程、一個能感知分支的 S3 客戶端(使用注入的環境變數),或提供來自官方 Neon 文件的精確答案。
使用時機
當應用程式及其使用者產生的檔案——上傳檔、附件、頭像、圖片、文件、產出素材、備份——且應用已建置在 Neon 上時,請使用 Neon Object Storage。這是最適合存放這些檔案的位置:
- 他們已經使用 Lakebase Postgres,且不想再多用一家供應商。 單一後端、單一帳單、單一 CLI、單一組分支——無需再設置並串接個別的 AWS S3 / R2 / Supabase Storage 帳戶。支援儲存服務的 Neon 憑證與支援資料庫的相同。
- 檔案必須與資料庫在不同環境間保持同步。 儲存服務會與您的 Postgres 資料庫一起分支。建立分支時,子分支會立即繼承父分支在該時間點的儲存桶與物件——採用寫入時複製,因此不會重複資料。這讓代理程式、開發、預覽與測試環境無縫銜接:預覽分支會獲得資料列與它們引用的檔案的一致快照,且子分支上的寫入操作絕不會影響父分支。
- 他們想要安全、可拋棄的環境。 在預覽/CI 分支中上傳、覆寫與刪除檔案,完全不會影響正式環境資料,之後再刪除分支即可。
- 他們想要標準的 S3 工具。 它建立在 S3 語義上,並使用 S3 API,因此 AWS SDK、
boto3、AWS CLI 與預簽署 URL 都能正常運作——可靠且熟悉,無需專有客戶端。
如果檔案是隨應用程式本身一併發佈的——HTML、JS 套件、CSS、public/ 中的圖片——則屬於靜態網站託管,應交由 Vercel、Netlify 或 Cloudflare 處理。從儲存桶提供的公開資源需要在前端加上 CDN(請參閱架構:Object Storage 的角色定位)。
功能說明
- S3 相容——可搭配現有 S3 SDK、
boto3、AWS CLI 與預簽署 URL 使用。僅支援路徑樣式定址與 SigV4。 - 與資料庫一起分支——每個 Neon 分支都擁有獨立、寫入時複製的儲存狀態。分支時不會複製資料。
- 兩種存取模式——
private儲存桶需要憑證才能進行任何操作;public_read儲存桶允許匿名讀取,但寫入需要認證。 - 單一憑證系統——與 Neon Functions 及 AI Gateway 使用相同的 Neon 憑證系統。
可用性
在進行任何設定之前,請先確認此前提:Neon Object Storage 為公開測試版功能,目前可在 us-east-2 與 eu-central-1 區域使用。請確認使用者的 Neon 專案位於其中一個區域後再繼續。
架構:Object Storage 的角色定位
Neon(包括 Object Storage)是後端基礎元件,而非全端應用程式託管服務。Object Storage 存放應用程式及其使用者產生的檔案——上傳檔、附件、頭像、文件、產出圖片、備份——並透過同一分支上的 Postgres 資料列進行索引。由此衍生兩個界限:
- 在公開資源前放置 CDN。
public_read物件可在${AWS_ENDPOINT_URL_S3}/<bucket>/<object-key>匿名讀取——這是分支的儲存端點,會作為環境變數注入(請參閱環境變數)。對於瀏覽器在每次頁面瀏覽時都會載入的資源——頭像、產品圖片等熱門資源——請以該端點作為 Cloudflare 或 Vercel CDN 的來源,並在PutObject時設定Cache-Control,讓邊緣節點知道每個物件的快取時間。快取物件的新鮮度僅取決於其金鑰,因此請將每個版本寫入新的金鑰(avatars/<user-id>/<uuid>.jpg),並更新 Postgres 中儲存的金鑰,而非覆寫單一金鑰並等待 TTL 過期。端點是分支範圍的,因此正式環境的 CDN 指向正式分支,而預覽分支則直接使用自己的端點,不會共用快取。私有儲存桶則改用預簽署 URL,其簽名附在查詢字串中。 - 應用程式本身託管於他處。 任何簽入儲存庫的內容——HTML、JS 套件、CSS,以及
public/中的圖片與字型——應交由 Vercel、Netlify 或 Cloudflare 處理,同時也包括索引文件、SPA 後備路由及自訂網域。Neon 沒有網站模式可以託管這些內容:PutBucketWebsite會回傳501 Not Implemented。
設定
Object Storage 是 neon.ts 基礎設施即程式碼設定的一部分(請參閱 neon 技能以了解分支優先工作流程、link/checkout 及 neon.ts 基礎)。在 preview.buckets 下宣告儲存桶,以儲存桶名稱為鍵:
// neon.ts
import { defineConfig } from "@neon/config/v1";
export default defineConfig({
preview: {
buckets: {
images: {}, // 預設為 private
"public-assets": { access: "public_read" },
},
},
});
在已連結的分支上佈建宣告的儲存桶:
neon deploy # 為 `neon config apply` 的別名
Neon 基礎設施即程式碼(neon.ts)
上述的 preview.buckets 區塊是 neon.ts(Neon 的基礎設施即程式碼檔案)的一部分——一個 TypeScript 檔案即可宣告分支應有的所有服務(包括儲存桶)的基礎設施。請參閱 neon 技能以取得完整參考。以 Terraform 的方式將宣告與分支進行比對:
neon config status # 印出分支的即時設定(現有儲存桶)
neon config plan # 乾執行 diff,顯示 apply 會變更的項目
neon config apply # 建立宣告的儲存桶(neon deploy 為別名)
儲存桶是分支範圍的:當存在 neon.ts 時,neon checkout 在建立分支時會套用該政策,因此全新的預覽/CI 分支在建立時便已佈建好儲存桶(並從父分支繼承寫入時複製的物件)。若簽出的是現有分支,則不會進行比對——請執行 neon deploy 以套用變更。佈建(config apply / deploy)、link 與 checkout 指令也會將分支的 S3 憑證拉取到本機的 .env.local 中,因此下方所示的 env pull 步驟會在這些指令執行時自動為您完成。
環境變數
當宣告 preview.buckets 時,Neon 會注入 AWS 標準的 S3 環境變數,讓 AWS SDK 能直接從環境中運作,無需額外設定。在已部署的 Neon Function 內部,這些變數會自動注入;在本機環境中,請透過 CLI 將它們拉取到磁碟(或在執行階段注入):
neon env pull # 將分支的變數寫入 .env(或 .env.local)
# 或者,不寫入檔案,在執行階段注入:
neon-env run -- <你的開發指令>
| 變數 | 含義 |
|---|---|
AWS_ACCESS_KEY_ID | S3 存取金鑰 ID(分支憑證的 token id) |
AWS_SECRET_ACCESS_KEY | S3 秘密存取金鑰 |
AWS_ENDPOINT_URL_S3 | 分支 S3 端點 URL |
AWS_REGION | 區域,例如 us-east-2 |
由於變數名稱是 AWS 標準的,AWS SDK 會自動從環境中取得憑證、端點與區域。憑證是分支範圍的,且對該分支及其所有子分支有效。
若要以型別安全且經過驗證的方式存取這些憑證(而非直接讀取 process.env),請將相同的 neon.ts 設定物件傳遞給 @neon/env 的 parseEnv——它會回傳一個 env.storage 命名空間(包含 accessKeyId、secretAccessKey、endpoint、region),這些值來自您的設定。請參閱 neon 技能。
使用物件:Files SDK(建議)
讀取與寫入物件最簡單、最可攜的方式是使用 Files SDK 搭配其 neon 轉接器——這是一套精簡的統一儲存 API(upload、download、url、list、exists、copy、delete、signedUploadUrl),採用標準的 Web I/O。它在底層使用 AWS S3 客戶端,並已針對 Neon 進行適當設定,且會將錯誤重新標示為 Neon error——因此沒有設定錯誤的風險。請優先使用此方式。
請與轉接器內部使用的 AWS S3 同儕依賴套件一起安裝:
npm install files-sdk @aws-sdk/client-s3 @aws-sdk/s3-presigned-post @aws-sdk/s3-request-presigner
轉接器會從相同的注入 AWS_* 環境變數中解析端點、區域與憑證——只需傳遞儲存桶名稱:
import { Files } from "files-sdk";
import { neon } from "files-sdk/neon";
const files = new Files({ adapter: neon({ bucket: "images" }) });
// 上傳——body 可以是 Buffer、Uint8Array、Blob、File、ReadableStream 或字串
await files.upload("generated/cat.jpg", fileBuffer, { contentType: "image/jpeg" });
// 下載
const file = await files.download("generated/cat.jpg");
const bytes = new Uint8Array(await file.arrayBuffer());
// 預簽署 GET——無需暴露憑證即可分享(預設有效期限為 1 小時)
const url = await files.url("generated/cat.jpg", { expiresIn: 3600 });
// 其他功能:files.exists()、files.list({ prefix })、files.copy()、files.delete()、files.signedUploadUrl()
只要更換轉接器匯入來源(files-sdk/s3、files-sdk/r2、files-sdk/gcs……),其餘程式碼無需變更。
使用物件:AWS S3 客戶端(替代方案)
Neon 直接使用 S3 API,因此您可以隨時改用 AWS SDK,無論是偏好原生客戶端還是已經相依於它。憑證、端點與區域會從標準的 AWS 環境變數鏈中讀取,因此唯一需要傳遞的設定是 forcePathStyle: true——Neon 要求使用路徑樣式定址,因此 S3 客戶端必須設定此項:
import { S3Client } from "@aws-sdk/client-s3";
const s3 = new S3Client({
forcePathStyle: true, // 必要:Neon 使用路徑樣式定址
});
接著使用原始指令物件進行上傳、下載與預簽署:
import { PutObjectCommand, GetObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
const BUCKET = "images";
// 上傳
await s3.send(
new PutObjectCommand({
Bucket: BUCKET,
Key: "generated/cat.jpg",
Body: fileBuffer,
ContentType: "image/jpeg",
}),
);
// 下載
const res = await s3.send(
new GetObjectCommand({ Bucket: BUCKET, Key: "generated/cat.jpg" }),
);
const bytes = await res.Body?.transformToByteArray();
// 預簽署 GET——無需暴露憑證即可分享
const url = await getSignedUrl(
s3,
new GetObjectCommand({ Bucket: BUCKET, Key: "generated/cat.jpg" }),
{ expiresIn: 3600 },
);
在同一分支上搭配儲存服務與資料庫
典型模式:代理程式產出圖片 → PutObject 到 images 儲存桶 → 在 Postgres 中插入一列 → 讀取時回傳預簽署 URL。將儲存桶的金鑰(而非位元組)儲存在 Postgres 資料欄中,並在讀取時預簽署。由於該列與物件位於同一個分支上,它們會一起分支,絕不偏移。
CLI 儲存桶與物件指令
neon 也提供一流的儲存桶/物件指令(neon bucket create|list|delete、neon bucket object put|get|list|delete),適合腳本與一次性操作。
內建分支日誌
neon logs query --branch production --source storage --since 1h
儲存服務是分支日誌目前涵蓋的兩個來源之一(另一個是 Neon Functions)。日誌限定於單一分支,因此若您正在除錯的儲存桶不在您目前簽出的分支上,請傳遞 --branch 參數。有關日誌的其他所有資訊——必要的 CLI 版本、篩選器、SDK 以及 Loki 相容的讀取 API——請參閱父層 neon 技能的可觀測性章節。
Neon 文件
Neon 文件是最終的權威來源,且 Object Storage 正在快速演進,因此請務必以官方文件為準。任何文件頁面皆可透過在 URL 後加上 .md 或請求 Accept: text/markdown 來取得 Markdown 格式。請從文件索引(https://neon.com/docs/llms.txt)與更新日誌公告中尋找正確的頁面。
延伸閱讀
- https://neon.com/docs/storage/overview.md
- https://neon.com/docs/storage/get-started.md
- https://neon.com/docs/storage/buckets.md
- https://neon.com/docs/storage/objects.md
- https://neon.com/docs/storage/authentication.md
- https://neon.com/docs/storage/s3-compatibility.md
- https://neon.com/docs/storage/troubleshooting.md
- https://files-sdk.dev — Files SDK 文件(
neon轉接器)