Community程式設計與開發github.com

neondatabase/neon-object-storage

Neon Object Storage 是與資料庫分支整合的 S3 相容物件儲存服務,讓檔案與資料列在開發、預覽、測試與正式環境之間保持同步。

neon-object-storage 是什麼?

Neon Object Storage 是一項與 Neon 資料庫分支深度整合的 S3 相容物件儲存服務,目前為公開測試版,支援 `us-east-2` 與 `eu-central-1` 區域。它讓每個分支擁有獨立的儲存狀態,透過寫入時複製(copy-on-write)技術,分支時不複製資料,確保檔案與資料庫列在開發、預覽、測試與正式環境間保持一致。 技能支援兩種使用路徑:推薦使用 **Files SDK**(`files-sdk` 搭配 `neon` 轉接器),提供統一的 `upload`、`download`、`url` 等 API;或直接使用 **AWS S3 Client**,只需設定 `forcePathStyle: true` 即可。技能會解釋如何在 `neon.ts` 中宣告儲存桶、使用 `neon deploy` 佈建、透過標準 AWS 環境變數(`AWS_ACCESS_KEY_ID`、`AWS_SECRET_ACCESS_KEY`、`AWS_ENDPOINT_URL_S3`、`AWS_REGION`)進行認證,以及搭配 CDN 與預簽署 URL 的最佳實踐。 此技能適用於已經採用 Neon 的專案,避免引入第二家儲存供應商,並提供安全的可拋棄式環境。它透過 `neon` CLI 提供儲存桶與物件操作命令,以及內建的分支日誌功能。若使用者尚未安裝,會引導先安裝父層 `neon` 技能以取得 Neon 概覽與基礎設定。

相容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/neondatabase/agent-skills/tree/main/skills/neon-object-storage

Installed? Explore more 程式設計與開發 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

首先:請使用父層 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_IDS3 存取金鑰 ID(分支憑證的 token id)
AWS_SECRET_ACCESS_KEYS3 秘密存取金鑰
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)與更新日誌公告中尋找正確的頁面。

延伸閱讀

Individual skills in this repo

This repo contains 7 individual skills — each has its own dedicated page.

neondatabase/claimable-postgres

Provision instant temporary Postgres databases via Claimable Postgres by Neon (neon.new) with no login, signup, or credit card. Supports REST API, CLI, and SDK. Use when users ask for a quick Postgres environment, a throwaway DATABASE_URL for prototyping/tests, or "just give me a DB now". Triggers include: "quick postgres", "temporary postgres", "no signup database", "no credit card database", "instant DATABASE_URL", "npx neon-new", "neon.new", "neon.new API", "claimable postgres API".

neondatabase/neon

>-

neondatabase/neon-ai-gateway

>-

neondatabase/neon-functions

>-

neondatabase/neon-postgres

Guides and best practices for working with Neon Serverless Postgres. Covers setup, connection methods, branching, autoscaling, scale-to-zero, read replicas, connection pooling, Neon Auth, and the Neon CLI, MCP server, REST API, TypeScript SDK, and Python SDK. Use when users ask about "Neon setup", "connect to Neon", "Neon project", "DATABASE_URL", "serverless Postgres", "Neon CLI", "neonctl", "Neon MCP", "Neon Auth", "@neondatabase/serverless", "@neondatabase/neon-js", "scale to zero", "Neon autoscaling", "Neon read replica", or "Neon connection pooling".

neondatabase/neon-postgres-branches

>-

neondatabase/neon-postgres-egress-optimizer

Diagnose and fix excessive Postgres egress (network data transfer) in a codebase. Use when a user mentions high database bills, unexpected data transfer costs, network transfer charges, egress spikes, "why is my Neon bill so high", "database costs jumped", SELECT * optimization, query overfetching, reduce Neon costs, optimize database usage, or wants to reduce data sent from their database to their application. Also use when reviewing query patterns for cost efficiency, even if the user doesn't explicitly mention egress or data transfer.

相關技能