Docker_ci_cd
Chapter 15: Docker in CI/CD - Building, Testing, and Deploying Containers
Section titled “Chapter 15: Docker in CI/CD - Building, Testing, and Deploying Containers”Table of Contents
Section titled “Table of Contents”- Introduction to CI/CD with Docker
- Why Use Docker in CI/CD
- CI/CD Pipeline Overview
- Building Docker Images in CI/CD
- Testing Containers
- Docker Registry Integration
- Image Tagging Strategies
- Deployment Strategies
- Security Scanning in CI/CD
- GitOps with Docker
- Hands-on Lab
- Summary
Introduction to CI/CD with Docker
Section titled “Introduction to CI/CD with Docker”What is CI/CD?
Section titled “What is CI/CD?”Continuous Integration and Continuous Deployment (CI/CD) is a methodology that automates the building, testing, and deployment of applications. Docker plays a crucial role in modern CI/CD pipelines.
┌─────────────────────────────────────────────────────────────────────────────┐│ CI/CD PIPELINE OVERVIEW │├─────────────────────────────────────────────────────────────────────────────┤│ ││ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ││ │ Code │───▶│ Build │───▶│ Test │───▶│ Deploy │ ││ │ Commit │ │ │ │ │ │ │ ││ └──────────┘ └──────────┘ └──────────┘ └──────────┘ ││ ││ CI (Continuous Integration): ││ ─────────────────────────── ││ • Automated builds on code commit ││ • Automated testing ││ • Code quality checks ││ ││ CD (Continuous Delivery/Deployment): ││ ─────────────────────────────────── ││ • Automated deployment to staging ││ • Automated deployment to production ││ • Rollback capabilities ││ ││ Where Docker Fits: ││ ────────────────── ││ • Build: Package application in containers ││ • Test: Run tests in isolated containers ││ • Deploy: Deploy containerized applications ││ │└─────────────────────────────────────────────────────────────────────────────┘Docker’s Role in CI/CD
Section titled “Docker’s Role in CI/CD”┌─────────────────────────────────────────────────────────────────────────────┐│ DOCKER IN CI/CD │├─────────────────────────────────────────────────────────────────────────────┤│ ││ ┌─────────────────────────────────────────────────────────────────────┐ ││ │ CI/CD Pipeline with Docker │ ││ │ │ ││ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ ││ │ │ Code │ │ Build │ │ Test │ │ Stage │ │ Deploy │ │ ││ │ │ Commit │ │ Image │ │ │ │ Image │ │ to Prod │ │ ││ │ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │ ││ │ │ │ │ │ │ │ ││ │ ▼ ▼ ▼ ▼ ▼ │ ││ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ ││ │ │ GitHub │ │ Docker │ │ Container│ │Registry │ │ K8s/ │ │ ││ │ │Actions │ │ Build │ │ Testing │ │ (ECR, │ │ Docker │ │ ││ │ │Jenkins │ │ │ │ │ │DockerHub)│ │ Swarm │ │ ││ │ │GitLab CI│ │ │ │ │ │ │ │ │ │ ││ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ ││ │ │ ││ │ Benefits: │ ││ │ • Consistent build environment │ ││ │ • Isolated testing │ ││ │ • Same artifacts from dev to production │ ││ │ • Fast rollbacks │ ││ │ │ ││ └─────────────────────────────────────────────────────────────────────┘ ││ │└─────────────────────────────────────────────────────────────────────────────┘Why Use Docker in CI/CD
Section titled “Why Use Docker in CI/CD”Benefits
Section titled “Benefits”┌─────────────────────────────────────────────────────────────────────────────┐│ BENEFITS OF DOCKER IN CI/CD │├─────────────────────────────────────────────────────────────────────────────┤│ ││ 1. CONSISTENCY ││ ────────────── ││ • Same environment from local dev to production ││ • Eliminates "works on my machine" issues ││ • Reproducible builds ││ ││ 2. ISOLATION ││ ────────── ││ • Tests run in clean containers ││ • No dependency conflicts ││ • Parallel test execution ││ ││ 3. SPEED ││ ────── ││ • Faster provisioning of test environments ││ • Cached layers speed up builds ││ • Parallel execution ││ ││ 4. SCALABILITY ││ ─────────── ││ • Easy to scale up test runners ││ • Container-based parallelization ││ • Resource isolation ││ ││ 5. PORTABILITY ││ ─────────── ││ • Works on any CI/CD platform ││ • Cloud-agnostic ││ • Same workflow everywhere ││ ││ 6. REPRODUCIBILITY ││ ───────────────── ││ • Exact same artifacts ││ • Version-controlled infrastructure ││ • Audit trails ││ │└─────────────────────────────────────────────────────────────────────────────┘CI/CD Pipeline Overview
Section titled “CI/CD Pipeline Overview”Pipeline Stages
Section titled “Pipeline Stages”┌─────────────────────────────────────────────────────────────────────────────┐│ COMPLETE CI/CD PIPELINE │├─────────────────────────────────────────────────────────────────────────────┤│ ││ ┌───────────────────────────────────────────────────────────────────┐ ││ │ │ ││ │ STAGE 1: SOURCE │ ││ │ ───────────────── │ ││ │ • Code checkout │ ││ │ • Dependency resolution │ ││ │ • Secret injection │ ││ │ │ ││ │ ┌───────────────────────────────────────────────────────────┐ │ ││ │ │ STAGE 2: BUILD │ │ ││ │ │ ─────────────── │ │ ││ │ │ • Build application code │ │ ││ │ │ • Build Docker image │ │ ││ │ │ • Run linters │ │ ││ │ │ • Security scan │ │ ││ │ │ • Push to registry │ │ ││ │ └───────────────────────────────────────────────────────────┘ │ ││ │ │ ││ │ ┌───────────────────────────────────────────────────────────┐ │ ││ │ │ STAGE 3: TEST │ │ ││ │ │ ─────────────── │ │ ││ │ │ • Unit tests │ │ ││ │ │ • Integration tests │ │ ││ │ │ • End-to-end tests │ │ ││ │ │ • Performance tests │ │ ││ │ │ • Security tests │ │ ││ │ └───────────────────────────────────────────────────────────┘ │ ││ │ │ ││ │ ┌───────────────────────────────────────────────────────────┐ │ ││ │ │ STAGE 4: DEPLOY │ │ ││ │ │ ─────────────── │ │ ││ │ │ • Deploy to staging │ │ ││ │ │ • Integration tests │ │ ││ │ │ • Deploy to production │ │ ││ │ │ • Health checks │ │ ││ │ │ • Smoke tests │ │ ││ │ └───────────────────────────────────────────────────────────┘ │ ││ │ │ ││ └───────────────────────────────────────────────────────────────────┘ ││ │└─────────────────────────────────────────────────────────────────────────────┘Building Docker Images in CI/CD
Section titled “Building Docker Images in CI/CD”Basic Docker Build
Section titled “Basic Docker Build”# Simple builddocker build -t myapp:latest .
# Build with specific Dockerfiledocker build -f Dockerfile.prod -t myapp:latest .
# Build with build argumentsdocker build --build-arg VERSION=1.0.0 -t myapp:latest .
# Build with labelsdocker build --label version=1.0.0 --label environment=ci -t myapp:latest .Multi-Stage Builds
Section titled “Multi-Stage Builds”# Dockerfile - Multi-stage build# Build stageFROM node:18-alpine AS builderWORKDIR /appCOPY package*.json ./RUN npm ci --only=productionCOPY . .RUN npm run build
# Production stageFROM node:18-alpine AS productionWORKDIR /appCOPY --from=builder /app/dist ./distCOPY --from=builder /app/node_modules ./node_modulesCOPY package*.json ./USER nodeEXPOSE 3000CMD ["node", "dist/main.js"]CI/CD Build Examples
Section titled “CI/CD Build Examples”GitHub Actions
Section titled “GitHub Actions”name: Build and Push Docker Image
on: push: branches: [main] pull_request: branches: [main]
jobs: build: runs-on: ubuntu-latest
steps: - name: Checkout code uses: actions/checkout@v4
Set up Docker Buildx uses - name:: docker/setup-buildx-action@v3
- name: Login to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract metadata id: meta uses: docker/metadata-action@v5 with: images: myregistry/myapp tags: | type=ref,event=branch type=sha,prefix= type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push uses: docker/build-push-action@v5 with: context: . push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=maxGitLab CI
Section titled “GitLab CI”stages: - build - test - deploy
variables: IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
build: stage: build image: docker:24-dind services: - docker:24-dind script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker build -t $IMAGE_TAG . - docker push $IMAGE_TAG
test: stage: test image: $IMAGE_TAG script: - npm test - npm run test:integration
deploy: stage: deploy image: alpine:latest script: - apk add --no-cache curl - kubectl set image deployment/myapp myapp=$IMAGE_TAG only: - mainJenkins
Section titled “Jenkins”// Jenkinsfilepipeline { agent any
environment { REGISTRY = 'docker.io' IMAGE_NAME = 'myapp' }
stages { stage('Checkout') { steps { checkout scm } }
stage('Build') { steps { script { def tag = "${env.BUILD_NUMBER}" env.IMAGE_TAG = "${IMAGE_NAME}:${tag}" } sh "docker build -t ${env.IMAGE_TAG} ." } }
stage('Test') { steps { sh "docker run --rm ${env.IMAGE_TAG} npm test" } }
stage('Push') { steps { withCredentials([usernamePassword(credentialsId: 'docker-hub', usernameVariable: 'USER', passwordVariable: 'PASS')]) { sh """ docker login -u ${USER} -p ${PASS} ${REGISTRY} docker tag ${env.IMAGE_TAG} ${REGISTRY}/${IMAGE_NAME}:latest docker push ${REGISTRY}/${IMAGE_NAME}:latest """ } } }
stage('Deploy') { when { branch 'main' } steps { sh "kubectl set image deployment/myapp myapp=${env.IMAGE_TAG}" } } }}Testing Containers
Section titled “Testing Containers”Unit Tests in Containers
Section titled “Unit Tests in Containers”FROM node:18-alpineWORKDIR /appCOPY package*.json ./RUN npm ciCOPY . .CMD ["npm", "test", "--", "--coverage"]# Run tests in containerdocker run --rm myapp:test npm testIntegration Testing
Section titled “Integration Testing”version: '3.8'
services: app: build: . environment: - DB_HOST=db - DB_PORT=5432
db: image: postgres:15 environment: - POSTGRES_PASSWORD=test - POSTGRES_DB=test
test: build: . command: npm run test:integration depends_on: - app - dbEnd-to-End Testing
Section titled “End-to-End Testing”# Cypress configuration for container testing# cypress.config.jsconst { defineConfig } = require('cypress')
module.exports = defineConfig({ e2e: { baseUrl: 'http://web:80', video: false, screenshotOnRunFailure: true, supportFile: false, },})version: '3.8'
services: web: build: . ports: - "3000:3000"
cypress: image: cypress/included:12.0.0 working_dir: /e2e volumes: - ./e2e:/e2e depends_on: - web command: --config-file cypress.config.jsDocker Registry Integration
Section titled “Docker Registry Integration”Popular Docker Registries
Section titled “Popular Docker Registries”┌─────────────────────────────────────────────────────────────────────────────┐│ DOCKER REGISTRY OPTIONS │├─────────────────────────────────────────────────────────────────────────────┤│ ││ Public Registries ││ ─────────────── ││ ┌────────────────┐ ┌────────────────┐ ││ │ Docker Hub │ │ GitHub │ ││ │ Official │ │ Packages │ ││ │ Images │ │ │ ││ └────────────────┘ └────────────────┘ ││ ││ Private/Cloud Registries ││ ────────────────────── ││ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ ││ │ AWS ECR │ │ Azure ACR │ │ GCP GCR │ ││ │ │ │ │ │ │ ││ │ Pay per use │ │ Pay per use │ │ Pay per use │ ││ │ IAM control │ │ RBAC │ │ IAM control │ ││ └────────────────┘ └────────────────┘ └────────────────┘ ││ ││ Self-Hosted ││ ─────────── ││ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ ││ │ Harbor │ │ GitLab │ │ Distribution │ ││ │ Enterprise │ │ Registry │ │ (OSS) │ ││ │ │ │ │ │ │ ││ └────────────────┘ └────────────────┘ └────────────────┘ ││ │└─────────────────────────────────────────────────────────────────────────────┘Pushing to Registry
Section titled “Pushing to Registry”# Login to registrydocker login myregistry.io# Or using credentialsdocker login -u USER -p PASS myregistry.io
# Tag image for registrydocker tag myapp:latest myregistry.io/myapp:latest
# Push imagedocker push myregistry.io/myapp:latest
# Pull imagedocker pull myregistry.io/myapp:latestAWS ECR Example
Section titled “AWS ECR Example”# Get ECR login passwordaws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin account.dkr.ecr.us-east-1.amazonaws.com
# Build and tagdocker build -t myapp .docker tag myapp:latest account.dkr.ecr.us-east-1.amazonaws.com/myapp:latest
# Pushdocker push account.dkr.ecr.us-east-1.amazonaws.com/myapp:latestImage Tagging Strategies
Section titled “Image Tagging Strategies”Tagging Strategies
Section titled “Tagging Strategies”┌─────────────────────────────────────────────────────────────────────────────┐│ IMAGE TAGGING STRATEGIES │├─────────────────────────────────────────────────────────────────────────────┤│ ││ 1. Semantic Versioning (SemVer) ││ ───────────────────────────────────── ││ myapp:1.0.0 - Major version ││ myapp:1.0.1 - Patch version ││ myapp:1.1.0 - Minor version ││ ││ 2. Git-based Tagging ││ ───────────────────── ││ myapp:abc123 - First 7 characters of commit SHA ││ myapp:sha-abc123 - Full SHA ││ myapp:branch-main - Branch name ││ ││ 3. Dynamic Tags ││ ──────────────── ││ myapp:latest - Latest stable build ││ myapp:stable - Stable release ││ myapp:develop - Development branch ││ ││ 4. Date-based Tags ││ ───────────────── ││ myapp:2024.01.15 - Date of build ││ myapp:2024-01-15 - ISO date ││ ││ Recommended Strategy: ││ ─────────────────── ││ Always tag with: ││ • SHA (myapp:sha-abc123) - Immutable, traceable ││ • SemVer (myapp:1.2.3) - Human readable ││ • Latest (myapp:latest) - Convenience (not for production) ││ │└─────────────────────────────────────────────────────────────────────────────┘CI/CD Tagging Examples
Section titled “CI/CD Tagging Examples”# Tag with git SHAIMAGE_TAG=$(git rev-parse --short HEAD)docker build -t myapp:${IMAGE_TAG} .
# Tag with branch nameBRANCH_NAME=${CI_COMMIT_BRANCH:-$(git branch --show-current)}docker build -t myapp:${BRANCH_NAME} .
# Tag with semver (from git tag)VERSION=$(git describe --tags --abbrev=0)docker build -t myapp:${VERSION} .
# Multiple tagsdocker build -t myapp:latest -t myapp:${VERSION} -t myapp:${SHA} .Deployment Strategies
Section titled “Deployment Strategies”Blue-Green Deployment
Section titled “Blue-Green Deployment”┌─────────────────────────────────────────────────────────────────────────────┐│ BLUE-GREEN DEPLOYMENT │├─────────────────────────────────────────────────────────────────────────────┤│ ││ Before Switch: ││ ┌─────────────────────────────────────────────────────────────────────┐ ││ │ │ ││ │ ┌─────────────────┐ ┌─────────────────┐ │ ││ │ │ BLUE (v1.0) │ │ GREEN (v2.0) │ │ ││ │ │ │ │ │ │ ││ │ │ Active ◄──────┼────────┼── Inactive │ │ ││ │ │ │ │ │ │ ││ │ └─────────────────┘ └─────────────────┘ │ ││ │ │ ││ │ Load Balancer: 100% traffic → Blue │ ││ └─────────────────────────────────────────────────────────────────────┘ ││ ││ After Switch: ││ ┌─────────────────────────────────────────────────────────────────────┐ ││ │ │ ││ │ ┌─────────────────┐ ┌─────────────────┐ │ ││ │ │ BLUE (v1.0) │ │ GREEN (v2.0) │ │ ││ │ │ │ │ │ │ ││ │ │ Inactive │◄───────┼── Active ► │ │ ││ │ │ │ │ │ │ ││ │ └─────────────────┘ └─────────────────┘ │ ││ │ │ ││ │ Load Balancer: 100% traffic → Green │ ││ └─────────────────────────────────────────────────────────────────────┘ ││ ││ Rollback: Switch traffic back to Blue ││ │└─────────────────────────────────────────────────────────────────────────────┘Canary Deployment
Section titled “Canary Deployment”┌─────────────────────────────────────────────────────────────────────────────┐│ CANARY DEPLOYMENT │├─────────────────────────────────────────────────────────────────────────────┤│ ││ Phase 1: 10% Traffic ││ ┌─────────────────────────────────────────────────────────────────────┐ ││ │ │ ││ │ v1.0 (90%) │██│██│██│██│██│██│██│██│██│ │ │ ││ │ v2.0 (10%) │█│ │ │ ││ │ │ ││ └─────────────────────────────────────────────────────────────────────┘ ││ ││ Phase 2: 50% Traffic ││ ┌─────────────────────────────────────────────────────────────────────┐ ││ │ │ ││ │ v1.0 (50%) │██│██│██│██│ │ │ ││ │ v2.0 (50%) │██│██│██│██│ │ │ ││ │ │ ││ └─────────────────────────────────────────────────────────────────────┘ ││ ││ Phase 3: 100% Traffic ││ ┌─────────────────────────────────────────────────────────────────────┐ ││ │ │ ││ │ v2.0 (100%) │██│██│██│██│██│██│██│██│██│ │ │ ││ │ │ ││ └─────────────────────────────────────────────────────────────────────┘ ││ ││ Benefits: ││ • Test with real traffic ││ • Easy rollback ││ • Gradual rollout ││ │└─────────────────────────────────────────────────────────────────────────────┘Rolling Deployment
Section titled “Rolling Deployment”┌─────────────────────────────────────────────────────────────────────────────┐│ ROLLING DEPLOYMENT │├─────────────────────────────────────────────────────────────────────────────┤│ ││ Initial: 3 replicas v1.0 ││ ┌─────────┐ ┌─────────┐ ┌─────────┐ ││ │ v1.0 ✓ │ │ v1.0 ✓ │ │ v1.0 ✓ │ ││ └─────────┘ └─────────┘ └─────────┘ ││ ││ Step 1: Replace 1st replica ││ ┌─────────┐ ┌─────────┐ ┌─────────┐ ││ │ v2.0 ⏳ │ │ v1.0 ✓ │ │ v1.0 ✓ │ ││ └─────────┘ └─────────┘ └─────────┘ ││ ││ Step 2: Replace 2nd replica ││ ┌─────────┐ ┌─────────┐ ┌─────────┐ ││ │ v2.0 ✓ │ │ v2.0 ⏳ │ │ v1.0 ✓ │ ││ └─────────┘ └─────────┘ └─────────┘ ││ ││ Step 3: Replace 3rd replica ││ ┌─────────┐ ┌─────────┐ ┌─────────┐ ││ │ v2.0 ✓ │ │ v2.0 ✓ │ │ v2.0 ⏳ │ ││ └─────────┘ └─────────┘ └─────────┘ ││ ││ Complete: All replicas v2.0 ││ ┌─────────┐ ┌─────────┐ ┌─────────┐ ││ │ v2.0 ✓ │ │ v2.0 ✓ │ │ v2.0 ✓ │ ││ └─────────┘ └─────────┘ └─────────┘ ││ │└─────────────────────────────────────────────────────────────────────────────┘Security Scanning in CI/CD
Section titled “Security Scanning in CI/CD”Integrating Security Scanning
Section titled “Integrating Security Scanning”# GitHub Actions with security scanningname: Security Scan
on: [push, pull_request]
jobs: scan: runs-on: ubuntu-latest
steps: - uses: actions/checkout@v4
# Build image - name: Build run: docker build -t myapp:test .
# Run Trivy scanner - name: Run Trivy uses: aquasecurity/trivy-action@master with: scan-type: 'fs' scan-ref: '.' format: 'sarif' output: 'trivy-results.sarif'
# Upload results - name: Upload results uses: github/codeql-action/upload-sarif@v2 with: sarif_file: 'trivy-results.sarif'
# Fail on critical vulnerabilities - name: Check for critical vulnerabilities run: | docker run --rm -v $(pwd):/workspace aquasecurity/trivy:0.44.0 \ image --exit-code 1 --severity CRITICAL myapp:test || \ (echo "Critical vulnerabilities found!" && exit 1)Docker Scout
Section titled “Docker Scout”# Enable Docker Scoutdocker scout cves myapp:latest
# In CI/CDdocker build -t myapp:latest .docker scout cves --exit-code --policy /policy.yaml myapp:latestGitOps with Docker
Section titled “GitOps with Docker”What is GitOps?
Section titled “What is GitOps?”┌─────────────────────────────────────────────────────────────────────────────┐│ GITOPS WORKFLOW │├─────────────────────────────────────────────────────────────────────────────┤│ ││ Traditional CI/CD: GitOps: ││ ─────────────────── ───────: ││ ││ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ││ │ Code │───▶│ Build │───▶ │ Code │───▶│ Sync │ ││ │ Commit │ │ & Deploy │ │ Commit │ │ State │ ││ └──────────┘ └──────────┘ └────┬─────┘ └────┬─────┘ ││ │ │ ││ ▼ ▼ ││ ┌──────────────┐ ┌──────────────┐ ││ │ Git │ │ Cluster │ ││ │ Repo │ │ State │ ││ │ (Desired) │ │ (Actual) │ ││ └──────────────┘ └──────────────┘ ││ ││ Key Principles: ││ • Git as single source of truth ││ • Declarative infrastructure ││ • Automated synchronization ││ • Drift detection ││ │└─────────────────────────────────────────────────────────────────────────────┘ArgoCD Example
Section titled “ArgoCD Example”apiVersion: argoproj.io/v1alpha1kind: Applicationmetadata: name: myapp namespace: argocdspec: project: default source: repoURL: https://github.com/myorg/myapp.git targetRevision: main path: k8s/overlays/production destination: server: https://kubernetes.default.svc namespace: production syncPolicy: automated: prune: true selfHeal: trueHands-on Lab
Section titled “Hands-on Lab”Lab: Complete CI/CD Pipeline
Section titled “Lab: Complete CI/CD Pipeline”In this hands-on lab, we’ll build a complete CI/CD pipeline with Docker.
Prerequisites
Section titled “Prerequisites”- Docker installed
- GitHub account (or use GitLab/Jenkins)
Lab Steps
Section titled “Lab Steps”# Step 1: Create a simple Node.js applicationmkdir myapp && cd myappnpm init -ynpm install express
# Step 2: Create the applicationcat > index.js << 'EOF'const express = require('express');const app = express();const port = process.env.PORT || 3000;
app.get('/', (req, res) => { res.json({ message: 'Hello from Docker CI/CD!', version: process.env.VERSION || 'dev' });});
app.listen(port, () => { console.log(`App listening on port ${port}`);});EOF
# Step 3: Create Dockerfilecat > Dockerfile << 'EOF'FROM node:18-alpineWORKDIR /appCOPY package*.json ./RUN npm ci --only=productionCOPY . .EXPOSE 3000CMD ["node", "index.js"]EOF
# Step 4: Create package.jsoncat > package.json << 'EOF'{ "name": "myapp", "version": "1.0.0", "main": "index.js", "scripts": { "start": "node index.js", "test": "echo \"No tests specified\"" }, "dependencies": { "express": "^4.18.2" }}EOF
# Step 5: Create GitHub Actions workflowmkdir -p .github/workflowscat > .github/workflows/docker.yml << 'EOF'name: Docker Build and Push
on: push: branches: [main] pull_request: branches: [main]
jobs: build: runs-on: ubuntu-latest
steps: - uses: actions/checkout@v4
- name: Set up Docker Buildx uses: docker/setup-buildx-action@v3
- name: Build run: docker build -t myapp:test .
- name: Test run: docker run --rm myapp:test node -e "console.log('Container works!')"
- name: Login to Docker Hub if: github.event_name != 'pull_request' uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract metadata id: meta if: github.event_name != 'pull_request' uses: docker/metadata-action@v5 with: images: ${{ secrets.DOCKER_USERNAME }}/myapp
- name: Push if: github.event_name != 'pull_request' uses: docker/build-push-action@v5 with: push: true tags: ${{ steps.meta.outputs.tags }}EOF
# Step 6: Commit and pushgit initgit add .git commit -m "Initial commit with Docker CI/CD"# git remote add origin <your-repo-url># git push -u origin main
# Step 7: Test locallydocker build -t myapp:local .docker run -p 3000:3000 myapp:local
# Step 8: Verify with curlcurl http://localhost:3000Summary
Section titled “Summary”Key Takeaways
Section titled “Key Takeaways”- CI/CD with Docker - Consistent builds, tests, and deployments
- Multi-stage Builds - Smaller, optimized images
- Security Scanning - Scan images in CI/CD pipeline
- Image Tagging - Use SHA-based tags for production
- Deployment Strategies - Blue-green, canary, rolling
- GitOps - Git as source of truth for deployments
Quick Reference
Section titled “Quick Reference”# Build imagedocker build -t myapp:latest .
# Tag for registrydocker tag myapp:latest registry.io/myapp:latest
# Push to registrydocker push registry.io/myapp:latest
# Pull in deploymentdocker pull registry.io/myapp:latest
# Security scantrivy image myapp:latestdocker scout cves myapp:latestNext Steps
Section titled “Next Steps”This concludes the Docker Advanced section. You now have comprehensive knowledge of:
- Docker Swarm (Chapter 11)
- Docker Security (Chapter 12)
- Docker Monitoring (Chapter 13)
- Docker Networking (Chapter 14)
- Docker CI/CD (Chapter 15)
Continue Learning
Section titled “Continue Learning”- Kubernetes Fundamentals (Chapter 16-25)
- Kubernetes Advanced (Chapter 26-32)
- Terraform & IaC (Chapter 33-40)
- Ansible (Chapter 41-45)
- CI/CD Tools (Chapter 46-50)