0Pricing
DevOps Bootcamp · บทเรียน

การเขียน Dockerfile และจุดเริ่มต้น Shell แบบกระชับ

เขียนสคริปต์สร้างแบบหลายขั้นตอนและตัวเชื่อมจุดเริ่มต้นที่ทนทาน พร้อมการจัดการสัญญาณและแม่แบบการกำหนดค่า

การเขียน Dockerfile และจุดเริ่มต้น Shell แบบกระชับ เป็นบทเรียน DevOps Bootcamp ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน DevOps Bootcamp และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส DevOps Bootcamp มีบทเรียนทั้งหมด 4 บทเรียน

เหตุใด Dockerfile แบบกระชับจึงสำคัญต่อ DevOps

ในสภาพแวดล้อมการใช้งานจริง ทุกเมกะไบต์ในอิมเมจ Docker ล้วนมีต้นทุน ได้แก่ การดึงอิมเมจที่ช้าลง พื้นที่โจมตีที่กว้างขึ้น และพื้นที่จัดเก็บในรีจิสทรีที่สูญเปล่า Dockerfile แบบกระชับที่ใช้ร่วมกับสคริปต์เริ่มต้นของเชลล์ที่แข็งแกร่ง เป็นลักษณะสำคัญของแนวปฏิบัติด้าน DevOps ที่มีวุฒิภาวะ

  • การสร้างแบบหลายขั้นตอน แยกเครื่องมือที่ใช้ขณะสร้างออกจากอิมเมจสำหรับการทำงานจริงขั้นสุดท้าย จึงลดขนาดลงได้อย่างมาก
  • ตัวช่วยเริ่มต้น คือสคริปต์เชลล์ขนาดเล็กที่เตรียมคอนเทนเนอร์ให้พร้อมทำงาน โดยสร้างไฟล์ตั้งค่าจากแม่แบบ ตรวจสอบตัวแปรสภาพแวดล้อม จัดการสัญญาณ และสุดท้ายเรียกใช้กระบวนการหลักโดยตรง
  • เมื่อนำมารวมกัน ทั้งสองสิ่งนี้จะเป็นแกนหลักของงานคอนเทนเนอร์ที่เชื่อถือได้และย้ายข้ามสภาพแวดล้อมได้ใน Kubernetes, ECS และสภาพแวดล้อมที่ติดตั้งบนเครื่องจริง

บทเรียนนี้ครอบคลุมทั้งสองแนวทางตั้งแต่ต้นจนจบ พร้อมรูปแบบระดับใช้งานจริงที่คุณสามารถนำไปใส่ในกระบวนการส่งมอบของคุณได้โดยตรง

โครงสร้างของ Dockerfile แบบหลายขั้นตอน

Dockerfile แบบหลายขั้นตอนใช้คำสั่ง FROM หลายรายการ แต่ละขั้นเป็นชุดเลเยอร์ที่แยกเป็นอิสระ คุณจะคัดลอกเฉพาะสิ่งที่จำเป็นไปยังขั้นถัดไปเท่านั้น

  • ขั้นที่ 0 (ตัวสร้าง): ติดตั้งคอมไพเลอร์ เครื่องมือทดสอบ และสิ่งที่จำเป็นต่อการสร้าง
  • ขั้นที่ 1 (สภาพแวดล้อมการทำงาน): เริ่มจากฐานที่มีขนาดเล็กที่สุด เช่น alpine, distroless และคัดลอกเฉพาะไบนารีที่คอมไพล์แล้วหรือชุดไฟล์แอป
  • อิมเมจสุดท้ายจะไม่มี gcc, make หรือซอร์สโค้ด เว้นแต่คุณจะคัดลอกสิ่งเหล่านี้อย่างชัดเจน

ใช้ --from=<stage> ใน COPY เพื่อดึงไฟล์ข้ามขอบเขตระหว่างขั้น ตั้งชื่อขั้นด้วย AS <name> เพื่อให้อ่านง่าย และเพื่อเลือกเป้าหมายเฉพาะด้วย docker build --target

# ---- Stage 0: builder ----
FROM golang:1.22-alpine AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags='-s -w' -o /app/server ./cmd/server

# ---- Stage 1: runtime ----
FROM gcr.io/distroless/static-debian12
COPY --from=builder /app/server /server
ENTRYPOINT ["/server"]

การลดเลเยอร์และการทำให้แคชใช้ไม่ได้

คำสั่ง RUN, COPY และ ADD แต่ละรายการจะสร้างเลเยอร์ใหม่ การจัดลำดับคำสั่งที่ไม่เหมาะสมทำให้แคชการสร้างใช้ไม่ได้โดยไม่จำเป็น ส่งผลให้กระบวนการส่งมอบแบบต่อเนื่องทำงานช้า

  • คัดลอกไฟล์แสดงรายการสิ่งที่ต้องพึ่งพา (package.json, go.mod, requirements.txt) ก่อน คัดลอกซอร์สโค้ด เพื่อให้การติดตั้งสิ่งที่ต้องพึ่งพาถูกแคชแยกจากกัน
  • เชื่อมคำสั่งที่เกี่ยวข้องด้วย && และล้างข้อมูลใน RUN เลเยอร์เดียวกัน เพื่อไม่ให้แคชแพ็กเกจตกค้างอยู่ในเลเยอร์ขั้นกลาง
  • ใช้ --no-cache กับเครื่องมือจัดการแพ็กเกจ และลบไฟล์รายการหลังการติดตั้ง
FROM python:3.12-slim AS builder
WORKDIR /app

# 1. Install deps first (cached until requirements change)
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt

# 2. Copy source (cache busted only when code changes)
COPY src/ ./src/

FROM python:3.12-slim
COPY --from=builder /install /usr/local
COPY --from=builder /app/src /app/src
WORKDIR /app
CMD ["python", "-m", "src.main"]

ข้อมูลลับของ BuildKit และการส่งต่อ SSH

รีจิสทรีส่วนตัว คีย์ SSH และโทเค็น API ต้อง ไม่ปรากฏ ในเลเยอร์ของอิมเมจโดยเด็ดขาด Docker BuildKit มีกลไกที่ปลอดภัยสองแบบ:

  • --secret: เมานต์ไฟล์ข้อมูลลับไว้ภายในขั้นตอน RUN เพียงขั้นตอนเดียว โดยไม่ฝังข้อมูลนั้นลงในเลเยอร์ เข้าถึงได้ผ่าน /run/secrets/<id>
  • --ssh: ส่งต่อซ็อกเก็ตตัวแทน SSH จากเครื่องโฮสต์เข้าไปในกระบวนการสร้าง เพื่อให้ git clone ยืนยันตัวตนได้โดยไม่ต้องฝังคีย์ส่วนตัว

เปิดใช้ BuildKit ด้วย DOCKER_BUILDKIT=1 หรือผ่าน docker buildx build คำสั่ง # syntax=docker/dockerfile:1 จะเปิดใช้ความสามารถเหล่านี้

# syntax=docker/dockerfile:1
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./

# Mount NPM token as a secret — never stored in the image
RUN --mount=type=secret,id=npm_token \
    NPM_TOKEN=$(cat /run/secrets/npm_token) \
    npm ci --prefer-offline

# Usage at build time:
# DOCKER_BUILDKIT=1 docker build \
#   --secret id=npm_token,src=~/.npmrc-token \
#   -t myapp:latest .

การเขียนตัวช่วยเริ่มต้นที่แข็งแกร่ง

ตัวช่วยเริ่มต้นคือสคริปต์เชลล์ที่กำหนดเป็น ENTRYPOINT ใน Dockerfile หน้าที่ของมันคือเตรียมสภาพแวดล้อมการทำงานก่อนส่งต่อการควบคุมให้กระบวนการหลัก

ตัวช่วยเริ่มต้นที่มีโครงสร้างดีจะทำงานตามลำดับต่อไปนี้:

  • ขั้นที่ 1: ตั้งค่า set -euo pipefail เพื่อให้ความล้มเหลวใด ๆ หยุดการทำงานตั้งแต่เนิ่น ๆ
  • ขั้นที่ 2: ตรวจสอบตัวแปรสภาพแวดล้อมที่จำเป็น และล้มเหลวทันทีพร้อมข้อความที่ช่วยอธิบายปัญหา
  • ขั้นที่ 3: สร้างไฟล์ตั้งค่าจากแม่แบบโดยใช้ตัวแปรสภาพแวดล้อม
  • ขั้นที่ 4: ลงทะเบียนตัวจัดการสัญญาณเพื่อปิดการทำงานอย่างราบรื่น
  • ขั้นที่ 5: exec "$@" — แทนที่เชลล์ด้วยกระบวนการหลัก เพื่อให้ PID 1 เป็นแอปพลิเคชัน ไม่ใช่ตัวช่วยเริ่มต้น

exec สุดท้ายมีความสำคัญอย่างยิ่ง หากไม่มีคำสั่งนี้ สัญญาณที่ Kubernetes หรือสภาพแวดล้อมขณะทำงานของ Docker ส่งมาจะไม่ถูกส่งต่อไปยังกระบวนการลูก

#!/usr/bin/env bash
set -euo pipefail

# Step 2: validate required env vars
REQUIRED_VARS=(DATABASE_URL APP_SECRET PORT)
for var in "${REQUIRED_VARS[@]}"; do
  if [[ -z "${!var:-}" ]]; then
    echo "[entrypoint] ERROR: required env var '$var' is not set" >&2
    exit 1
  fi
done

# Step 3: template config (see next scene)

# Step 4: signal handling (see scene after that)

# Step 5: hand off to CMD
exec "$@"

การสร้างไฟล์ตั้งค่าจากแม่แบบด้วย envsubst

envsubst (จากแพ็กเกจ GNU gettext ซึ่งมีอยู่ใน Alpine ในชื่อ gettext) จะแทนที่ช่องตัวแทน ${VAR} ในไฟล์แม่แบบด้วยค่าปัจจุบันของตัวแปรสภาพแวดล้อม

  • ใส่แม่แบบการตั้งค่า *.tmpl ไว้ในอิมเมจ แล้วให้ตัวช่วยเริ่มต้นสร้างไฟล์จริงเมื่อเริ่มทำงาน
  • ส่งรายการตัวแปรให้ envsubst อย่างชัดเจน เพื่อไม่ให้ขยายเครื่องหมายดอลลาร์ที่ไม่เกี่ยวข้องโดยไม่ตั้งใจ เช่น ในนิพจน์ปกติของ nginx
  • เขียนไฟล์ที่สร้างแล้วไปยังเส้นทางที่เขียนได้ เช่น /tmp หรือวอลุ่มตั้งค่าเฉพาะ
#!/usr/bin/env bash
# Template: /etc/nginx/conf.d/app.conf.tmpl contains:
# server { listen ${NGINX_PORT}; server_name ${SERVER_NAME}; ... }

export NGINX_PORT=${NGINX_PORT:-8080}
export SERVER_NAME=${SERVER_NAME:-localhost}

envsubst '${NGINX_PORT} ${SERVER_NAME}' \
  < /etc/nginx/conf.d/app.conf.tmpl \
  > /etc/nginx/conf.d/app.conf

echo "[entrypoint] nginx config rendered:"
grep -E 'listen|server_name' /etc/nginx/conf.d/app.conf

exec "$@"

การจัดการสัญญาณและการปิดการทำงานอย่างราบรื่น

คอนเทนเนอร์จะได้รับ SIGTERM เมื่อ Kubernetes, ECS หรือ docker stop สั่งหยุด หากตัวช่วยเริ่มต้นของคุณเป็น PID 1 และไม่ส่งต่อสัญญาณ กระบวนการหลักจะถูกฆ่าด้วย SIGKILL หลังพ้นช่วงเวลาผ่อนผัน ซึ่งอาจทำให้คำขอสูญหายหรือข้อมูลเสียหาย

  • ใช้ trap เพื่อดักจับ SIGTERM และ SIGINT ในตัวช่วยเริ่มต้น
  • ส่งต่อสัญญาณไปยัง PID ของกระบวนการลูกด้วย kill -TERM "$child"
  • ใช้ wait "$child" เพื่อรอจนกระบวนการลูกสิ้นสุด แล้วส่งต่อรหัสการสิ้นสุดของกระบวนการนั้น
  • อีกทางเลือกหนึ่งคือใช้ exec เพื่อแทนที่เชลล์ทั้งหมด จากนั้น OS จะส่งสัญญาณไปยังกระบวนการลูกโดยตรงโดยไม่ต้องใช้ trap วิธีนี้เป็นรูปแบบที่แนะนำสำหรับกรณีทั่วไปที่ไม่ซับซ้อน
#!/usr/bin/env bash
set -euo pipefail

# Start main process in background
"$@" &
child=$!

# Forward SIGTERM and SIGINT to the child
trap 'echo "[entrypoint] caught SIGTERM, forwarding..."; kill -TERM "$child"' TERM
trap 'echo "[entrypoint] caught SIGINT, forwarding...";  kill -INT  "$child"' INT

# Wait for child to exit and capture its exit code
wait "$child"
exit $?

การใช้ tini เป็นกระบวนการเริ่มต้นขนาดเล็ก

เมื่อคอนเทนเนอร์สร้างกระบวนการลูก เช่น เชลล์ที่แยกกระบวนการทำงานย่อย คุณจะต้องมี init ที่แท้จริงเพื่อเก็บกวาดกระบวนการซอมบี้ tini คือไบนารี init ขนาดเล็กที่ออกแบบมาโดยเฉพาะสำหรับคอนเทนเนอร์

  • เพิ่ม tini ลงในอิมเมจ และตั้งให้เป็นตัวห่อหุ้มจุดเริ่มต้น
  • มันจะเก็บกวาดกระบวนการลูกที่กลายเป็นซอมบี้ ส่งต่อสัญญาณอย่างถูกต้อง และจบการทำงานด้วยรหัสสถานะของกระบวนการลูก
  • Docker มี tini ในตัว ซึ่งเปิดใช้ด้วย docker run --init แต่การฝังไว้ในอิมเมจจะทำให้พฤติกรรมสอดคล้องกันในสภาพแวดล้อมขณะทำงานต่าง ๆ เช่น Kubernetes และ ECS
FROM node:20-alpine

# Install tini for proper signal handling and zombie reaping
RUN apk add --no-cache tini

WORKDIR /app
COPY --chown=node:node . .
RUN npm ci --omit=dev

USER node

# tini wraps CMD; forwards SIGTERM and reaps zombies
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["node", "server.js"]

การทำงานในฐานะผู้ใช้ที่ไม่ใช่รูท

คอนเทนเนอร์ที่ทำงานในฐานะ root (UID 0) มีความเสี่ยงด้านความปลอดภัยอย่างมาก เพราะการหลบหนีจากคอนเทนเนอร์จะทำให้เข้าถึงโฮสต์ได้อย่างเต็มรูปแบบ ควรเปลี่ยนไปใช้ผู้ใช้ที่ไม่มีสิทธิ์พิเศษก่อนเรียกใช้กระบวนการหลักเสมอ

  • สร้างผู้ใช้และกลุ่มระบบเฉพาะใน Dockerfile ด้วย addgroup / adduser (Alpine) หรือ groupadd / useradd (Debian)
  • เปลี่ยนเจ้าของไฟล์แอปด้วย COPY --chown=appuser:appgroup ซึ่งมีประสิทธิภาพมากกว่าการสร้างเลเยอร์ RUN chown แยกต่างหาก
  • เปลี่ยนไปใช้ผู้ใช้ดังกล่าวด้วยคำสั่ง USER ตัวช่วยเริ่มต้นและ CMD จะสืบทอดผู้ใช้นี้
  • Kubernetes securityContext.runAsNonRoot: true จะปฏิเสธการเริ่มอิมเมจที่ยังทำงานในฐานะรูท
FROM python:3.12-slim

# Create non-root user
RUN groupadd --gid 1001 appgroup && \
    useradd --uid 1001 --gid appgroup --shell /bin/bash --create-home appuser

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy app files with correct ownership in a single layer
COPY --chown=appuser:appgroup src/ ./src/
COPY --chown=appuser:appgroup entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

USER appuser

ENTRYPOINT ["/entrypoint.sh"]
CMD ["python", "-m", "src.main"]

การตรวจสอบสุขภาพและการตรวจสอบความพร้อมในอิมเมจ

การตรวจสอบว่ายังทำงานอยู่และการตรวจสอบความพร้อมของ Kubernetes กำหนดไว้ในไฟล์แสดงรายการทรัพยากร แต่คุณยังสามารถฝัง HEALTHCHECK ไว้ใน Dockerfile สำหรับสภาพแวดล้อมแบบสแตนด์อโลนที่ใช้ docker run และ Docker Compose ได้

  • HEALTHCHECK --interval=10s --timeout=3s --start-period=15s --retries=3 CMD ...
  • ใช้ curl --fail หรือ wget -qO- กับบริการ HTTP ส่วนดีมอนที่ไม่ใช่ HTTP ให้ตรวจสอบซ็อกเก็ตด้วย /dev/tcp/localhost/PORT
  • ติดตั้งเฉพาะสิ่งที่จำเป็น: ในอิมเมจ distroless หลีกเลี่ยงการเพิ่ม curl เพียงเพื่อการตรวจสอบสุขภาพ ให้ใช้ไบนารีสำหรับตรวจสอบที่สร้างมาโดยเฉพาะ หรือไบนารีตรวจสอบสุขภาพของแอปเอง
FROM nginx:1.27-alpine

COPY nginx.conf /etc/nginx/nginx.conf
COPY dist/ /usr/share/nginx/html/

# Lightweight health check using bash TCP pseudo-device
# (no curl needed — works on any image with bash)
HEALTHCHECK --interval=15s --timeout=5s --start-period=10s --retries=3 \
  CMD bash -c 'exec 3<>/dev/tcp/localhost/80 && echo -e "GET /health HTTP/1.0\r\n" >&3 && cat <&3 | grep -q "200 OK"' || exit 1

EXPOSE 80

รวมทุกอย่างเข้าด้วยกัน: ตัวช่วยเริ่มต้นสำหรับใช้งานจริง

ต่อไปนี้คือตัวช่วยเริ่มต้นฉบับสมบูรณ์ระดับใช้งานจริง ซึ่งรวมรูปแบบทั้งหมดจากบทเรียนนี้ ได้แก่ การตรวจสอบสภาพแวดล้อม การสร้างไฟล์ตั้งค่าจากแม่แบบ การส่งต่อสัญญาณ และการส่งต่อด้วย exec รูปแบบนี้ใช้ในไมโครเซอร์วิส Node.js, Python และ Go ที่ใช้งานจริงบน Kubernetes

  • ทุกส่วนมีคำอธิบายกำกับไว้ เพื่อทำหน้าที่เป็นแม่แบบที่อธิบายตัวเอง
  • ตัวช่วยเริ่มต้นมีความยาวไม่เกิน 50 บรรทัด เพราะจุดเริ่มต้นควรเรียบง่ายและตรวจสอบได้
  • สังเกต exec "$@" สุดท้าย: เมื่อตั้งค่าทั้งหมดเสร็จแล้ว เชลล์จะถูกแทนที่ด้วยกระบวนการแอปพลิเคชัน ทำให้แอปเป็น PID 1 และรับสัญญาณ OS ทั้งหมดโดยตรง
#!/usr/bin/env bash
# entrypoint.sh — production-grade container entrypoint shim
set -euo pipefail

# ── 1. Validate required environment variables ──────────────────
REQUIRED=(DATABASE_URL APP_SECRET PORT LOG_LEVEL)
for var in "${REQUIRED[@]}"; do
  [[ -n "${!var:-}" ]] || { echo "[entrypoint] FATAL: $var is not set" >&2; exit 1; }
done

# ── 2. Set safe defaults for optional variables ─────────────────
export HOST=${HOST:-0.0.0.0}
export WORKERS=${WORKERS:-2}

# ── 3. Render config template ───────────────────────────────────
if [[ -f /etc/app/app.conf.tmpl ]]; then
  envsubst '${DATABASE_URL} ${PORT} ${LOG_LEVEL} ${HOST}' \
    < /etc/app/app.conf.tmpl \
    > /etc/app/app.conf
  echo "[entrypoint] config rendered at /etc/app/app.conf"
fi

# ── 4. Wait for dependent services (optional, fast) ─────────────
if [[ -n "${WAIT_FOR_HOST:-}" ]]; then
  echo "[entrypoint] waiting for ${WAIT_FOR_HOST}:${WAIT_FOR_PORT:-5432}..."
  until bash -c "exec 3<>/dev/tcp/${WAIT_FOR_HOST}/${WAIT_FOR_PORT:-5432}" 2>/dev/null; do
    sleep 1
  done
  echo "[entrypoint] dependency ready"
fi

# ── 5. Hand off to CMD (PID 1 becomes the application) ──────────
echo "[entrypoint] starting: $*"
exec "$@"

ตรวจสอบความรู้: การจัดการสัญญาณในจุดเริ่มต้น

ทดสอบความเข้าใจของคุณเกี่ยวกับการจัดการสัญญาณในสคริปต์จุดเริ่มต้นของคอนเทนเนอร์

ทบทวน: Dockerfile แบบกระชับและจุดเริ่มต้นของเชลล์

คุณได้ครอบคลุมการเขียนคอนเทนเนอร์สำหรับใช้งานจริงครบทั้งชุดแล้ว:

  • การสร้างแบบหลายขั้นตอน ใช้คำสั่ง FROM หลายรายการเพื่อไม่นำคอมไพเลอร์และเครื่องมือสร้างเข้าไปในอิมเมจสุดท้าย ทำให้ได้เลเยอร์ขณะทำงานที่กระชับและมีขนาดเล็ก
  • การจัดลำดับเลเยอร์ — คัดลอกไฟล์แสดงรายการสิ่งที่ต้องพึ่งพาก่อนซอร์สโค้ด — ช่วยเพิ่มการใช้แคชและเร่งกระบวนการส่งมอบแบบต่อเนื่อง
  • ข้อมูลลับและการเมานต์ SSH ของ BuildKit ช่วยเก็บข้อมูลรับรองไว้นอกประวัติอิมเมจ โดยไม่ทำให้การสร้างที่ต้องยืนยันตัวตนเสียหาย
  • ตัวช่วยเริ่มต้น ตรวจสอบตัวแปรสภาพแวดล้อม สร้างไฟล์ตั้งค่าจากแม่แบบด้วย envsubst และส่งต่อให้อัปพลิเคชันผ่าน exec "$@"
  • การจัดการสัญญาณ ต้องใช้ exec เพื่อให้แอปเป็น PID 1 หรือใช้รูปแบบ trap + kill + wait อย่างชัดเจนเมื่อมีงานเบื้องหลัง
  • tini เพิ่มความสามารถในการเก็บกวาดกระบวนการซอมบี้และส่งต่อสัญญาณอย่างถูกต้อง เมื่อคอนเทนเนอร์สร้างหลายกระบวนการ
  • ผู้ใช้ที่ไม่ใช่รูท และคำสั่ง HEALTHCHECK ช่วยให้อิมเมจปลอดภัย ตรวจสอบได้ และพร้อมสำหรับงานจริงบน Kubernetes

ใช้รูปแบบเหล่านี้ร่วมกันอย่างสม่ำเสมอ แล้วอิมเมจของคุณจะมีขนาดเล็กลง นำไปใช้งานได้เร็วขึ้น และแข็งแกร่งขึ้นอย่างมากภายใต้สภาวะการใช้งานจริง

คำถามที่พบบ่อย

บทเรียน “การเขียน Dockerfile และจุดเริ่มต้น Shell แบบกระชับ” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การเขียน Dockerfile และจุดเริ่มต้น Shell แบบกระชับ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส DevOps Bootcamp ให้อัปเกรดเป็น CoddyKit PRO คอร์ส DevOps Bootcamp มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การเขียน Dockerfile และจุดเริ่มต้น Shell แบบกระชับ”

เขียนสคริปต์สร้างแบบหลายขั้นตอนและตัวเชื่อมจุดเริ่มต้นที่ทนทาน พร้อมการจัดการสัญญาณและแม่แบบการกำหนดค่า คุณปฏิบัติ DevOps Bootcamp ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน DevOps Bootcamp หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน DevOps Bootcamp บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน

บทเรียน “การเขียน Dockerfile และจุดเริ่มต้น Shell แบบกระชับ” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน DevOps Bootcamp นี้ได้ไหม

ได้ บทเรียน DevOps Bootcamp ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การเขียน Dockerfile และจุดเริ่มต้น Shell แบบกระชับ
  2. การสร้างแม่แบบการกำหนดค่าด้วย envsubst และ heredoc
  3. การเขียนสคริปต์จัดการทรัพยากรคลาวด์ด้วย CLI และ jq
  4. โพรบสุขภาพ ด่านความพร้อม และลูปรอ
← กลับไปที่ DevOps Bootcamp