AWS帳號代開服務 AWS S3 靜態網站託管詳細步驟
第一章:你到底在用 S3 做什麼
把網站部署到 S3,本質上是把「靜態檔案」放到一個可靠的物件儲存空間,然後讓瀏覽器能透過固定的 URL 取得這些檔案。靜態網站託管的意思,是 S3 會在特定條件下回應特定的首頁檔案(例如 index.html),並把請求導到正確的物件。
你可以把它想成:S3 負責「存放與發送檔案」,而不是負責「運行後端邏輯」。因此適合放前端頁面(HTML、CSS、JavaScript)、影像、字型、甚至是一些簡易的單頁式應用(SPA)資源。
當你理解這一點,後面所有設定就更像是解謎:你是在告訴 S3 哪個檔案要當首頁、哪些檔案要可公開存取、以及當有人訪問某個路徑時,S3 要怎麼找到對應檔案。
第二章:部署前的準備工作
2.1 準備你的靜態網站檔案
在開始前,先確認你有一個可部署的輸出資料夾。典型情況包括:
- index.html:首頁。
- assets 或其他資料夾:CSS、JS、圖片、字型等。
若你使用前端框架(React、Vue、Angular、Svelte 等),通常建置後會得到一個 build 或 dist 資料夾。你要上傳的,就是那個資料夾內的內容。
2.2 決定是公開網站還是受控網站
靜態網站託管常見兩種模式:
- 公開讀取:任何人只要有 URL 就能看見網站內容。多數展示型網站會用這個。
- 限制存取:使用授權或 CloudFront 等方式控制。S3 自身也能做一定程度的權限,但「靜態網站託管」的直覺路徑通常偏向公開。
你需要先想清楚,因為「公有讀取」涉及 IAM/Bucket Policy/封鎖性設定,稍後會看到很多人卡關就卡在這裡。
2.3 檢查網域與 HTTPS 的需求
如果你只是測試,S3 網站端點就夠用了;但如果你要正式上線,通常會搭配自訂網域與 HTTPS。這會涉及 CloudFront 更常見,但本文仍會把 S3 網站託管的基本自訂網域流程交代清楚,讓你理解選擇。
第三章:建立 S3 Bucket
AWS帳號代開服務 3.1 建立 Bucket
登入 AWS Console,進入 S3,按「建立 Bucket」。接著填入:
- Bucket 名稱:必須全域唯一。
- 區域:建議選擇離使用者較近的區域。
Bucket 名稱唯一性是常見踩雷點。你在不同帳號或不同區域都可能取不到相同名稱。
3.2 設定 Block Public Access(公開存取封鎖)
在建立過程中或建立後,你會看到「Block all public access」一類的選項。若你想讓靜態網站公開,必須確認不要把整個 Bucket 永久封鎖公開。
但注意:這不是叫你盲目關閉。更好的做法是理解「你要公開哪些東西」,然後再搭配 Bucket Policy 精準開放。
簡化流程(公開網站)通常是:在 Block Public Access 相關選項上,允許必要的公開讀取。
如果你把它全部鎖死,後續你寫了 Policy 也可能沒用,最後呈現就是 403 或網站打不開。
第四章:啟用 S3 靜態網站託管
4.1 進入 Bucket 的 Static website hosting 設定
進入你剛建立的 Bucket,找到「Properties(屬性)」或「Static website hosting(靜態網站託管)」相關區塊,啟用。
選擇你要的託管類型,並填入:
- Index document:例如 index.html
- Error document(建議填):例如 error.html 或直接留空但不建議。
這一步對你理解 S3 行為很重要。當使用者打到根路徑時,S3 會把它當成 index 文件;當不存在或 404 時,就回傳你指定的錯誤頁。
4.2 取得網站端點(Website endpoint)
啟用後,畫面會顯示「網站端點」。你可用瀏覽器打開它測試。
有時候你看到端點但網站仍失敗,原因可能是檔案尚未上傳、權限未開、或你上傳的檔名不正確。
第五章:上傳網站檔案到 Bucket
5.1 建議的目錄結構
假設你的輸出檔案如下:
- index.html
- main.css
- main.js
- assets/logo.png
你可以直接把這些檔案上傳到 Bucket 根目錄(index.html 必須在根或你設定的路徑能對上)。其餘檔案依照你的打包產物保留原有資料夾結構。
5.2 上傳方式
AWS帳號代開服務 你可以用 Console 上傳或用 CLI 上傳。Console 上傳適合小型專案;CLI 適合有大量檔案、版本管理或自動化流程。
重點是:上傳後要確認物件名稱與你的引用路徑一致。很多「圖片打不出來」其實是檔名大小寫或路徑錯誤。
5.3 確認 Content-Type
靜態網站通常依賴瀏覽器正確判斷檔案類型。S3 會嘗試自動判斷 Content-Type,但有時候不如你想像。
例如:
- HTML 應為 text/html
- CSS 應為 text/css
- JavaScript 應為 application/javascript 或 text/javascript
若 Content-Type 判錯,可能導致瀏覽器行為異常(例如 CSS 當成純文字下載)。你可以在物件屬性中檢查。
第六章:設定權限,讓網頁能被讀取
6.1 先確認「你到底要不要公開」
公開網站常見目標是:所有人讀取 Bucket 內的檔案(至少是網站資源)。這通常需要:
- 關閉或調整 Block Public Access 相關封鎖
- AWS帳號代開服務 配置 Bucket Policy 或物件 ACL(現代最佳實務通常偏 Bucket Policy)
如果你希望網站不是完全公開,這一章你就要調整策略。但多數快速部署就走公開讀取。
6.2 建立 Bucket Policy(公開讀取物件)
在 Bucket 的 Permissions 裡找到 Bucket Policy,加入一個允許 GetObject 的 policy。核心概念是:
- AWS帳號代開服務 Action:通常是 s3:GetObject
- Resource:指向你的物件,例如 arn:aws:s3:::你的bucket名稱/*
- Principal:如果完全公開,就會允許任何人(*)。
你要避免「只允許讀取某些檔案卻漏掉 assets」的狀況。否則你會遇到首頁開得起來,但圖片或 JS 載不出來。
6.3 常見陷阱:你開了 Policy,但仍 403
當你遇到 403 Forbidden,常見原因包括:
- Block Public Access 沒有調整:即便 policy 寫了,也被擋下。
- 物件沒有正確上傳或名稱不對:S3 找不到會導向不同錯誤頁或直接 404。
- Policy resource 寫錯:例如只寫 arn 指到某個前綴。
- 網站端點與路徑:S3 靜態網站端點對路徑處理有自己的規則。
排錯的思路是:先確認能不能打開 index.html,再確認引用的資源是否都有正確 URL。
第七章:用正確的 URL 測試與驗證
7.1 先測根路徑
打開 S3 提供的 Website endpoint(或你自訂網域之前的端點),確認根路徑能顯示 index.html。
如果根路徑不顯示,優先查:
- Index document 設定是否為正確檔名(例如 index.html)
- 檔案是否真的上傳到 Bucket 根目錄
- 權限是否允許讀取
7.2 再測資源路徑
打開開發者工具(Network),觀察是否有資源失敗。常見狀況:
- CSS/JS 404:多半是路徑拼錯或打包時產生的路徑不同於你上傳的結構。
- 圖片 403:權限沒開到相應物件或前綴。
- 字型載入失敗:Content-Type 或跨來源政策。
第八章:SPA(單頁應用)要怎麼讓路由正常
如果你部署的是 SPA(例如 React Router、Vue Router),使用者可能會訪問:
- /
- /about
- /products/123
但 S3 靜態網站託管是「檔案導向」。當使用者打到 /about,S3 會嘗試找 about 這個物件(或 about/index.html),而不是幫你回傳 index.html。結果就會 404。
解法是「將錯誤頁設為 index.html」或使用重導規則。S3 的靜態網站託管本身有能力指定 Error document;但要做到完整 SPA fallback,實務上常見作法是:錯誤頁回傳 index.html(你可能需要讓 error.html 內容引用或直接複用 index.html),或改用 CloudFront 來做更彈性的設定。
如果你只想快速讓 SPA 能跑,最常見的策略是提供一個能回到 index.html 的錯誤頁,確保未知路徑也會載入同一套前端資源。
第九章:設定快取與檔案更新策略
9.1 為什麼你會遇到「更新了但用戶還是看到舊版」
瀏覽器會快取 CSS、JS、圖片。即便你更新了檔案,若瀏覽器或中介快取仍認為版本沒變,就可能繼續使用舊內容。S3 上存取本身也可透過 Header 控制快取。
9.2 用檔名 hash 來避免快取問題(推薦)
現代打包工具常會在檔名中加入 hash,例如 main.3f2a9c.js。這樣當內容更新,檔名也會變,瀏覽器就會重新下載新檔。這通常是最省事、也最符合前端部署直覺的方式。
因此當你重新部署時,盡量不要把所有版本都維持同一個檔名(例如 main.js 永遠不變),除非你有能力正確處理快取失效。
9.3 檔案大小與效能考量
S3 對靜態檔案的傳輸表現通常良好。你要注意的是:如果你的網站流量大、需要更低延遲、需要更細緻的快取控制,CloudFront 會更合適。本文仍聚焦 S3,但你要記得:S3 靜態網站託管不是唯一選擇。
第十章:自訂網域與 HTTPS(從理解到落地)
AWS帳號代開服務 當你有自訂網域(例如 example.com),通常你希望訪客用漂亮的網域打開網站,而不是看 S3 的長端點字串。
10.1 DNS 指向你的網站端點
最基本的做法是讓 DNS 將請求導到 S3 的網站端點。你會在 Route 53 建立對應的 Alias 或 CNAME 記錄。不同情況(是否是根網域、是否用子網域)設定方式會不同。
你需要確認:你使用的是「S3 網站端點」還是「S3 REST endpoint」。兩者對應的行為和 DNS 設定不同。S3 靜態網站託管是網站端點,常見會涉及不同協定或重導行為。
10.2 HTTPS 的現實:S3 靜態網站託管不是主流終點
要在自訂網域上提供 HTTPS,最常見的做法是把 CloudFront 放在前面,讓 CloudFront 提供 SSL/TLS,然後再把請求轉到 S3。原因很實際:讓 TLS 在邊緣節點終止,效果更好、配置更成熟。
如果你只用 S3 靜態網站端點,HTTPS 的可行性與限制會因設定而不同。你要做的是:先確認你想要的效果(全站 HTTPS、是否要 HSTS、是否要自動憑證管理),再決定是否上 CloudFront。
簡言之:想要更順的 HTTPS 體驗,多數情境會直接走 CloudFront。S3 靜態網站託管可以先讓你把網站跑起來,但要長期穩定上線,CloudFront 幾乎是標準選項。
第十一章:常見問題與排錯清單
11.1 404:找不到檔案或首頁
遇到 404 的時候,先確認三件事:
- AWS帳號代開服務 Index document 設定是否正確(檔名拼錯也會失敗)
- index.html 是否真的上傳到預期路徑
- 你訪問的路徑是否存在。SPA 情況下需要 fallback 邏輯。
11.2 403:權限或公開封鎖
403 的優先排查:
- Block Public Access 是否仍擋住
- Bucket Policy 是否允許 s3:GetObject
- Resource 範圍是否涵蓋所有要讀取的檔案(包含 assets 子目錄)
11.3 網站打得開,但 CSS/JS/圖片不正常
通常是路徑或檔案類型問題:
- 檔案路徑是否與打包輸出的引用一致
- 檔名大小寫是否一致(特別是 linux/區分大小寫的情況)
- Content-Type 是否錯誤
- AWS帳號代開服務 跨來源要求的 CORS 是否需要(通常圖片/字型較常見)
11.4 字型或 API 請求被攔截
若你網站資源包含跨來源載入(例如字型從其他網域載入),瀏覽器可能因 CORS 限制而阻擋。這時你要檢查:
- 是否需要在 S3 設定 CORS 規則
- 是否在前端程式中使用了錯誤的 URL
第十二章:一個可重複的部署流程(建議你照這樣做)
為了避免每次部署都憑感覺,你可以把流程整理成固定步驟。下面是一個實務上很實用的順序:
- 建立 Bucket(選區、確認公開封鎖設定)
- 啟用 Static website hosting(Index document、Error document)
- 準備好 build/dist 資料夾內容
- AWS帳號代開服務 上傳檔案到 Bucket(保持路徑與打包引用一致)
- 設定 Bucket Policy 讓需要的物件可讀
- 用 Website endpoint 測試根路徑
- 用 Network 檢查資源載入是否有錯
- 若是 SPA,設定 fallback(確保子路由不會 404)
- 若上線要自訂網域/HTTPS,規劃 DNS 與(必要時)CloudFront
AWS帳號代開服務 你只要每次都按順序走,就會大幅降低「因為漏一步導致整個網站無法顯示」的情況。
結語:把 S3 當作可靠的檔案交付平台
S3 靜態網站託管的價值,不在於它有多花俏,而在於它把「部署靜態內容」這件事做得夠直接、夠可靠。你只要掌握三個核心:首頁與錯誤頁怎麼指定、檔案怎麼上傳到正確路徑、權限如何讓瀏覽器讀得到。
當你能清楚解釋每一步背後的目的,就不容易在 403/404/資源錯誤之間反覆試錯。下一次你再部署新版本,也會更像是在做工程,而不是在賭運氣。

