慣性聚合 高效追蹤和閱讀你感興趣的部落格、新聞、科技資訊
閱讀原文 在慣性聚合中打開

推薦訂閱源

小众软件
小众软件
博客园 - 叶小钗
有赞技术团队
有赞技术团队
大猫的无限游戏
大猫的无限游戏
博客园_首页
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
L
LangChain Blog
Hugging Face - Blog
Hugging Face - Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
aimingoo的专栏
aimingoo的专栏
Blog — PlanetScale
Blog — PlanetScale
爱范儿
爱范儿
T
Tailwind CSS Blog
Jina AI
Jina AI
量子位
Stack Overflow Blog
Stack Overflow Blog
人人都是产品经理
人人都是产品经理
J
Java Code Geeks
V
Visual Studio Blog
月光博客
月光博客

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python)
在AWS + Cloudflare上免費寄宿網站
Mark Gerald · 2026-05-28 · via DEV Community

你好,你好!想用幾乎沒有花費的方式在AWS上部署一個網站,並且還帶有GitHub自動部署流程?這就是這篇文章要教你的,沒有拖泥帶水.

這個想法很簡單:找一個現成的倉儲(開源,MIT,最後有鏈接),了解背後運作的方式,並且適應到你的專案。可以是作品集、首頁、靜態文件、React、Vue、Vite、Astro的SPA。只要最後能生成HTML/CSS/JS,就行。

在代碼崩潰前,我們快速對齊三個概念。有經驗的話,請直接跳到實際操作部分.

AWS,這是什麼?

AWS是亞馬遜的雲服務。你不需要購買伺服器,插上電源然後祈禱它不會崩潰,而是按需租用"塊塊"基礎設施。從簡單的(在S3上存儲文件)到複雜的(管理的Kubernetes集群、多區域數據庫、生成式AI等)。

供宿主靜態網站,我們會使用四個基本小工具:

  • S3:對象儲存。想像一下雲端中的一個資料夾,你把你的檔案放進去。
  • CloudFront:全球CDN。將網站分發到AWS的全球邊緣伺服器,所以東京的人載入快速就像聖保羅的人一樣。
  • ACM: SSL憑證管理器。免費HTTPS,自動更新。
  • IAM: 控制誰能做什麼。權限、角色等。

Cloudflare,在AWS之外,作為DNS供應商登錄。它的免費方案已經能解決,不需要購買Route 53。

基礎設施即代碼(IaC),是為了什麼?

歌劇摘要:你不需要點擊AWS控制台,而是在代碼文件中描述基礎設施。優點:

  • 可在Git中進行版本控制.
  • 使用一個命令即可部署到任何環境.
  • 如果出錯,可以通過diff來檢查.
  • 基礎設施的代碼審查,老兄.

最知名的工具有:Terraform、Pulumi、CloudFormation (來自AWS) 和 AWS CDK,我們要使用什麼?

AWS CDK,這是什麼?

CDK = Cloud Development Kit。它是用於在 AWS 上編寫基礎設施的「現代」方式。你不需要編寫巨大的 YAML/JSON(純 CloudFormation),而是編寫 TypeScript、Python、Java、Go 或 C#。CDK 將其編譯為 CloudFormation,然後 AWS 執行。

優勢:您獲得自動補全、類型檢查、高階抽象(稱為「構建式」)。您不必為 CloudFront 配置 20 個功能,包括 OAC、私有 S3 和桶策略,您只需實例化一個類別即可完成。

關於 CDK 堆疊的一個簡單例子:

export class MinhaStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const bucket = new s3.Bucket(this, 'MeuBucket', {
      blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
      encryption: s3.BucketEncryption.S3_MANAGED,
    });
  }
}

進入全螢幕模式 退出全螢幕模式

即時,這樣就會建立一個已啟用加密的私有 S3。無需點擊任何地方。

我們要搭建的架構如下:

網站的流程是這樣:

Arquitetura

翻譯:

  1. 用戶在瀏覽器中訪問 seusite.com
  2. Cloudflare 解析 DNS 並指向 CloudFront。
  3. CloudFront 透過 HTTPS (ACM 証書) 使用 OAC 來拉取 S3 個人化儲存空間的檔案.
  4. S3 從不會變成公開.

與它溝通的就只有 CloudFront.

  1. 而在部署方面:main您會將 branch 推送到 __JHSNS_SEG_98a392ea_43__.
  2. GitHub Actions 透過 OIDC 自動認證 AWS (無固定 access key,更安全).
  3. 執行 cdk deploy,進行s3 sync 指令無效,清除 CloudFront 缓存。

很棒呢? 馬上部署運行吧。

存儲庫

專案已上傳,MIT 授權,隨意克隆:

github.com/markgerald/aws-cdk-static-site-starter

提供英文葡萄牙文的文件版本。 在這篇帖子裡我將總結幸福的路徑.

前置條件

在做任何事之前,你需要:

  • AWS帳戶(有免費套餐,可以免費玩)。
  • 安裝Node.js 22+.
  • 設定AWS CLI (aws configure).
  • 在Cloudflare上擁有域作為權威DNS。

如果你從未安裝Node/AWS CLI,這裡有一個逐步教程:本地安裝.

要設定Cloudflare,請按照這個:Cloudflare中的域名、DNS和SSL/TLS.

克隆並設定.env

git clone https://github.com/markgerald/aws-cdk-static-site-starter.git
cd aws-cdk-static-site-starter
cp .env.example .env

全屏模式 退出全屏模式

打開.env沒有編輯器就無法調整。這是設定中的核心:

PROJECT_NAME=meu-site
DOMAIN_NAME=meusite.com
WWW_DOMAIN_NAME=www.meusite.com

AWS_ACCOUNT_ID=123456789012
AWS_REGION=eu-west-1
CERTIFICATE_REGION=us-east-1

ENABLE_SPA_FALLBACK=true

CREATE_GITHUB_OIDC_ROLE=false
GITHUB_OWNER=seuuser
GITHUB_REPO=seu-repo
GITHUB_BRANCH=main
GITHUB_OIDC_PROVIDER_ARN=

進入全螢幕模式 離開全螢幕模式

注意兩點:

  • CERTIFICATE_REGION tem要成為us-east-1. CloudFront 只接受此區域的特定 ACM,是 AWS 的規則。
  • AWS_REGION可以是你想要的任何地方。我使用eu-west-1按預設,但sa-east-1 (São Paulo) 功能相同.

安裝並進行 bootstrap

npm install

# Bootstrap nas duas regiões (cert e stack principal)
npx cdk bootstrap aws://123456789012/us-east-1
npx cdk bootstrap aws://123456789012/eu-west-1

Enter fullscreen mode Exit fullscreen mode

Bootstrap 是 CDK 在賬戶上進行的一個 "初始設定"。創建資產儲存桶、設置部署角色等。每個區域運行一次即可忘記.

首次部署

npm run build
npm run build:site
npm test

npx cdk deploy --all --require-approval never

Enter fullscreen mode 退出全螢幕模式

第一次,ACM 會停留等待 DNS 驗證。這是這樣的:AWS 需要確認域名是您的。它會提供一些奇怪的 CNAME 供您複製到 Cloudflare.

前往 AWS 控制台> ACM> 地區 us-east-1> 你的證書。它顯示了類似:

Name:  _abc123.meusite.com
Value: _xyz789.acm-validations.aws
Type:  CNAME

Enter fullscreen mode Exit fullscreen mode

複製這些到 Cloudflare, DNS only (灰雲,無代理)。等待幾分鐘,ACM 標記 Issued 並繼續部署。

驗證的細節:教學雲端(Cloudflare) ACM 沒有儲存庫.

指定域名給 CloudFront

堆疊建立後,CDK 會回傳類似 d111111abcdef8.cloudfront.net 的輸出。前往 Cloudflare 並建立:

Type   Name   Target
CNAME  @      d111111abcdef8.cloudfront.net
CNAME  www    d111111abcdef8.cloudfront.net

進入全螢幕模式 離開全螢幕模式

DNS 僅限模式開始. 若後來想啟用 Cloudflare 的橘色代理,請使用全模式 (嚴格模式) 在 SSL/TLS 上。絕不使用靈活模式 (會產生重定向迴圈).

開啟瀏覽器,訪問 https://meusite.com,應該會載入倉儲的範例頁面.

如何適用於您的網站

現在來到重點部分:如何安裝 至您的 網站不是範例位置.

網站文件夾是 website_src/. 預設帶有一個最小化的 React + Vite. 結構:

website_src/
├── favicon.svg
├── index.html
├── src/
│   └── (componentes React)
├── tsconfig.json
└── vite.config.ts

Enter fullscreen mode Exit fullscreen mode

你有兩個選擇:

選項 1: 將你的專案整個放在 website_src/

更簡單。刪除內容。website_src/ 需要將您的專案導出(Next.js、Astro、Vue、純HTML,任何東西都可以)。調整 build:sitepackage.json 上以運行您的框架的建置。目前是這樣的:

"build:site": "vite build --config website_src/vite.config.ts"

Enter fullscreen mode Exit fullscreen mode

如果您使用Astro,就變成這樣:

"build:site": "cd website_src && npm install && npm run build"

Enter fullscreen mode Exit fullscreen mode

重要的在於的建置最終檔案需要放在website_dist/,因為是這個資料夾會讓部署程式上傳到S3。請將您的框架的輸出設定為指向那裡:

// vite.config.ts
export default defineConfig({
  build: {
    outDir: '../website_dist',
  },
});

Enter fullscreen mode Exit fullscreen mode

選項2:作為單一倉庫使用

您將您的網站放在一個獨立的倉庫中,產生檔案,然後放上去website_dist/ 只做部署。如果前端團隊和基礎設施團隊是分開的,那這就很有用。

純 HTML?沒問題。

如果你的網站只是 HTML/CSS/JS 靜態內容,直接把所有東西都放到 website_dist/

mkdir -p website_dist
cp -r meu-site-pronto/* website_dist/

Enter fullscreen mode Exit fullscreen mode

然後禁用 SPA fallback(當沒有客戶端路由時,不需要 fallback 到 index.html):

ENABLE_SPA_FALLBACK=false

進入全螢幕模式 離開全螢幕模式

部署網站

設定並編譯後:

npm run build:site

BUCKET_NAME=$(aws cloudformation describe-stacks \
  --stack-name aws-cdk-static-site-starter-static-site \
  --region eu-west-1 \
  --query "Stacks[0].Outputs[?OutputKey=='WebsiteBucketName'].OutputValue" \
  --output text)

DISTRIBUTION_ID=$(aws cloudformation describe-stacks \
  --stack-name aws-cdk-static-site-starter-static-site \
  --region eu-west-1 \
  --query "Stacks[0].Outputs[?OutputKey=='CloudFrontDistributionId'].OutputValue" \
  --output text)

aws s3 sync website_dist/ "s3://${BUCKET_NAME}" --delete --cache-control "public,max-age=300"
aws cloudfront create-invalidation --distribution-id "$DISTRIBUTION_ID" --paths "/*"

進入全螢幕模式 離開全螢幕模式

這個create-invalidation是用來強制 CloudFront 查找新版本。沒有這個,它可能會提供過期的快取,持續數分鐘或數小時。

提示:可以將這些放在腳本deploy-site.sh中一次性執行.

在 GitHub Actions 中自動化所有操作

手動操作有助於學習。在生產環境中,您希望將代碼推送至 main 分支並自動更新網站.

這個倉庫已經包含兩個工作流程

  • .github/workflows/ci.yml:在 PR 和 push 時運行,執行 build/test/synth,無需 AWS 凭據。
  • .github/workflows/deploy.yml: 在 main 中推動,透過 OIDC 自動認證,執行 cdk deploy,同步並失效.

OIDC 是一個很棒的機制:你不需要將 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY 作為密鑰存放在 GitHub(這些會在日誌中洩露),GitHub Actions 會請求一個臨時的 AWS 凭據,這個憑據信任 GitHub 的 OIDC 提供者。沒有固定金鑰,無需手動輪換。

為了建立具有 OIDC 認證的 IAM 角色,請在 .env 中啟用:

CREATE_GITHUB_OIDC_ROLE=true
GITHUB_OWNER=seuuser
GITHUB_REPO=seu-repo
GITHUB_BRANCH=main

Enter fullscreen mode Exit fullscreen mode

重新運行 npx cdk deploy,複製 output GithubActionsRoleArn,並將其添加為 GitHub 中的 Repository Variable

AWS_ROLE_ARN=arn:aws:iam::123456789012:role/...github-actions-deploy

Enter fullscreen mode Exit fullscreen mode

與其他變數一起(與.env的相同鍵):

AWS_ACCOUNT_ID=123456789012
AWS_REGION=eu-west-1
DOMAIN_NAME=meusite.com
WWW_DOMAIN_NAME=www.meusite.com
PROJECT_NAME=meu-site
CERTIFICATE_REGION=us-east-1
ENABLE_SPA_FALLBACK=true
CREATE_GITHUB_OIDC_ROLE=false
GITHUB_OWNER=seuuser
GITHUB_REPO=seu-repo
GITHUB_BRANCH=main

進入全螢幕模式 退出全螢幕模式

這樣就可以在Actions中推送至main,並在Actions的build、deploy、sync、invalidation上變得聰明。所有都是自動的.

這個遊戲要花多少錢?

對於一個小網站(每月幾千次點擊),成本是每個月幾分錢 或免費,取決於用量:

  • ACM:對CloudFront的公證書是免費的
  • S3:收存储和請求費用。小網站僅需幾分錢。
  • CloudFront: 免費方案每月非常慷慨(1 TB 傳輸量 + 10M 請求)。除此之外,需要付費。
  • Cloudflare DNS: 免費方案解析。

可能增加成本的:

  • CloudFront 高流量(超出免費方案範圍)。
  • 頻繁且廣泛的失效(/* 直接,每天多次)。
  • 啟用 WAF、日誌、Lambda@Edge、CloudFront Functions 而無需

因此該專案有意不啟用這些功能。如果您需要,後續再啟用,並清楚成本

安全,豈能忘記

設定已預設包含:

  • S3帶有BlockPublicAccess從未暴露過。
  • CloudFront 存取 S3 透過 OAC (現代方式),非 OAI 遺留方式.
  • HTTP 自動重定向至 HTTPS.
  • 工作流程使用 OIDC,無長壽存取金鑰.

在生產環境中,將部署角色的 AdministratorAccess 替換為權限較低的策略。readme 文件說明了如何操作.

而關於 "刪除所有內容" 的部分?

想結束這個玩笑嗎?先清空你的bucket(Bucket)吧。autoDeleteObjectsfalse為了避免自定義資源,有意識地):

BUCKET_NAME=$(aws cloudformation describe-stacks \
  --stack-name aws-cdk-static-site-starter-static-site \
  --region eu-west-1 \
  --query "Stacks[0].Outputs[?OutputKey=='WebsiteBucketName'].OutputValue" \
  --output text)

aws s3 rm "s3://${BUCKET_NAME}" --recursive
npx cdk destroy --all

進入全螢幕模式 離開全螢幕模式

不要忘記在 Cloudflare 也刪除 CNAMEs。

Pra 關閉

總結一下發生了什麼:

  • 你學習 (或複習) 了 AWS、IaC 和 CDK.
  • 在 AWS 上部署了一個靜態網站,帶有 HTTPS、全球 CDN 和 Cloudflare 的 DNS.
  • 透過 GitHub Actions 配置了自動部署,並使用 OIDC.
  • 幾乎沒有花錢在這上面.

這個專案是開源的,放在 github.com/markgerald/aws-cdk-static-site-starter. 喜歡就給個星星。如果發現錯誤或有建議,請發送 PR 或開啟 issue.

有疑問嗎?在下方留言,我會回覆.

謝謝,說完啦!👋


有用連結