1. บทนำ: Docker BuildKit คืออะไร?
Docker BuildKit เป็น backend build engine ของ Docker ที่ถูกพัฒนาขึ้นมาเพื่อแก้ไขข้อจำกัดของ Docker build แบบเดิม ช่วยให้การ build container images เร็วขึ้น มีประสิทธิภาพมากขึ้น และรองรับฟีเจอร์ขั้นสูงได้หลากหลาย
BuildKit ถูกแนะนำตั้งแต่ Docker 18.06 และปัจจุบันเป็น default build engine ตั้งแต่ Docker 23.04+
ข้อดีของ BuildKit
- Fast builds: Parallel execution และ intelligent caching
- Advanced mount types: cache, secret, ssh mounts
- Multi-stage build: Optimize ขนาด image
- Concurrent caching: Build multiple images จาก Dockerfile เดียวกัน
- Selinux/AppArmor support: ปลอดภัยมากขึ้น
BuildKit vs Legacy Builder: Legacy builder run ทีละ step โดยไม่มี intelligent cache แต่ BuildKit วิเคราะห์ dependency graph และ execute tasks แบบ parallel ทำให้ build เร็วขึ้นอย่างมากเมื่อมีการเปลี่ยนแปลงน้อย
BuildKit Architecture Diagram / โครงสร้างระบบ
2. สิ่งที่ต้องเตรียม (Prerequisites)
Software Requirements
- Docker Engine: v23.04+ (BuildKit เป็น default)
- Docker CLI: v23.04+
- OS: Linux (Ubuntu 20.04+, Debian, CentOS 8+, etc.)
- Environment: ไม่ต้องเปิด BuildKit แยก (default แล้ว)
Hardware Requirements
- CPU: 2 cores minimum (4+ สำหรับ multi-platform builds)
- RAM: 4GB minimum (8GB+ แนะนำสำหรับ large projects)
- Disk: 20GB free space (cache จะใช้พื้นที่)
- Network: สัญญาณอินเทอร์เน็ตที่เสถียรสำหรับ pull/push images
ความรู้พื้นฐานที่ควรรู้
- Docker basics (docker build, docker run, docker images)
- Dockerfile syntax และคำสั่งพื้นฐาน (FROM, RUN, COPY, CMD)
- Multi-stage builds concept
- ความเข้าใจพื้นฐานของ terminal/command line
- ความรู้พื้นฐาน v security ( secrets management)
วิธีตรวจสอบ BuildKit
# ตรวจสอบ Docker version (ต้องเป็น 23.04+)
$ docker --version
Docker version 24.0.5, build ced0996
# ตรวจสอบว่า BuildKit ถูกใช้งาน
$ docker buildx version
github.com/docker/buildx v0.14.0 ...
# Build ด้วย BuildKit explicitly (แม้จะเป็น default แล้วก็ตาม)
$ DOCKER_BUILDKIT=1 docker build -t myapp:latest .
3. Cache Mounts: ลดเวลา build อย่างมีประสิทธิภาพ
Cache Mounts เป็นฟีเจอร์ของ BuildKit ที่ช่วยให้เรา cache ข้อมูลระหว่าง build ต่างๆ อย่างมีประสิทธิภาพมากกว่าการใช้ Docker cache แบบ legacy ทำงานได้ดีกับ tools อย่าง npm, pip, go mod, danmaku, และ other toolchains
BuildKit Cache Mounts vs Legacy Layer Caching: Legacy layer caching ต้องใช้ cache ที้ง layer และไม่สามารถ cache ระหว่าง build ได้ดี BuildKit cache mounts สามารถ cache ข้อมูลไปยัง registry หรือ local และใช้ได้ข้าม builds
Cache Mount Options
id=cache-name
ระบุชื่อ cache ( mandatory)
type=cache|tmpfs|bind
ประเภทของ cache (default: cache)
mode=0777
Permission mode (default: 0755)
uid=1000, gid=1000
User/group ID (default: 0)
ตัวอย่างการใช้งาน
ตัวอย่างนี้จะ cache npm dependencies ระหว่าง build ต่างๆ:
# syntax=docker/dockerfile:1
FROM node:20-alpine AS base
# Node.js dependencies cache
FROM base AS deps
RUN --mount=type=cache,target=/root/.npm \
npm ci
# Build application
FROM deps AS build
WORKDIR /app
COPY . .
RUN --mount=type=cache,target=/root/.npm \
npm run build
# Production stage
FROM base AS production
WORKDIR /app
COPY --from=build /app/dist ./dist
COPY --from=deps /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/index.js"]
เมื่อ rebuild ถ้า package.json ไม่เปลี่ยน npm ci จะใช้ cache ที่มีอยู่แล้ว
Registry Cache Mounts (Shared Cache)
Registry cache mounts ช่วยให้ cache ถูกแชร์ระหว่าง build ต่างๆ (แม้จะเป็นต่างเครื่องกัน)
# Build พร้อม Registry Cache
$ docker build \
--cache-from=type=registry,ref=myregistry.com/myapp:buildcache \
--cache-to=type=registry,ref=myregistry.com/myapp:buildcache,mode=max \
-t myapp:latest .
คำอธิบาย:
type=registry: เก็บ cache ที่ container registryref=...: ชื่อ image ที่ใช้เก็บ cachemode=max: เก็บ cache ทุก layer ที่สร้าง (default: min)- เหมาะกับ CI/CD ที่ใช้ temporary agents
Cache Mount Strategy / กลยุทธ์การ Cache
4. Secret Mounts: จัดการข้อมูลลับอย่างปลอดภัย
Secret Mounts เป็นวิธีการส่ง secrets (API keys, passwords, tokens) ไปยัง build context อย่างปลอดภัย secrets จะถูก mount เข้าไปใน container ด้วย tmpfs (memory-based filesystem) ซึ่งปลอดภัยกว่า environment variables
ข้อดีของ Secret Mounts
- Safe: secrets ไม่ถูกเก็บใน image layers
- Temp: tmpfs ถูกลบออกเมื่อ container หยุด
- Restricted: สิทธิ์สามารถกำหนดได้ (mode, uid, gid)
- No build args: secrets ไม่ถูกแสดงใน build logs
ข้อควรระวัง
- อย่าใช้ secrets กับ public builds
- อย่า commit secrets ไปกับ build context
- ล้าง secrets ออกจาก cache ใน CI/CD
ตัวอย่างการใช้งาน Secret Mounts
ตัวอย่าง: สร้าง Docker image ที่ต้องใช้ private npm registry token
# syntax=docker/dockerfile:1
FROM node:20-alpine
# Mount secret token
RUN --mount=type=secret,id=npm_token \
echo "//registry.npmjs.org/:_authToken=\$(cat /run/secrets/npm_token)" > /root/.npmrc
# Install dependencies (will use private registry)
RUN npm ci
# Clean up .npmrc for security
RUN rm -f /root/.npmrc
WORKDIR /app
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["node", "dist/index.js"]
Build with Secret File
# 1. สร้างไฟล์ secrets (อย่า commit ไฟล์นี้!)
$ echo "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" > .secrets/npm_token
# 2. Build พร้อม secret mount
$ docker build \
--secret id=npm_token,src=.secrets/npm_token \
-t myapp:latest .
# 3. หรือใช้ environment variable
$ export NPM_TOKEN="ghp_xxxxxxxxx..."
$ echo $NPM_TOKEN > .secrets/npm_token
$ docker build --secret id=npm_token,src=.secrets/npm_token -t myapp:latest .
# Clean up
$ rm .secrets/npm_token
เส้นทาง relative ของ source file จะถูกอ้างอิงจาก build context (directory ที่รัน docker build)
ใช้งาน Secrets หลายอันพร้อมกัน
# syntax=docker/dockerfile:1
FROM node:20-alpine AS base
# Node.js base (without secrets)
FROM base AS deps
RUN --mount=type=cache,target=/root/.npm \
npm ci --ignore-scripts
# Build with secret
FROM deps AS build
RUN --mount=type=secret,id=npm_token,required=true \
--mount=type=secret,id=api_key,required=true \
--mount=type=cache,target=/root/.npm \
RUN_SCRIPT=$(cat /run/secrets/api_key) npm run build
required=true ทำให้ build ล้มเหลวถ้า secret ไม่ถูกส่งมา (safe by default: false)
5. SSH Mounts: Clone private repositories
SSH Mounts เป็นวิธีการส่ง SSH private keys ไปยัง build context อย่างปลอดภัย
ใช้ได้กับคำสั่งที่มี ssh ใน Dockerfile
Use Cases:
- Clone private Git repositories
ตัวอย่างการใช้งาน SSH Mounts
ตัวอย่าง: Clone private repository และ install dependencies
# syntax=docker/dockerfile:1
FROM node:20-alpine
# Install SSH client and Git
RUN apk add --no-cache openssh-client git
# Mount SSH key and create known_hosts
RUN --mount=type=ssh \
mkdir -p -m 600 ~/.ssh && \
ssh-keyscan github.com > ~/.ssh/known_hosts
# Clone private repository
RUN --mount=type=ssh \
git clone git@github.com:your-org/private-repo.git /app/repo
# Install dependencies
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["node", "dist/index.js"]
Build with SSH
# Build พร้อม SSH mount
$ docker build --ssh default=$HOME/.ssh/id_rsa -t myapp:latest .
อธิบาย:
default=$HOME/.ssh/id_rsa: ใช้ private key ที่ระบุโดย alias "default"--mount=type=ssh: ใช้ default SSH keygit@github.com:...: Git จะใช้ SSH key ที่ mount เข้ามา
SSH Mounts หลายอัน
# Build พร้อม SSH keys หลายอัน
$ docker build \
--ssh github=$HOME/.ssh/id_rsa_github \
--ssh gitlab=$HOME/.ssh/id_rsa_gitlab \
-t myapp:latest .
ใน Dockerfile จะใช้งานด้วย:
RUN --mount=type=ssh,id=github git clone git@github.com:org/repo.git
RUN --mount=type=ssh,id=gitlab git clone git@gitlab.com:org/repo.git
6. Multi-stage Build Optimization: ลดขนาด image
Multi-stage builds ช่วยให้เราสร้าง final image ที่ nhกว่าและปลอดภัยกว่าด้วยการแยก build process ออกจาก runtime
ข้อดีของ Multi-stage Builds
- Smaller final image: ไม่มี build dependencies
- Security: ไม่มี compilers หรือ tools ที่ไม่จำเป็น
- Layer reuse: Docker จะ cache แต่ละ stage
- Clean separation: Build vs Runtime context แยกกันชัดเจน
Multi-stage Build Flow / โครงสร้างระบบ
ตัวอย่าง Multi-stage Builds
Node.js Example
#syntax=docker/dockerfile:1
FROM node:20-alpine AS base
RUN apk add --no-cache curl
WORKDIR /app
# Install dependencies
FROM base AS deps
RUN apk add --no-cache python3 make g++
COPY package*.json ./
RUN npm ci
# Build
FROM deps AS build
COPY . .
RUN npm run build
# Production
FROM base AS production
COPY --from=deps /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
EXPOSE 3000
CMD ["node", "dist/index.js"]
Go Example
#syntax=docker/dockerfile:1
FROM golang:1.21-alpine AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest AS runtime
RUN apk --no-cache add ca-certificates
WORKDIR /app
COPY --from=builder /src/app .
EXPOSE 8080
CMD ["./app"]
Python Example
#syntax=docker/dockerfile:1
FROM python:3.11-slim AS builder
WORKDIR /build
COPY requirements.txt .
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
RUN pip install --no-cache-dir -r requirements.txt
FROM python:3.11-slim AS runtime
WORKDIR /app
COPY --from=builder /opt/venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0"]
Build Specific Stage
# Build และหยุดที่ stage ที่ระบุ (ไม่รวม stage ถัดไป)
$ docker build --target build -t myapp:build .
# Build stage เฉพาะ
$ docker build --target deps -t myapp:deps .
# Build production stage
$ docker build --target production -t myapp:latest .
--target เหมาะสำหรับ:
- Debug build issues
- Fast iteration ระหว่าง development
- Build images สำหรับ CI/CD pipelines
7. BuildKit Features Deep Dive: Advanced Options
BuildKit มีฟีเจอร์ขั้นสูงที่ช่วยให้เราควบคุม build process ได้มากขึ้น
Build Arguments (BUILDKIT_INLINE_CACHE, etc.)
# Build พร้อม build args และ inline cache
$ docker build \
--build-arg BUILDKIT_INLINE_CACHE=1 \
--build-arg NODE_ENV=production \
-t myapp:latest .
BUILDKIT_INLINE_CACHE=1 จะ embed cache metadata ลงใน image ทำให้สามารถใช้ --cache-from ได้โดยไม่ต้อง pull image ทั้งหมด
Progress Output Options
# Normal output
$ docker build -t myapp:latest .
# Plain output (machine-readable)
$ docker build --progress=plain -t myapp:latest .
# Quiet output
$ docker build --quiet -t myapp:latest .
--progress=plain แสดง build process แบบ detailed และ machine-readable เหมาะสำหรับ CI/CD
Build Context Options
# Build จาก remote git repository
$ docker build github.com/user/repo -t myapp:latest
# Build จาก tarball
$ tar -czf context.tar.gz . && docker build - < context.tar.gz -t myapp:latest
# Build จาก stdin (ดีสำหรับ docker run)
$ docker build -t myapp:latest < Dockerfile
# Build จาก remote Dockerfile
$ docker build https://github.com/user/repo.git#main -t myapp:latest
Build Cache Export
# Export cache ไปยัง local directory
$ docker build \
--cache-to type=local,dest=/path/to/cache \
-t myapp:latest .
# Import cache จาก local directory
$ docker build \
--cache-from type=local,src=/path/to/cache \
-t myapp:latest .
# Export cache ไปยัง registry (แบบ tarball)
$ docker build \
--cache-to type=registry,ref=myregistry.com/cache:latest,mode=max \
--cache-from type=registry,ref=myregistry.com/cache:latest \
-t myapp:latest .
type=local |
เก็บ cache ใน local filesystem |
type=registry |
เก็บ cache ใน container registry |
type=inline |
embed cache metadata ลงใน image (default) |
mode=min|max |
min: เก็บ cache ที่ใช้, max: เก็บ cache ทั้งหมด |
Concurrency Control
# Control concurrency
$ DOCKER_BUILDKIT=1 \
BUILDKIT_CONCURRENT_DOWNLOADS=10 \
BUILDKIT_CONCURRENT_UPLOADS=5 \
docker build -t myapp:latest .
Variants:
BUILDKIT_CONCURRENT_DOWNLOADSBUILDKIT_CONCURRENT_UPLOADSBUILDKIT_RAPID_CACHE
8. ตัวอย่างการใช้งานจริง (Practical Examples)
ในส่วนนี้จะรวมตัวอย่าง complete Dockerfiles ที่ใช้ BuildKit advanced features พร้อมคำอธิบาย
ตัวอย่าง 1: Node.js with Optimized Cache
Build optimized Docker image สำหรับ Node.js application ที่มี large dependencies
# syntax=docker/dockerfile:1
FROM node:20-alpine AS base
RUN apk add --no-cache curl
WORKDIR /app
# Install dependencies stage (cached if package.json unchanged)
FROM base AS deps
RUN --mount=type=cache,target=/root/.npm \
npm ci --ignore-scripts
RUN npm cache clean --force
# Build stage (cached if source unchanged)
FROM deps AS build
COPY . .
RUN --mount=type=cache,target=/root/.npm \
npm run build
# Production stage (smallest, most secure)
FROM base AS production
COPY --from=deps /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
COPY --from=build /app/package*.json ./
EXPOSE 3000
CMD ["node", "dist/index.js"]
ตัวอย่าง 2: Go with Multi-platform Builds
Buildmulti-platform Go binary และสร้าง image สำหรับ production
# syntax=docker/dockerfile:1
FROM --platform=$BUILDPLATFORM golang:1.21-alpine AS builder
WORKDIR /src
# Download dependencies
COPY go.mod go.sum ./
RUN go mod download
# Build the binary
COPY . .
RUN --mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg/mod \
CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH \
go build -a -installsuffix cgo -o /bin/app .
FROM alpine:latest AS runtime
RUN apk --no-cache add ca-certificates
WORKDIR /app
COPY --from=builder /bin/app .
EXPOSE 8080
CMD ["./app"]
ตัวอย่าง 3: Python with Virtualenv
Build optimized Python Docker image ด้วย virtualenv เพื่อ save space
# syntax=docker/dockerfile:1
FROM python:3.11-slim AS builder
WORKDIR /build
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
FROM python:3.11-slim AS runtime
WORKDIR /app
COPY --from=builder /opt/venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0"]
ตัวอย่าง 4: CI/CD with Registry Cache
Complete CI/CD workflow พร้อม registry cache sharing
# 1. Build และ save cache ไป registry
$ docker build \
--cache-to type=registry,ref=myregistry.com/myapp:buildcache,mode=max \
-t myregistry.com/myapp:build-$CI_COMMIT_SHA .
# 2. Push image
$ docker push myregistry.com/myapp:build-$CI_COMMIT_SHA
# 3. On next build, use cached cache
$ docker build \
--cache-from type=registry,ref=myregistry.com/myapp:buildcache \
-t myregistry.com/myapp:latest .
# 4. หรือใช้ buildx สำหรับ multi-platform
$ docker buildx build \
--cache-to type=registry,ref=myregistry.com/myapp:cache,mode=max \
--cache-from type=registry,ref=myregistry.com/myapp:cache \
--platform linux/amd64,linux/arm64 \
-t myregistry.com/myapp:latest \
--push .
ตัวอย่าง 5: Secret + SSH for Private Repos
Build application ที่ clone private repository และใช้ private npm packages
# syntax=docker/dockerfile:1
FROM node:20-alpine AS base
RUN apk add --no-cache git openssh-client
WORKDIR /app
# Install dependencies with private repos
FROM base AS deps
RUN --mount=type=ssh \
mkdir -p -m 600 ~/.ssh && \
ssh-keyscan github.com > ~/.ssh/known_hosts
RUN --mount=type=secret,id=npm_token \
echo "//registry.npmjs.org/:_authToken=\$(cat /run/secrets/npm_token)" > /root/.npmrc
RUN --mount=type=cache,target=/root/.npm \
npm ci
# Pull private repository
FROM base AS repo
RUN --mount=type=ssh \
mkdir -p /root/.ssh && \
ssh-keyscan github.com > /dev/null
RUN --mount=type=ssh \
git clone git@github.com:your-org/private-repo.git /private
# Build
FROM deps AS build
COPY --from=repo /private ./private
COPY . .
RUN --mount=type=cache,target=/root/.npm \
npm run build
# Production
FROM base AS production
COPY --from=deps /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
COPY --from=build /app/package*.json ./
EXPOSE 3000
CMD ["node", "dist/index.js"]
Build ด้วย:
docker build --ssh default=~/.ssh/id_rsa --secret id=npm_token,src=.secrets/npm_token -t myapp:latest .
9. แก้ไขปัญหาที่พบบ่อย (Troubleshooting)
ปัญหาที่ 1: "invalid cache mount"
Symptom: ERROR: invalid cache mount
Solution: ตรวจสอบว่า Docker version รองรับ BuildKit cache mounts (v23.04+)
# ตรวจสอบ version
$ docker version
Client: Docker Engine - Community
Version: 24.0.5
# ถ้าเก่ากว่านี้ ให้อัปเดต
# Linux:
$ apt-get update && apt-get upgrade docker-ce docker-ce-cli
# หรือ
$ yum update docker-ce docker-ce-cli
ปัญหาที่ 2: "failed to solve: secrets not allowed"
Symptom: failed to solve: secrets not allowed
Solution: ตรวจสอบว่าใช้ build command ที่ถูกต้อง และมี --secret flag
# ❌ ผิด
$ docker build -t myapp:latest .
# ✅ ถูก
$ docker build --secret id=npm_token,src=.secrets/npm_token -t myapp:latest .
ปัญหาที่ 3: "ssh: github.com: No such file or directory"
Symptom: SSH key authentication failed
Solution: ต้อง add SSH keys ไปยัง known_hosts ก่อนใช้งาน
# ✅ ถูกต้อง
RUN --mount=type=ssh \
mkdir -p -m 600 ~/.ssh && \
ssh-keyscan github.com > ~/.ssh/known_hosts
# ❌ ผิด (ไม่มี known_hosts)
RUN --mount=type=ssh git clone git@github.com:org/repo.git
ปัญหาที่ 4: Build Cache ใช้ไม่ได้
Symptom: Cache ไม่ถูกใช้ หรือ rebuild เสมอ
Solution: ตรวจสอบ cache mode และ mount path
# ❌ ผิด (path ไม่ตรง)
RUN --mount=type=cache,target=/tmp/npm_cache npm install
# ✅ ถูก (path ตรงกับ npm cache location)
RUN --mount=type=cache,target=/root/.npm npm install
# หรือ
RUN --mount=type=cache,target=/root/.npm,mode=0777 npm install
วิธี Debug Build
# ดู detailed output
$ docker build --progress=plain -t myapp:latest .
# Build พร้อม debug logs
$ DOCKER_BUILDKIT=1 \
BUILDKIT_DEBUG=true \
docker build -t myapp:latest .
# ดู build stats
$ docker build --export-cmd=stats -t myapp:latest .
คำถามที่พบบ่อย (FAQ)
BuildKit ใช้กับ Docker Desktop ได้ไหม?
ได้เลย! Docker Desktop ใช้ BuildKit เป็น default builder ตั้งแต่เวอร์ชัน 4.0+
BuildKit ยังใช้ Dockerfile เดิมได้ไหม?
ได้เลย! BuildKit รองรับ Dockerfile syntax เดิม 100% เพียงแต่เพิ่มฟีเจอร์ใหม่เข้าไป
Cache mounts กับ layer caching ต่างกันยัง?
Layer caching เป็นของ Docker engine เดิม ใช้ cache แต่ละ layer แต่ BuildKit cache mounts สามารถ cache ทั้ง directory และแชร์ระหว่าง builds ได้
BuildKit เร็วกว่ากี่เท่า?
ขึ้นกับ project: โดยทั่วไปจะเร็วกว่า 2-5 เท่า, บาง project ถึง 10 เท่า (ถ้ามี cache ที่ดี)
10. สรุปและขั้นตอนถัดไป (Summary)
สิ่งที่เรียนรู้ในบทความนี้
-
Cache Mounts: ใช้ --mount=type=cache เพื่อ cache ข้อมูลระหว่าง build และแชร์ cache ได้ระหว่างเครื่อง
-
Secret Mounts: ส่ง secrets อย่างปลอดภัยด้วย tmpfs ไม่เก็บใน image layers
-
SSH Mounts: ใช้ SSH keys สำหรับ clone private repos และ install private packages
-
Multi-stage Builds: สร้าง final image ที่ nhกว่าและปลอดภัยกว่า
ขั้นตอนถัดไป (Next Steps)
เรียนรู้เพิ่มเติม
ทดลองใช้งาน
- สร้าง Dockerfile ใหม่ที่ใช้ cache mounts
- ทดลอง secret mounts กับ API keys
- Optimize multi-stage build ให้เล็กที่สุด
สรุป
Docker BuildKit Advanced Features ช่วยให้เรา build container images ได้เร็วขึ้น ปลอดภัยกว่า และยืดหยุ่นมากขึ้น โดยเฉพาะ cache mounts, secret mounts และ SSH mounts ที่จำเป็นสำหรับ production environments