Givepo
บล็อก

Cloud Computing และ DevOps: คู่มือปฏิบัติจริงเรื่อง Docker, CI/CD และการ Deploy ที่เชื่อถือได้

ตั้งแต่ Dockerfile ที่พร้อมใช้บน production ไปจนถึง pipeline อัตโนมัติและการปล่อยเวอร์ชันโดยไม่มี downtime: แนวทาง DevOps ที่ช่วยให้ทีมเล็กปล่อยงานได้หลายครั้งต่อวันโดยระบบไม่พัง

ทีมงาน Givepo
อ่าน 6 นาที
Illustration of a cloud above a CI/CD pipeline with build, test and scan steps passed and deploy in progress, next to a stack of containersคลาวด์และ DevOps

การเขียนโค้ดเป็นเพียงครึ่งหนึ่งของการส่งมอบซอฟต์แวร์ อีกครึ่งคือการ build ทดสอบ นำขึ้นเซิร์ฟเวอร์ และดูแลให้ทำงานต่อเนื่อง ซึ่งในอุดมคติควรทำได้หลายครั้งต่อสัปดาห์โดยไม่ต้องอดนอนแก้ปัญหากลางดึก DevOps คือชุดแนวทางที่ทำให้เรื่องนี้เป็นงานประจำ ส่วน container, CI/CD pipeline และโครงสร้างพื้นฐานบนคลาวด์คือเครื่องมือที่ทำให้ทำได้จริง

DevOps หมายถึงอะไรจริงๆ

DevOps ไม่ใช่ชื่อตำแหน่งหรือเครื่องมือ แต่เป็นแนวคิดที่ว่าคนที่สร้างซอฟต์แวร์และคนที่ดูแลระบบต้องรับผิดชอบทั้งสองด้านร่วมกัน โดยมีระบบอัตโนมัติจำนวนมากคอยสนับสนุน โครงการวิจัย DORA สรุปประสิทธิภาพการส่งมอบไว้ด้วยตัวชี้วัดสี่ตัว:

  • ความถี่ในการ deploy: คุณปล่อยงานขึ้น production บ่อยแค่ไหน
  • ระยะเวลาของการเปลี่ยนแปลง: commit หนึ่งใช้เวลานานเท่าไรกว่าจะถึง production
  • อัตราความล้มเหลวของการเปลี่ยนแปลง: การปล่อยงานทำให้เกิดปัญหาที่ต้องแก้ไขบ่อยเพียงใด
  • เวลาในการกู้คืนบริการ: คุณกู้ระบบกลับมาได้เร็วแค่ไหนเมื่อการปล่อยงานล้มเหลว

ทีมที่มีประสิทธิภาพสูงทำคะแนนได้ดีทั้งสี่ตัวพร้อมกัน ปรากฏว่าการปล่อยการเปลี่ยนแปลงเล็กๆ บ่อยๆ ทั้งเร็วกว่าและปลอดภัยกว่าการปล่อยงานก้อนใหญ่นานๆ ครั้ง

Container ด้วย Docker

Container image รวมแอปพลิเคชันของคุณเข้ากับ runtime, ไลบรารีของระบบ และค่าคอนฟิกเริ่มต้นที่แน่นอน ส่วน container คืออินสแตนซ์ของ image นั้นที่กำลังทำงาน เพราะ image เหมือนกันทุกประการทั้งบนแล็ปท็อป ใน CI และบน production ปัญหา "เครื่องผมรันได้นะ" จึงหมดไป

Multi-stage build ทำให้ image สำหรับ production มีขนาดเล็กและปลอดภัย การติดตั้ง dependency และคอมไพล์แอปเกิดขึ้นใน stage ชั่วคราว แล้วคัดลอกเฉพาะผลลัพธ์ไปไว้ใน runtime image ที่เล็กที่สุด นี่คือตัวอย่างสำหรับแอป Next.js ที่ build ด้วย output: 'standalone':

Dockerfile
# syntax=docker/dockerfile:1
FROM node:24-alpine AS deps
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable && pnpm install --frozen-lockfile

FROM node:24-alpine AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN corepack enable && pnpm build

FROM node:24-alpine AS runtime
WORKDIR /app
ENV NODE_ENV=production
# Never run the application as root
RUN addgroup -S app && adduser -S app -G app
COPY --from=build --chown=app:app /app/.next/standalone ./
COPY --from=build --chown=app:app /app/.next/static ./.next/static
COPY --from=build --chown=app:app /app/public ./public
USER app
EXPOSE 3000
CMD ["node", "server.js"]

แนวทางที่ดีสำหรับ container ที่ควรใช้ตั้งแต่วันแรก:

  • เพิ่มไฟล์ .dockerignore เพื่อไม่ให้ node_modules, .git และข้อมูลลับในเครื่องหลุดเข้าไปใน build context
  • ระบุเวอร์ชันของ base image ให้แน่นอน และ build ใหม่เป็นประจำเพื่อรับแพตช์ความปลอดภัย
  • รันหนึ่งโปรเซสต่อหนึ่ง container และเขียน log ออก standard output ให้แพลตฟอร์มเก็บรวบรวม
  • ส่งค่าคอนฟิกผ่านตัวแปรสภาพแวดล้อม และเก็บข้อมูลลับไว้นอก image ทั้งหมด
  • เก็บข้อมูลไว้ใน volume หรือบริการแบบ managed ห้ามเก็บในตัว container ซึ่งอาจถูกแทนที่ได้ทุกเมื่อ

สำหรับการพัฒนาในเครื่องและการ deploy ขนาดเล็ก Docker Compose อธิบาย container หลายตัวและวิธีเชื่อมต่อกันไว้ในไฟล์เดียว:

YAML
services:
  app:
    build: .
    ports:
      - '3000:3000'
    environment:
      DATABASE_URL: postgres://app:${POSTGRES_PASSWORD}@db:5432/app
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres:17
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: app
    volumes:
      - db-data:/var/lib/postgresql/data
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U app']
      interval: 5s
      retries: 10

volumes:
  db-data:

CI/CD Pipeline

Continuous Integration (CI) หมายถึงทุกครั้งที่ push จะมีการ build และทดสอบอัตโนมัติ เพื่อให้ปัญหาปรากฏภายในไม่กี่นาที แทนที่จะเจอไม่กี่วันก่อนปล่อยงาน Continuous Delivery (CD) ต่อยอดจากนั้น ทุกการเปลี่ยนแปลงที่ผ่าน pipeline จะถูกแพ็กเกจพร้อม deploy และใน Continuous Deployment จะถูกนำขึ้น production โดยอัตโนมัติ

Pipeline พื้นฐานที่แข็งแรงบน GitHub Actions จะติดตั้ง dependency ตรวจไทป์ รันเทสต์ และ build ทุก pull request และทุกครั้งที่ push เข้า main:

YAML
name: CI

on:
  push:
    branches: [main]
  pull_request:

jobs:
  verify:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: pnpm/action-setup@v4
        with:
          version: 10
      - uses: actions/setup-node@v5
        with:
          node-version: 24
          cache: pnpm
      - run: pnpm install --frozen-lockfile
      - run: pnpm typecheck
      - run: pnpm test
      - run: pnpm build

จากนั้นเพิ่มขั้นตอนสำหรับเรื่องที่ทีมของคุณเจอปัญหาซ้ำๆ เช่น สแกนช่องโหว่ของ dependency และ container image, end-to-end test บน preview environment และ job สำหรับ deploy ที่รันเฉพาะบน main หลังทุกอย่างผ่านหมดแล้ว รักษา pipeline ให้เร็วเข้าไว้ pipeline สิบนาทีจะถูกใช้จริง แต่ pipeline สี่สิบนาทีจะถูกหาทางเลี่ยง

กลยุทธ์การ Deploy

วิธีปล่อยงานสำคัญพอๆ กับสิ่งที่ปล่อย เป้าหมายคือไม่มี downtime และมีทางถอยกลับที่เร็วและเรียบง่ายเมื่อมีปัญหา:

  • Rolling update: แทนที่อินสแตนซ์ทีละไม่กี่ตัว เรียบง่ายและเป็นค่าเริ่มต้นในแพลตฟอร์มส่วนใหญ่ แต่เวอร์ชันเก่าและใหม่จะทำงานคู่กันช่วงหนึ่ง
  • Blue-green: รันเวอร์ชันใหม่ข้างเวอร์ชันเก่า ทดสอบให้เรียบร้อย แล้วสลับทราฟฟิกทั้งหมดในครั้งเดียว การ rollback คือการสลับกลับ
  • Canary: ส่งทราฟฟิกส่วนน้อย เช่น 5% ไปยังเวอร์ชันใหม่ ติดตามอัตราข้อผิดพลาดและความหน่วง แล้วค่อยๆ เพิ่มสัดส่วน
  • Feature flag: deploy โค้ดในสถานะปิด แล้วค่อยเปิดให้ผู้ใช้ที่เลือกไว้ภายหลัง วิธีนี้แยกการ deploy ออกจากการเปิดใช้งาน

การเปลี่ยนแปลงฐานข้อมูลก็ต้องระวังไม่แพ้กัน ใช้รูปแบบ expand and contract คือ เพิ่มคอลัมน์หรือตารางใหม่แบบที่เข้ากันได้กับของเดิมก่อน deploy โค้ดที่ใช้ของใหม่ แล้วจึงลบโครงสร้างเก่าในการปล่อยงานรอบถัดไป วิธีนี้ทำให้แอปเวอร์ชันก่อนหน้ายังทำงานได้ทั้งระหว่าง deploy และเมื่อ rollback

โครงสร้างพื้นฐานบนคลาวด์แบบเข้าใจง่าย

ผู้ให้บริการคลาวด์มีตัวเลือกไล่ตั้งแต่ virtual machine เปล่าๆ (IaaS) ผ่านแพลตฟอร์มแบบ managed และบริการ container (PaaS) ไปจนถึงฟังก์ชันแบบ serverless ที่คุณส่งแค่โค้ด ยิ่งไปทางหลัง คุณยิ่งต้องดูแลเองน้อยลงและควบคุมได้น้อยลง สำหรับทีมส่วนใหญ่ จุดที่ลงตัวคือใช้บริการแบบ managed สำหรับส่วนที่ยาก (ฐานข้อมูล คิว object storage และ load balancer) และใช้ container สำหรับตัวแอปพลิเคชัน

กำหนดโครงสร้างพื้นฐานเหล่านั้นเป็นโค้ดด้วยเครื่องมืออย่าง Terraform, OpenTofu หรือ Pulumi แล้วเซิร์ฟเวอร์ เครือข่าย และ DNS ของคุณจะอยู่ในระบบควบคุมเวอร์ชัน ถูกรีวิวเหมือนโค้ด และสร้างใหม่ได้ในไม่กี่นาที รวมถึง staging environment ที่เหมือน production จริงๆ

หลักสำคัญในการดูแลและรักษาความปลอดภัยเซิร์ฟเวอร์

  • สิทธิ์ขั้นต่ำ: ทุกคน ทุกบริการ และทุก job ใน CI ได้รับสิทธิ์เท่าที่จำเป็นเท่านั้น
  • ข้อมูลลับต้องอยู่ใน secrets manager หรือการตั้งค่าที่เข้ารหัสของแพลตฟอร์ม ห้ามอยู่ใน repository หรือ image
  • อัปเดตแพตช์ของระบบปฏิบัติการ base image และ dependency ตามรอบ และทำให้อัตโนมัติเท่าที่ทำได้
  • เครือข่ายส่วนตัว: ไม่เปิดฐานข้อมูลสู่อินเทอร์เน็ตสาธารณะ เปิดเฉพาะ load balancer
  • ใช้ HTTPS ทุกที่ พร้อมต่ออายุใบรับรองอัตโนมัติ
  • ข้อมูลสำรองจะมีค่าก็ต่อเมื่อกู้คืนได้จริง: ทำให้อัตโนมัติ เข้ารหัส เก็บไว้อีกที่หนึ่ง และทดลองกู้คืนเป็นประจำ
  • ระบบติดตามและแจ้งเตือนเรื่องความพร้อมใช้งาน อัตราข้อผิดพลาด และความหน่วง พร้อมเวรรับเหตุ และคู่มือรับมือ (runbook) สำหรับเหตุการณ์ที่พบบ่อย

ประเด็นสำคัญ

  • Container ทำให้การ build ทำซ้ำได้ ใช้ multi-stage build, base image ขนาดเล็ก และผู้ใช้ที่ไม่ใช่ root
  • ทำเส้นทางสู่ production ให้เป็นอัตโนมัติ ทุกการเปลี่ยนแปลงถูก build ทดสอบ และสแกนด้วยวิธีเดียวกัน
  • ปล่อยการเปลี่ยนแปลงเล็กๆ บ่อยๆ และใช้ blue-green, canary หรือ feature flag เพื่อลดความเสี่ยงในการปล่อยงาน
  • จัดการโครงสร้างพื้นฐานเป็นโค้ด ใช้บริการแบบ managed กับส่วนที่มีสถานะ และฝึกกู้คืนข้อมูลสำรอง

สรุป

DevOps ให้ผลตอบแทนเป็นความสงบ ไม่ใช่แค่ความเร็ว เมื่อการ build ทำซ้ำได้ pipeline จับปัญหาได้ตั้งแต่เนิ่นๆ และทุกการปล่อยงาน rollback ได้ในหนึ่งนาที การ deploy ก็ไม่ใช่เหตุการณ์ใหญ่อีกต่อไป แต่กลายเป็นงานประจำ เริ่มจาก Dockerfile และ CI pipeline ที่รันเทสต์ของคุณ แล้วค่อยๆ ทำขั้นตอนที่ทำด้วยมือให้เป็นอัตโนมัติทีละขั้น

อ่านเพิ่มเติม

  • #CI/CD
  • #Cloud
  • #DevOps
  • #Docker
เขียนโดย
ทีมงาน Givepo

Givepo คือบริษัทไอทีที่พัฒนาเว็บไซต์ แอปมือถือ และซอฟต์แวร์เฉพาะทาง เพื่อผลักดันธุรกิจของคุณให้ก้าวไปข้างหน้า

แชร์บทความนี้

ปรึกษาฟรี 30 นาที

พูดคุยเรื่องไอเดีย ขอบเขตงาน และงบประมาณกับทีมของเรา

นัดหมายปรึกษา

บทความอื่นๆ

บล็อก
AI และแมชชีนเลิร์นนิง
·อ่าน 8 นาที

AI และ Machine Learning ในการใช้งานจริง: สร้างคุณค่าทางธุรกิจได้ที่ไหนบ้าง

มองให้ทะลุกระแส เข้าใจว่า Machine Learning และ Generative AI ทำงานอย่างไรจริงๆ สร้างคุณค่าที่วัดผลได้ในงานแบบไหนบ้างในวันนี้ และจะทำโปรเจกต์ AI แรกให้ใช้งานได้จริงอย่างไร แทนที่จะจบแค่เดโม

ดูรายละเอียด
พัฒนาเว็บ
·อ่าน 6 นาที

พัฒนาเว็บยุคใหม่ด้วย Next.js, React และ TypeScript: แนวทางปฏิบัติที่ดีที่สุด

Server Components กลยุทธ์การเรนเดอร์ ข้อมูลที่ปลอดภัยด้วยไทป์ และ Core Web Vitals คู่มือปฏิบัติจริงสำหรับสร้างเว็บแอปที่เร็วและดูแลง่าย ด้วยชุดเทคโนโลยีที่ทีมส่วนใหญ่เลือกใช้ในวันนี้

ดูรายละเอียด
แบ็กเอนด์และ API
·อ่าน 7 นาที

อธิบายสถาปัตยกรรมแบ็กเอนด์: REST API, Microservices และฐานข้อมูลที่ขยายได้

วิธีออกแบบ REST API ที่นักพัฒนาชอบใช้ เมื่อไรที่ Microservices คุ้มค่ากับต้นทุน วิธีออกแบบฐานข้อมูลที่รับโหลดหนักได้ และรูปแบบที่ทำให้ระบบแบ็กเอนด์เร็วและเสถียร

ดูรายละเอียด