DevOps Skill
Overview
Skill สำหรับ containerization, orchestration, และ automation ของ software delivery
Docker
Dockerfile Best Practices
Multi-stage Build
dockerfile
# Stage 1: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: Production
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
# Non-root user for security
RUN addgroup -g 1001 -S nodejs && \
adduser -S nextjs -u 1001
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
USER nextjs
EXPOSE 3000
CMD ["npm", "start"]
Optimization Tips
dockerfile
# 1. Order layers by change frequency (least to most)
COPY package*.json ./
RUN npm ci
COPY . .
# 2. Use .dockerignore
# .dockerignore
node_modules
.git
*.md
.env*
# 3. Use specific base image versions
FROM node:20.10-alpine3.19
# 4. Combine RUN commands
RUN apt-get update && \
apt-get install -y --no-install-recommends curl && \
rm -rf /var/lib/apt/lists/*
Docker Compose
Development Environment
yaml
version: "3.8"
services:
app:
build:
context: .
dockerfile: Dockerfile.dev
ports:
- "3000:3000"
volumes:
- .:/app
- /app/node_modules
environment:
- NODE_ENV=development
- DATABASE_URL=postgresql://user:pass@db:5432/mydb
depends_on:
db:
condition: service_healthy
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: mydb
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d mydb"]
interval: 5s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
postgres_data:
Common Commands
bash
# Build and start docker compose up --build # Start in background docker compose up -d # View logs docker compose logs -f app # Execute command in container docker compose exec app sh # Stop and remove docker compose down # Remove with volumes docker compose down -v
Kubernetes
Core Concepts
Pod
yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp
labels:
app: myapp
spec:
containers:
- name: myapp
image: myregistry/myapp:1.0.0
ports:
- containerPort: 3000
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
Deployment
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myregistry/myapp:1.0.0
ports:
- containerPort: 3000
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: db-secret
key: url
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
Service
yaml
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
type: ClusterIP
selector:
app: myapp
ports:
- port: 80
targetPort: 3000
ConfigMap & Secret
yaml
# ConfigMap apiVersion: v1 kind: ConfigMap metadata: name: myapp-config data: LOG_LEVEL: "info" FEATURE_FLAG: "true" --- # Secret apiVersion: v1 kind: Secret metadata: name: db-secret type: Opaque stringData: url: postgresql://user:pass@db:5432/mydb
Ingress
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- myapp.example.com
secretName: myapp-tls
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp
port:
number: 80
Common Commands
bash
# Apply manifests kubectl apply -f deployment.yaml # Get resources kubectl get pods kubectl get deployments kubectl get services # Describe resource kubectl describe pod myapp-xxx # View logs kubectl logs -f myapp-xxx # Execute in pod kubectl exec -it myapp-xxx -- sh # Port forward kubectl port-forward svc/myapp 8080:80 # Scale deployment kubectl scale deployment myapp --replicas=5 # Rolling update kubectl set image deployment/myapp myapp=myregistry/myapp:2.0.0 # Rollback kubectl rollout undo deployment/myapp
CI/CD
GitHub Actions
yaml
name: CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Run linter
run: npm run lint
- name: Run tests
run: npm test -- --coverage
- name: Upload coverage
uses: codecov/codecov-action@v3
build:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Login to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
deploy:
needs: build
runs-on: ubuntu-latest
environment: production
steps:
- name: Deploy to Kubernetes
uses: azure/k8s-deploy@v4
with:
manifests: k8s/
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
Monitoring & Logging
Health Endpoints
javascript
// Express.js
app.get("/health", (req, res) => {
res.json({ status: "healthy" });
});
app.get("/ready", async (req, res) => {
try {
await db.query("SELECT 1");
res.json({ status: "ready" });
} catch (error) {
res.status(503).json({ status: "not ready", error: error.message });
}
});
Logging Best Practices
javascript
// Structured logging
const logger = {
info: (message, meta = {}) => {
console.log(
JSON.stringify({
level: "info",
message,
timestamp: new Date().toISOString(),
...meta,
}),
);
},
};
logger.info("User created", { userId: 123, action: "create" });
DevOps Checklist
- • Dockerfile optimized (multi-stage, small image)
- • docker-compose.yml for local development
- • Kubernetes manifests (Deployment, Service, Ingress)
- • ConfigMaps และ Secrets
- • Health และ Readiness probes
- • Resource limits configured
- • CI/CD pipeline setup
- • Monitoring และ logging
- • Backup strategy
- • Disaster recovery plan