Category: guide
Deploying Static Sites — Vercel, Netlify, GitHub Pages
วิธี deploy static site ด้วย Vercel, Netlify, และ GitHub Pages — เปรียบเทียบ features, ราคา, และ workflow
สารบัญ
เปรียบเทียบ Platforms
| Feature | Vercel | Netlify | GitHub Pages |
|---|---|---|---|
| ราคา Free | 100GB bandwidth | 100GB bandwidth | ไม่จำกัด |
| Custom domain | ✓ | ✓ | ✓ |
| HTTPS อัตโนมัติ | ✓ | ✓ | ✓ |
| Branch preview | ✓ ทุก PR | ✓ ทุก PR | ✗ |
| Edge Functions | ✓ | ✓ | ✗ |
| Build cache | ✓ ดีมาก | ✓ | ✗ |
| ใช้งานง่าย | ★★★★★ | ★★★★☆ | ★★★☆☆ |
Vercel
Deploy อัตโนมัติจาก Git
# 1. Install Vercel CLI
npm i -g vercel
# 2. Login
vercel login
# 3. Deploy (ครั้งแรก)
vercel
# 4. Deploy production
vercel --prod
หรือเชื่อม GitHub แล้ว push → deploy อัตโนมัติ
vercel.json สำหรับ Static Site
{
"buildCommand": "npm run build",
"outputDirectory": "dist",
"installCommand": "npm install",
"framework": null
}
สำหรับ Astro โดยเฉพาะ:
{
"framework": "astro"
}
Environment Variables
# ผ่าน CLI
vercel env add MY_API_KEY production
# หรือ Dashboard → Settings → Environment Variables
Redirect Rules
{
"redirects": [
{ "source": "/old-path", "destination": "/new-path", "permanent": true },
{ "source": "/blog/:slug", "destination": "/posts/:slug", "permanent": false }
]
}
Netlify
Deploy ผ่าน CLI
npm i -g netlify-cli
netlify login
netlify init
netlify deploy --dir=dist
netlify deploy --dir=dist --prod
netlify.toml
[build]
command = "npm run build"
publish = "dist"
[build.environment]
NODE_VERSION = "20"
[[redirects]]
from = "/old"
to = "/new"
status = 301
[[headers]]
for = "/*"
[headers.values]
X-Frame-Options = "DENY"
X-Content-Type-Options = "nosniff"
Referrer-Policy = "strict-origin-when-cross-origin"
[[headers]]
for = "/fonts/*"
[headers.values]
Cache-Control = "public, max-age=31536000, immutable"
Branch Deploys
[context.branch-deploy]
command = "npm run build"
[context.deploy-preview]
command = "npm run build"
GitHub Pages
GitHub Actions Workflow
# .github/workflows/deploy.yml
name: Deploy to GitHub Pages
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npm run build
- uses: actions/upload-pages-artifact@v3
with:
path: dist/
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/deploy-pages@v4
id: deployment
ตั้งค่า astro.config.mjs สำหรับ GitHub Pages
// ถ้า deploy ที่ username.github.io/repo-name (ไม่ใช่ custom domain)
export default defineConfig({
site: 'https://username.github.io',
base: '/repo-name',
});
Custom Domain
ตั้งค่า DNS
# A record (apex domain)
@ A 76.76.21.21 (Vercel)
@ A 75.2.60.5 (Netlify)
@ A 185.199.108.153 (GitHub Pages)
@ A 185.199.109.153
@ A 185.199.110.153
@ A 185.199.111.153
# CNAME record (www)
www CNAME cname.vercel-dns.com. (Vercel)
www CNAME [site].netlify.app. (Netlify)
www CNAME username.github.io. (GitHub Pages)
Best Practices
Build Optimization
# ตรวจ bundle size
npm run build && du -sh dist/
# ดู output ละเอียด
npx astro build --verbose 2>&1 | grep -E 'dist|kB|bytes'
Cache Strategy
# netlify.toml
[[headers]]
for = "/_astro/*"
[headers.values]
Cache-Control = "public, max-age=31536000, immutable"
[[headers]]
for = "/fonts/*"
[headers.values]
Cache-Control = "public, max-age=31536000, immutable"
[[headers]]
for = "/*.html"
[headers.values]
Cache-Control = "public, max-age=0, must-revalidate"
Astro build puts hashed assets ใน /_astro/ ทำให้ immutable cache ปลอดภัย
Security Headers
[[headers]]
for = "/*"
[headers.values]
X-Frame-Options = "DENY"
X-Content-Type-Options = "nosniff"
Referrer-Policy = "strict-origin-when-cross-origin"
Permissions-Policy = "camera=(), microphone=(), geolocation=()"
Content-Security-Policy = """
default-src 'self';
script-src 'self' 'unsafe-inline';
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
font-src 'self';
"""