การนำ React ขึ้นใช้งานในปี 2026: บิลด์ที่ไม่เปลี่ยนแปลง Traefik และการปล่อยระบบโดยไม่หยุดให้บริการ
บทความต่อยอดฉบับปัจจุบันที่เน้นการใช้งานจริง โดยแปลงเอกสารจากผู้ให้บริการให้เป็นการควบคุมงาน การตัดสินใจย้ายระบบ และเกณฑ์การปล่อยระบบที่ตรวจสอบได้
สิ่งที่เปลี่ยนไปในปี 2026
เราทบทวนหัวข้อนี้อีกครั้งเพราะขอบเขตการดำเนินงานเปลี่ยนไป หลักการที่ใช้ได้ในระยะยาวยังมีประโยชน์ แต่เวอร์ชันปัจจุบันทำให้ทางลัดเก่าบางอย่างไม่เพียงพอหรือไม่ปลอดภัย บทความต่อยอดนี้เริ่มจากเอกสารผู้ให้บริการที่มีอยู่ ณ วันที่ 14 กรกฎาคม 2026 แยกข้อเท็จจริงออกจากทางเลือกเฉพาะระบบ และถือว่าการเปลี่ยนค่ากำหนดทุกครั้งเป็นการเปลี่ยนระบบใช้งานจริงที่ต้องควบคุม
แหล่งข้อมูลปฐมภูมิปัจจุบัน
แนวทางใช้บทความฉบับปรับปรุง
อ่านแหล่งข้อมูลก่อน บันทึกเวอร์ชันที่ใช้งานจริง และกำหนดผลลัพธ์ที่สังเกตได้ก่อนเปลี่ยนค่า ทดสอบการเปลี่ยนแปลงที่เล็กที่สุดและย้อนกลับได้ในสภาพแวดล้อมที่เป็นตัวแทนของระบบจริง คำสั่งที่สำเร็จไม่ใช่เกณฑ์ยอมรับ แต่ต้องดูสถานะบริการ ความสมบูรณ์ของข้อมูล ความหน่วง ขอบเขตความปลอดภัย และเวลาย้อนกลับ เราคงลำดับวินิจฉัยจากคู่มือเดิมที่ยังมีประโยชน์ไว้เป็นพื้นฐาน แต่ตัวอย่างที่ขึ้นกับเวอร์ชันยังต้องตรวจเทียบกับเอกสารปัจจุบัน ไฟล์การตั้งค่าและคำสั่งที่กล่าวถึงด้านล่างอยู่ในคู่มือเดิม
- GitHub Actions สำหรับกระบวนการนำระบบขึ้นใช้งานที่ติดตั้งและดูแลเอง
- การซ้อน Reverse Proxy: สถาปัตยกรรมสำหรับสภาพแวดล้อมใช้งานจริง
- จาก React SPA สู่ Astro: เมื่อใดและทำไมต้องย้าย
พื้นฐานการดำเนินงาน
การสร้างแอปพลิเคชัน React บนเครื่องของตัวเองทำได้ไม่ยาก แต่การนำขึ้นเซิร์ฟเวอร์ใช้งานจริงอย่างถูกต้องเป็นจุดที่นักพัฒนาส่วนใหญ่พบอุปสรรคไม่คาดคิด คู่มือนี้บันทึกการวินิจฉัยปัญหาการนำระบบขึ้นใช้งานจริง ซึ่งทุกอย่างดูตั้งค่าถูกต้อง ทั้งคอนเทนเนอร์ที่ทำงาน เลเบล Traefik และ DNS ที่แปลงชื่อได้ แต่แอปพลิเคชันยังตอบข้อผิดพลาด 404 ต่อเนื่อง
เราจะอธิบายกระบวนการทั้งหมด ตั้งแต่สร้างแอปพลิเคชัน React บนเครื่องของคุณจนถึงนำขึ้นเซิร์ฟเวอร์ Docker ใช้งานจริง พร้อมการตั้งค่า reverse proxy, SSL อัตโนมัติ และการกำหนดเส้นทางโดเมนอย่างเหมาะสม แนวทางนี้ต่อยอดจากหลักการติดตั้งและดูแลระบบเองของเรา เช่น การติดตั้ง n8n เพื่อทำเวิร์กโฟลว์อัตโนมัติ และการสร้างชุดระบบพัฒนาแบบ multi-tenant เพื่อควบคุมการดำเนินงานได้เต็มที่
ปัญหาของการนำระบบขึ้นใช้งาน React แบบดั้งเดิม
คู่มือการนำ React ขึ้นใช้งานส่วนใหญ่ข้ามรายละเอียดสำคัญของระบบจริง มักแสดงเพียง npm run build และการคัดลอกไฟล์ไปยัง nginx แต่แทบไม่ครอบคลุม:
ความขัดแย้งในการกำหนดค่า:
- เราเตอร์ HTTP ที่กำหนดเองทับการเปลี่ยนเส้นทางส่วนกลาง
- ไวยากรณ์เลเบล Traefik ผิด ทำให้ล้มเหลวโดยไม่แจ้ง
- การผูก IPv6 กับ IPv4 ไม่ตรงกันในการตรวจสถานะ
- ไม่มีการแมปพอร์ตบริการ ทำให้เกิดข้อผิดพลาด 404
การจัดการทรัพยากร:
- ดิสก์เต็มจนลงทะเบียนคอนเทนเนอร์ไม่ได้
- อิมเมจ Docker ใหญ่เกินไปจากไฟล์บิลด์ที่ไม่จำเป็น
- กลยุทธ์แคชที่ไม่มีประสิทธิภาพซึ่งทำให้การนำระบบขึ้นใช้งานช้าลง
- หน่วยความจำจำกัด ส่งผลต่อประสิทธิภาพการบิลด์
ความพร้อมสำหรับใช้งานจริง:
- การออกใบรับรอง SSL อัตโนมัติอย่างถูกต้อง
- กลยุทธ์นำระบบขึ้นใช้งานโดยไม่หยุดให้บริการ
- การตั้งค่าตรวจสถานะระบบ
- การเชื่อมระบบบันทึกเหตุการณ์และเฝ้าติดตาม
ผลคือเสียเวลาหลายชั่วโมงวินิจฉัยว่าทำไมแอปที่ทำงานบนเครื่องตัวเองได้สมบูรณ์กลับตอบ 404 ที่หาสาเหตุไม่พบในระบบจริง ทั้งที่ “ทุกอย่างดูถูกต้อง”
เครื่องมือที่เราใช้
มาดูหน้าที่ของแต่ละส่วนในสถาปัตยกรรมการนำ React ขึ้นใช้งานของเรา:
Vite: เครื่องมือบิลด์สมัยใหม่
Vite ช่วยให้พัฒนาได้รวดเร็วและสร้างชุดไฟล์บิลด์ที่ปรับให้เหมาะกับการใช้งานจริง ต่างจาก Create React App โดยใช้ ES modules โดยตรงระหว่างพัฒนา และรวมชุดไฟล์ที่เพิ่มประสิทธิภาพสำหรับระบบจริง แอป React จึงบิลด์ได้ในไม่กี่วินาทีแทนที่จะใช้เวลาหลายนาที
ข้อได้เปรียบหลักคือ Vite แบ่งโค้ด ตัดโค้ดที่ไม่ได้ใช้ และเพิ่มประสิทธิภาพไฟล์ทรัพยากรให้อัตโนมัติ ได้ชุดไฟล์พร้อมใช้งานจริงโดยไม่ต้องตั้งค่า webpack ซับซ้อน
Docker: การบรรจุในคอนเทนเนอร์เพื่อให้ทำงานเหมือนกัน
Docker ทำให้แอป React ทำงานเหมือนกันในสภาพแวดล้อมพัฒนาและใช้งานจริง คอนเทนเนอร์ nginx ที่ให้บริการแอปบนเครื่องของคุณจะทำงานเหมือนกันบนเซิร์ฟเวอร์จริง จึงขจัดปัญหา “ทำงานได้บนเครื่องของฉัน”
Docker บรรจุสภาพแวดล้อมทั้งหมดของแอป ได้แก่ ไฟล์บิลด์ React การตั้งค่า nginx และสภาพแวดล้อมรันโปรแกรม ไว้ในคอนเทนเนอร์ที่เคลื่อนย้ายและใช้งานได้ทุกที่
Traefik: Reverse Proxy อัจฉริยะ
Traefik กำหนดเส้นทางทราฟฟิกไปยังแอปพลิเคชันในคอนเทนเนอร์ที่ถูกต้องตามชื่อโดเมนอัตโนมัติ แทนการกำหนดกฎ nginx หรือ Apache ที่ซับซ้อนเองทุกครั้งที่เพิ่มแอป Traefik อ่านเลเบลจากคอนเทนเนอร์ Docker และตั้งค่าเส้นทางให้
ในการตั้งค่า Docker แบบ multi-tenant ของเรา เราได้แสดงพลังของ Traefik สำหรับการจัดการสภาพแวดล้อมลูกค้าหลายราย หลักการเดียวกันนี้ใช้ได้ที่นี่สำหรับการจัดการแอปพลิเคชัน React หลายตัวบนเซิร์ฟเวอร์เดียว
Traefik ยังจัดการ SSL termination ผ่าน Let’s Encrypt อัตโนมัติ ค้นหาบริการอัตโนมัติ และให้การเฝ้าติดตามอย่างละเอียด โดยใช้การกำหนดค่าเพียงเล็กน้อย
nginx: เว็บเซิร์ฟเวอร์สำหรับใช้งานจริง
nginx ให้บริการไฟล์บิลด์ React แบบสแตติกได้อย่างมีประสิทธิภาพ เป็นมาตรฐานที่ใช้กันทั่วไปสำหรับเนื้อหาสแตติกในระบบจริง รองรับการเชื่อมต่อพร้อมกันหลายพันรายการโดยใช้ทรัพยากรน้อย
ทำความเข้าใจขั้นตอนการนำระบบขึ้นใช้งาน
กระบวนการทั้งหมดจากการพัฒนาบนเครื่องจนถึงใช้งานจริงมีดังนี้:
- การพัฒนาบนเครื่อง: สร้างและทดสอบ React ด้วย npm run dev
- การบิลด์สำหรับใช้งานจริง: สร้างไฟล์สแตติกที่เพิ่มประสิทธิภาพด้วย npm run build
- การบรรจุในคอนเทนเนอร์: รวมไฟล์บิลด์ไว้ในคอนเทนเนอร์ Docker ของ nginx
- การนำขึ้นเซิร์ฟเวอร์: อัปโหลดและเริ่มคอนเทนเนอร์บนเซิร์ฟเวอร์ใช้งานจริง
- การลงทะเบียน Traefik: การกำหนดเส้นทางอัตโนมัติและการออกใบรับรอง SSL
- การเฝ้าติดตามสถานะ: ตรวจสถานะต่อเนื่องเพื่อให้มั่นใจว่าระบบพร้อมใช้งาน
จุดเด่นคือระบบอัตโนมัติ เมื่อตั้งค่าถูกต้อง คุณนำการอัปเดตขึ้นใช้งานได้ภายใน 60 วินาทีด้วยคำสั่งเดียว
การตั้งค่าแอปพลิเคชัน React
โครงสร้างโครงการสำหรับใช้งานจริง
จัดระเบียบโครงการ React ของคุณโดยคำนึงถึงการนำระบบขึ้นใช้งาน:
my-react-app/
├── src/ # React source code
├── public/ # Static assets
├── dist/ # Build output (auto-generated)
├── package.json # Dependencies
├── package-lock.json # Locked dependency versions (npm ci)
├── vite.config.ts # Vite configuration
├── Dockerfile # Container definition
├── nginx.conf # nginx configuration
└── docker-compose.yml # Deployment definition
การเพิ่มประสิทธิภาพการกำหนดค่า Vite
สร้าง vite.config.ts ด้วยการตั้งค่าที่เหมาะกับระบบใช้งานจริง:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
build: {
outDir: 'dist',
sourcemap: false, // Do not publish source maps in production
// Minification is on by default (Oxc minifier in Vite 8)
rolldownOptions: {
output: {
// Vite 8 (Rolldown): codeSplitting replaces the manualChunks object form
codeSplitting: {
groups: [
{ test: /node_modules[\\/](react|react-dom|scheduler)[\\/]/, name: 'vendor' },
],
},
},
},
},
server: {
port: 3000,
host: true, // Enable network access
},
})
การกำหนดค่านี้:
- แยกไลบรารีภายนอกเพื่อให้แคชได้ดีขึ้น
- ย่อโค้ดเพื่อขนาดไฟล์ที่เล็กลง
- ปิดแผนที่ซอร์สโค้ดในระบบจริงเพื่อป้องกันโค้ดถูกเปิดเผย
- ปรับการแบ่งชุดไฟล์ย่อยให้โหลดเร็วขึ้น
การบิลด์สำหรับใช้งานจริง
สร้างชุดไฟล์บิลด์ที่ปรับให้เหมาะกับการใช้งานจริง:
# Install the exact dependency versions from package-lock.json
npm ci
# Create production build
npm run build
# Verify build output
ls -lh dist/
โฟลเดอร์ dist/ ของคุณควรมี:
- index.html – จุดเริ่มต้น
- assets/ – JS, CSS และรูปภาพที่ย่อแล้ว
- ไฟล์สแตติกจาก public/
การสร้างคอนเทนเนอร์สำหรับใช้งานจริง
การกำหนดค่า nginx สำหรับ React
แอปพลิเคชัน React กำหนดเส้นทางฝั่งไคลเอนต์ จึงต้องตั้งค่า nginx เป็นพิเศษ สร้าง nginx.conf:
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
# Gzip compression for better performance
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript
application/x-javascript application/xml+rss
application/javascript application/json;
# Security headers (a location with its own add_header drops these)
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# SPA: Route all paths to index.html for client-side routing
location / {
try_files $uri $uri/ /index.html;
}
# Cache static assets aggressively
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Revalidate HTML on every request so new releases show up immediately
location ~* \.html$ {
expires -1;
}
# Health check endpoint for monitoring
location /health {
access_log off;
default_type text/plain;
return 200 "healthy\n";
}
}
ส่วนสำคัญคือ try_files $uri $uri/ /index.html ซึ่งทำให้ React Router ทำงานในระบบจริงได้ถูกต้อง ทุกเส้นทางจะได้รับไฟล์ index.html หลัก
Dockerfile สำหรับใช้งานจริง
สร้าง Dockerfile ที่เพิ่มประสิทธิภาพ:
FROM nginx:alpine
# Copy custom nginx configuration
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Copy production build files
COPY dist/ /usr/share/nginx/html/
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
ใช้อิมเมจ nginx:alpine ขนาดเล็กสำหรับระบบจริง (ขนาดหลังบีบอัดต่ำกว่า 30 MB ณ เดือนตุลาคม 2026) ที่มีทุกอย่างสำหรับให้บริการแอป React
การกำหนดค่า Docker Compose
สร้าง docker-compose.yml เพื่อให้นำระบบขึ้นใช้งานได้ง่าย:
services:
my-react-app:
build:
context: .
dockerfile: Dockerfile
container_name: my-react-app
restart: unless-stopped
networks:
- proxy
labels:
# Enable Traefik
- "traefik.enable=true"
# Define routing rule
- "traefik.http.routers.myapp.rule=Host(`app.yourdomain.com`)"
- "traefik.http.routers.myapp.entrypoints=https"
- "traefik.http.routers.myapp.tls=true"
- "traefik.http.routers.myapp.tls.certresolver=letsencrypt"
# Define service port
- "traefik.http.services.myapp.loadbalancer.server.port=80"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:80/health"]
interval: 30s
timeout: 3s
retries: 3
start_period: 5s
networks:
proxy:
external: true
หมายเหตุการกำหนดค่าที่สำคัญ:
ส่วน labels เป็นจุดที่การนำระบบขึ้นใช้งานมักล้มเหลว สังเกตสิ่งที่เราไม่ใส่ไว้:
- ไม่กำหนดเราเตอร์ HTTP แยก
- ไม่เพิ่มมิดเดิลแวร์เปลี่ยนเส้นทางเอง
- ไม่กำหนดจุดเข้า HTTP
เพราะการตั้งค่าส่วนกลางของ Traefik จัดการการเปลี่ยนเส้นทาง HTTP→HTTPS อยู่แล้ว ในการตั้งค่าของเรา การเพิ่มเราเตอร์ HTTP ของแต่ละบริการรบกวนพฤติกรรมนี้และทำให้เกิด 404 ซึ่งเป็นปัญหาที่เราแก้ได้ในการวินิจฉัยครั้งนี้
การนำขึ้นเซิร์ฟเวอร์ใช้งานจริง
ข้อกำหนดเบื้องต้นบนเซิร์ฟเวอร์
เซิร์ฟเวอร์ใช้งานจริงต้องมี:
สภาพแวดล้อม Docker:
# Verify Docker is installed
docker --version
docker compose version
# Verify Traefik is running
docker ps | grep traefik
# Verify proxy network exists
docker network ls | grep proxy
หากยังไม่ได้ตั้งค่า Traefik ให้ดูคู่มือ Docker แบบ multi-tenant ของเราที่อธิบายการตั้งค่าไว้อย่างครบถ้วน
พื้นที่ดิสก์เพียงพอ:
# Check available space
df -h /
# You need at least 2-5GB free for Docker operations
การกำหนดค่า DNS:
- ชี้ app.yourdomain.com ไปยังที่อยู่ IP ของเซิร์ฟเวอร์
- รอการกระจาย DNS (โดยปกติ 5-60 นาที)
การอัปโหลดแอปพลิเคชัน
ถ่ายโอนแอปพลิเคชันไปยังเซิร์ฟเวอร์:
# From your local machine
scp -r my-react-app/ user@your-server:/opt/
# Or use rsync for efficient updates
rsync -avz --exclude 'node_modules' \
my-react-app/ user@your-server:/opt/my-react-app/
การบิลด์และเริ่มคอนเทนเนอร์
เชื่อมต่อเซิร์ฟเวอร์ผ่าน SSH และนำระบบขึ้นใช้งาน:
# Navigate to application directory
cd /opt/my-react-app
# Build the Docker image
docker compose build
# Start the container
docker compose up -d
# Verify it's running
docker compose ps
การตรวจสอบการนำระบบขึ้นใช้งาน
ตรวจสอบว่าทุกอย่างทำงาน:
# Test container health internally
docker compose exec my-react-app wget -q -O- http://127.0.0.1/health
# Check Traefik routing (wait 30 seconds for SSL)
curl -I https://app.yourdomain.com
# View container logs
docker compose logs -f
คุณควรเห็น HTTP/2 200 จากคำสั่ง curl ซึ่งบ่งชี้ความสำเร็จ
ปัญหาการนำระบบขึ้นใช้งานที่พบบ่อยและวิธีแก้
ข้อผิดพลาด 404 แม้จะกำหนดค่าถูกต้อง
อาการ: Traefik ตอบ HTTP/2 404 ทั้งที่คอนเทนเนอร์ทำงานภายในได้
สาเหตุ: กำหนดเราเตอร์หลายตัวให้บริการเดียวโดยไม่ได้แมปพอร์ตบริการอย่างเหมาะสม หรือเราเตอร์ HTTP ที่กำหนดเองทับการเปลี่ยนเส้นทางส่วนกลางของ Traefik
วิธีแก้ไข:
# Remove these labels if present:
# - "traefik.http.middlewares.myapp-redirect.redirectscheme.scheme=https"
# - "traefik.http.routers.myapp-http.rule=Host(`app.yourdomain.com`)"
# - "traefik.http.routers.myapp-http.entrypoints=http"
# - "traefik.http.routers.myapp-http.middlewares=myapp-redirect"
# Keep only HTTPS router:
labels:
- "traefik.enable=true"
- "traefik.http.routers.myapp.rule=Host(`app.yourdomain.com`)"
- "traefik.http.routers.myapp.entrypoints=https"
- "traefik.http.routers.myapp.tls.certresolver=letsencrypt"
- "traefik.http.services.myapp.loadbalancer.server.port=80"
การเปลี่ยนเส้นทาง HTTP→HTTPS ส่วนกลางของ Traefik ที่ตั้งใน traefik.yml จัดการทราฟฟิก HTTP อัตโนมัติ เราเตอร์ HTTP เฉพาะบริการอาจขัดแย้งกับการเปลี่ยนเส้นทางนี้ได้
คอนเทนเนอร์มีสถานะไม่พร้อมใช้งาน
อาการ: docker compose ps แสดงสถานะคอนเทนเนอร์เป็น “unhealthy”
สาเหตุ: การตรวจสถานะใช้ localhost ซึ่งแปลงเป็น IPv6 [::1] แต่ nginx รับการเชื่อมต่อเฉพาะ IPv4
วิธีแก้ไข:
healthcheck:
# Use explicit IPv4 address instead of localhost
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:80/health"]
การบิลด์ Docker ล้มเหลวด้วย “No Space Left”
อาการ: การบิลด์ล้มเหลวด้วยข้อผิดพลาดพื้นที่ดิสก์
วิธีแก้ไข:
# Check disk usage
df -h /
# Clean Docker system
docker system prune -a -f
# Remove unused images
docker image prune -a -f
# Remove unused volumes
docker volume prune -f
หากดิสก์เต็มจริง (>95%) ต้องเพิ่มพื้นที่ว่างหรือขยายพื้นที่จัดเก็บ Docker ต้องใช้พื้นที่ชั่วคราวสำหรับแคชเลเยอร์และการบิลด์
ใบรับรอง SSL ไม่ถูกสร้าง
อาการ: curl แสดงใบรับรองที่ลงนามเองหลังผ่านไป 10+ นาที
สาเหตุทั่วไป:
- DNS ไม่ได้ชี้ไปยังเซิร์ฟเวอร์อย่างถูกต้อง
- พอร์ต 80/443 ไม่สามารถเข้าถึงจากอินเทอร์เน็ต
- ถึงขีดจำกัดอัตรา Let’s Encrypt (ตัวอย่างเช่น ใบรับรอง 5 ฉบับต่อชุดชื่อโฮสต์ที่ตรงกันทุกชื่อ หรือ 50 ฉบับต่อโดเมนที่จดทะเบียน ทุก 7 วัน)
วิธีแก้ไข:
# Verify DNS resolution
dig app.yourdomain.com
# Test port accessibility
curl -I http://app.yourdomain.com
# Check Traefik logs for ACME errors
docker logs traefik 2>&1 | grep -i acme
# Restart Traefik if needed
docker restart traefik
ข้อผิดพลาด 404 ของ React Router เมื่อรีเฟรช
อาการ: แอปทำงานเมื่อโหลดครั้งแรกแต่แสดง 404 เมื่อรีเฟรชบนเส้นทางเช่น /about
สาเหตุ: ไม่มีคำสั่ง try_files ในการตั้งค่า nginx
วิธีแก้ไข: ตรวจสอบว่า nginx.conf ของคุณมี:
location / {
try_files $uri $uri/ /index.html;
}
คำสั่งนี้ให้ nginx ส่ง index.html สำหรับทุกเส้นทาง แล้วให้ React Router จัดการเส้นทางฝั่งไคลเอนต์
คอนเทนเนอร์ทำงานแต่ Traefik เข้าถึงไม่ได้
อาการ: คอนเทนเนอร์ทำงาน แต่ Traefik ตอบ “Service Unavailable”
วิธีแก้ไข:
# Verify container is on correct network
docker network inspect proxy
# Check if container is listed
docker inspect my-react-app | grep -A 20 Networks
# Ensure proxy network exists
docker network create proxy
การเพิ่มประสิทธิภาพสำหรับใช้งานจริง
การนำระบบขึ้นใช้งานโดยไม่หยุดให้บริการ
อัปเดตแอปพลิเคชันโดยให้หยุดบริการน้อยที่สุด การสร้างคอนเทนเนอร์เดียวขึ้นใหม่ด้วย docker compose up ยังคงทำให้ทราฟฟิกหยุดชั่วครู่ หากต้องการให้บริการโดยไม่หยุดชะงักจริง ๆ ต้องมีอินสแตนซ์ที่สองซึ่งทำงานปกติอยู่หลัง Traefik ก่อนหยุดอินสแตนซ์เดิม:
#!/bin/bash
# deploy-update.sh - rebuild and replace the container
# Recreating a single container briefly interrupts traffic (see above)
set -euo pipefail
cd /opt/my-react-app
# Pull latest code (from git or updated files)
git pull origin main
# Build new production assets from the lockfile
npm ci
npm run build
# Build the new image while the old container keeps serving
docker compose build my-react-app
# Replace the container: Compose stops the old one, then starts the new one,
# and --wait returns once the new container reports healthy
docker compose up -d --no-deps --wait my-react-app
การตรวจสถานะระบบขั้นสูง
เพิ่มการเฝ้าติดตามสถานะระบบอย่างครอบคลุม:
healthcheck:
test: |
wget --no-verbose --tries=1 --spider http://127.0.0.1:80/health &&
wget --no-verbose --tries=1 --spider http://127.0.0.1:80/
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
ตรวจทั้งจุดตรวจสถานะและเส้นทางหลักของแอปพลิเคชัน เพื่อให้มั่นใจว่าทั้งแอปตอบสนองถูกต้อง
การเพิ่มประสิทธิภาพ
ปรับแต่ง nginx เพื่อประสิทธิภาพที่ดีขึ้น:
# Add to nginx.conf
server {
# ... existing config ...
# Increase buffer sizes for large headers
client_header_buffer_size 1k;
large_client_header_buffers 4 8k;
# Enable keep-alive connections
keepalive_timeout 65;
# Optimize file serving
sendfile on;
tcp_nopush on;
tcp_nodelay on;
}
ขีดจำกัดทรัพยากร
กำหนดขีดจำกัดคอนเทนเนอร์เพื่อป้องกันทรัพยากรหมด:
services:
my-react-app:
# ... existing config ...
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
nginx ที่ให้บริการไฟล์ React แบบสแตติกใช้ทรัพยากรน้อย หน่วยความจำ 512 MB และ CPU ครึ่งคอร์เป็นขีดจำกัดเริ่มต้นที่เหมาะสม ควรทดสอบโหลดเพื่อยืนยันว่ารองรับการใช้งานพร้อมกันตามที่ทราฟฟิกของคุณต้องการได้
เหตุใดการติดตั้งและดูแลระบบเองด้วย Docker จึงสำคัญ
การติดตั้งและดูแลแอป React เองบน Docker ทำให้ควบคุมกระบวนการนำระบบขึ้นใช้งานได้เต็มที่โดยไม่ผูกติดกับผู้ให้บริการ คุณนำแอปขึ้นโครงสร้างพื้นฐานของตัวเองได้ไม่จำกัด ปรับแต่งทุกขั้นตอน และเชื่อมกับบริการที่ติดตั้งและดูแลเองที่มีอยู่ได้
แนวทางนี้ทำงานได้ดีเป็นพิเศษเมื่อรวมกับสถาปัตยกรรม Docker แบบ multi-tenant ของเรา ซึ่งคุณสามารถโฮสต์แอปพลิเคชันลูกค้าหลายตัวบนโครงสร้างพื้นฐานเดียวกันโดยแยกคอนเทนเนอร์และเครือข่ายสำหรับลูกค้าแต่ละราย
ระบบอัตโนมัติและการเชื่อมต่อ CI/CD
การนำระบบขึ้นใช้งานด้วย GitHub Actions
ทำให้การนำระบบขึ้นใช้งานเป็นอัตโนมัติทุกครั้งที่ push:
# .github/workflows/deploy.yml
name: Deploy to Production
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version: '24'
cache: 'npm'
- name: Build React app
run: |
npm ci
npm run build
- name: Deploy to server
uses: appleboy/[email protected]
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
source: "dist/,Dockerfile,nginx.conf,docker-compose.yml"
target: "/opt/my-react-app"
- name: Restart container
uses: appleboy/[email protected]
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /opt/my-react-app
docker compose up -d --build --wait
กระบวนการ GitLab CI/CD
สำหรับผู้ใช้ GitLab:
# .gitlab-ci.yml
stages:
- build
- deploy
build:
stage: build
image: node:24
script:
- npm ci
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 hour
deploy:
stage: deploy
image: alpine:3.23
before_script:
- apk add --no-cache openssh-client
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
# Trust the server's host key (store `ssh-keyscan your-server` output in SSH_KNOWN_HOSTS)
- mkdir -p ~/.ssh && echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
script:
- scp -r dist/ Dockerfile nginx.conf docker-compose.yml $SERVER_USER@$SERVER_HOST:/opt/my-react-app/
- ssh $SERVER_USER@$SERVER_HOST "cd /opt/my-react-app && docker compose up -d --build --wait"
rules:
- if: $CI_COMMIT_BRANCH == "main"
การเฝ้าติดตามระบบใช้งานจริง
กลยุทธ์การบันทึกเหตุการณ์
เพิ่มการบันทึกเหตุการณ์อย่างครอบคลุม:
# Add to docker-compose.yml
services:
my-react-app:
# ... existing config ...
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
ดูบันทึกอย่างมีประสิทธิภาพ:
# Real-time logs
docker compose logs -f my-react-app
# Last 100 lines
docker compose logs --tail=100 my-react-app
# Logs from specific time
docker compose logs --since=2h my-react-app
# Filter for errors only
docker compose logs my-react-app | grep -i error
ตัวชี้วัดและการแจ้งเตือน
ตรวจสถานะคอนเทนเนอร์:
#!/bin/bash
# health-check.sh - Regular health monitoring
CONTAINER="my-react-app"
WEBHOOK_URL="your-notification-webhook"
STATUS=$(docker inspect --format='{{.State.Health.Status}}' $CONTAINER)
if [ "$STATUS" != "healthy" ]; then
curl -X POST $WEBHOOK_URL \
-H 'Content-Type: application/json' \
-d "{\"text\":\"⚠️ Container $CONTAINER is $STATUS\"}"
fi
รันผ่าน cron ทุก 5 นาทีเพื่อเฝ้าติดตามเบื้องต้น
การเชื่อมต่อ React กับโครงสร้างพื้นฐาน Backend
แอป React มักต้องสื่อสารกับบริการ backend ซึ่งเชื่อมกับโครงสร้างพื้นฐานที่ติดตั้งและดูแลเองได้โดยตรง หากใช้ n8n ทำเวิร์กโฟลว์อัตโนมัติหรือ Windmill สำหรับเวิร์กโฟลว์ backend ให้ตั้งค่า CORS และเส้นทาง API ใน nginx อย่างเหมาะสม:
# Add to nginx.conf, above the server block: set Connection only for WebSocket upgrades
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# Inside the server block. Same-origin proxying: the browser makes no
# cross-origin request, so these API calls need no CORS headers
location /api {
proxy_pass http://your-backend-service:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
สิ่งนี้ทำงานได้อย่างราบรื่นเมื่อทุกบริการเป็นส่วนหนึ่งของ Docker network เดียวกัน ตามที่แสดงในคู่มือสถาปัตยกรรม multi-tenant ของเรา
ชุดไฟล์บิลด์เฉพาะสภาพแวดล้อม
สภาพแวดล้อมที่แตกต่างกันมักต้องการการกำหนดค่าที่แตกต่างกัน:
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig(({ mode }) => ({
plugins: [react()],
define: {
'import.meta.env.VITE_API_URL': JSON.stringify(
mode === 'production'
? 'https://api.yourdomain.com'
: 'http://localhost:3000'
),
},
build: {
outDir: 'dist',
sourcemap: mode !== 'production',
},
}))
บิลด์สำหรับสภาพแวดล้อมต่าง ๆ:
# Development build
npm run build -- --mode development
# Staging build
npm run build -- --mode staging
# Production build
npm run build -- --mode production
คุณค่าที่แท้จริงของการเข้าใจการตั้งค่านี้
แนวทางการนำระบบขึ้นใช้งานนี้มีความสำคัญหากคุณ:
จัดการหลายแอปพลิเคชัน:
- นำแอป React ขึ้นใช้งานร่วมกับบริการ backend บนโครงสร้างพื้นฐานเดียวกัน
- ใช้กระบวนการนำระบบขึ้นใช้งานที่สอดคล้องกันข้ามทุกโครงการ
- เชื่อมต่อเครื่องมือที่ติดตั้งและดูแลเอง เช่น n8n และ Windmill
สร้างสำหรับลูกค้า:
- โดเมนกำหนดเองที่ปลอดภัยด้วย SSL ระดับมืออาชีพ
- ควบคุมโครงสร้างพื้นฐานและการนำระบบขึ้นใช้งานได้อย่างสมบูรณ์
- ไม่มีข้อจำกัดของแพลตฟอร์มหรือการผูกติดกับผู้จำหน่าย
เรียนรู้โครงสร้างพื้นฐาน:
- เข้าใจพื้นฐานการบรรจุแอปในคอนเทนเนอร์ Docker
- เชี่ยวชาญการกำหนดค่า Traefik reverse proxy
- วินิจฉัยปัญหาการนำระบบขึ้นใช้งานจริงอย่างเป็นระบบ
การตั้งค่าที่บันทึกไว้ที่นี่อิงจากเซสชันดีบักจริง—ปัญหาที่อธิบายเกิดขึ้นจริง และโซลูชันทำงานได้จริง สิ่งนี้ทำให้มีคุณค่ามากกว่าบทเรียนเชิงทฤษฎีเพราะคุณเห็นข้อผิดพลาดจริงและวิธีหลีกเลี่ยง
เมื่อรวมกับสถาปัตยกรรม Docker แบบ multi-tenant ของเรา จะเป็นรากฐานสำหรับการส่งมอบแอปพลิเคชันที่ติดตั้งและดูแลเอง ซึ่งขยายขนาดและควบคุมได้เต็มที่
ทรัพยากรที่เกี่ยวข้อง
ดูคู่มือเพิ่มเติมเกี่ยวกับโครงสร้างพื้นฐานที่ติดตั้งและดูแลเองได้จาก:
- การติดตั้งและดูแล n8n เองสำหรับเวิร์กโฟลว์อัตโนมัติ – ทำให้การนำระบบขึ้นใช้งานและงานโครงสร้างพื้นฐานเป็นอัตโนมัติ
- การติดตั้งและดูแล Windmill เองด้วย Docker – อีกทางเลือกสำหรับแพลตฟอร์มเวิร์กโฟลว์อัตโนมัติ
- การสร้างชุดระบบ Docker แบบ multi-tenant – การตั้งค่า Traefik อย่างครบถ้วนสำหรับหลายแอปพลิเคชัน
- tva Duplicate Pro – เครื่องมืออัตโนมัติ WordPress สำหรับเวิร์กโฟลว์เนื้อหา
คู่มือเหล่านี้แสดงหลายแง่มุมของการสร้างโครงสร้างพื้นฐานที่ติดตั้งและดูแลเอง ให้คุณควบคุมได้เต็มที่และรักษามาตรฐานระดับมืออาชีพ
รับการสนับสนุนจากผู้เชี่ยวชาญ
การนำ React ขึ้นใช้งานจริงเกี่ยวข้องกับโครงสร้างพื้นฐานหลายด้าน แม้คู่มือนี้อธิบายไว้ครบถ้วน แต่แต่ละโครงการมีข้อกำหนด ข้อจำกัดของโครงสร้างพื้นฐานเดิม และความต้องการด้านประสิทธิภาพเฉพาะ
หากกำลังสร้างโครงสร้างพื้นฐานสำหรับนำ React ขึ้นใช้งานจริง หรือต้องการปรับให้เหมาะกับการส่งมอบงานให้ลูกค้า เราช่วยได้ในเรื่องต่อไปนี้:
- กระบวนการนำระบบขึ้นใช้งานที่ปรับให้เหมาะกับเวิร์กโฟลว์ของคุณ
- การเชื่อมต่อกับระบบ CI/CD ที่มีอยู่
- การเพิ่มประสิทธิภาพสำหรับแอปพลิเคชันที่มีทราฟฟิกสูง
- กลยุทธ์การนำระบบขึ้นใช้งานหลายภูมิภาค
- การฝึกอบรมทีมเกี่ยวกับแนวปฏิบัติที่ดีที่สุดของ Docker และ Traefik
- การจัดการและตรวจสอบโครงสร้างพื้นฐานอย่างต่อเนื่อง
ติดต่อเราผ่าน tva.sg/contact เพื่อหารือเกี่ยวกับความต้องการการนำระบบขึ้นใช้งาน React ของคุณและรับคำแนะนำจากผู้เชี่ยวชาญเกี่ยวกับการนำไปใช้
จากการตั้งค่าสู่การตัดสินใจด้านการดำเนินงาน
คำถามในทางปฏิบัติคือ ทีมอธิบายผู้รับผิดชอบ ตรวจจับค่ากำหนดที่เปลี่ยนจากที่ตั้งใจ กู้คืนได้โดยไม่ต้องแก้เฉพาะหน้า และแสดงหลักฐานว่าการเปลี่ยนแปลงช่วยให้ได้ผลลัพธ์ตามเป้าหมายได้หรือไม่ เราจึงจับคู่การกำหนดค่ากับเจ้าของงาน ค่าอ้างอิงตั้งต้น ขั้นตอนย้อนกลับ และช่วงเวลาตรวจผล เปลี่ยนการแก้ครั้งเดียวให้เป็นขีดความสามารถในการดำเนินงาน บันทึกของระบบใช้งานจริงควรระบุเหตุผล หลักฐานที่ทบทวน ขอบเขตที่แน่นอน และผู้มีสิทธิ์สั่งหยุดหรือย้อนกลับ หลังปล่อยระบบ ให้เทียบตัวชี้วัดที่ตกลงกันไว้กับค่าอ้างอิงตั้งต้น และเก็บผลไว้กับบันทึกการเปลี่ยนแปลง หากไม่ดีขึ้นตามคาด การย้อนกลับเป็นผลลัพธ์ที่ยอมรับได้ ไม่ใช่ความล้มเหลว วินัยนี้สำคัญกว่าค่ากำหนดใดค่าหนึ่ง บันทึกเดียวกันช่วยให้ผู้ดูแลคนถัดไปมีจุดเริ่มต้นที่เชื่อถือได้ และทำให้การเพิ่มประสิทธิภาพครั้งต่อไปอาศัยข้อมูลวัดผลแทนการคาดเดา