DEV Community

Srinivasaraju Tangella
Srinivasaraju Tangella

Posted on

Cold vs Hot Deployment in CI/CD: From Traditional Web Apps to Kubernetes Microservices (Step-by-Step Guide)

📘 Page 1 — Introduction to Cold and Hot Deployment

What you will learn:

Difference between Cold and Hot deployment

How deployments differ in traditional monolithic apps vs microservices

Practical, step-by-step commands

🔹 Key Concepts

Cold Deployment → Stop application → Deploy → Start application.

Users experience downtime.

Hot Deployment → Deploy without stopping the service.

Minimal or zero downtime.

Notes:

Cold deployments are common in legacy systems.

Hot deployments are standard in modern CI/CD pipelines.

Understanding downtime, rollback, and risk is crucial for production environments.

📘 Page 2 — Cold Deployment in Traditional Web Applications

Scenario: Deploying a WAR file to Tomcat

Steps:

1.Stop Tomcat server:

sudo systemctl stop tomcat

2.Replace old WAR file:

cp /tmp/app.war /opt/tomcat/webapps/app.war

3.Start Tomcat:

sudo systemctl start tomcat

4.Verify health:

curl -f http://web1:8080/app/health || echo "Deployment failed"

Notes:

Users cannot access the app while Tomcat is down.

Downtime depends on app startup time.

Simple, but risky in production environments.

📘 Page 3 — Hot Deployment in Traditional Web Applications

Scenario: Using Tomcat Manager

Steps:

1.Upload new WAR without stopping server:

curl -u admin:password -T target/app.war \
"http://web1:8080/manager/text/deploy?path=/app&update=true"

2.Verify app is working:

curl -f http://web1:8080/app/health

Notes:

Server stays live → no downtime.

Risk: Classloader memory leaks or session loss may occur.

Alternative: Use Load Balancer rolling updates for safer hot deployment:

Remove one server from LB

Deploy update

Test and re-register with LB

📘 Page 4 — Cold Deployment in Microservices

Scenario: Docker Compose

Steps:

1.Stop services:

docker-compose -f docker-compose.prod.yml down

2.Pull new images:

docker-compose -f docker-compose.prod.yml pull

3.Start services:

docker-compose -f docker-compose.prod.yml up -d

4.Test endpoints:

curl -f http://microservice:8080/health

Notes:

All containers stop before new ones start → downtime occurs.

Works for small-scale deployments.

Not recommended for production microservices.

📘 Page 5 — Hot Deployment in Microservices

Scenario: Docker Swarm Rolling Update

Steps:

1.Build and push new Docker image:

docker build -t registry/myapp:v2 .
docker push registry/myapp:v2

2.Update service with rolling strategy:

docker service update --image registry/myapp:v2 \
--update-parallelism 1 --update-delay 10s myapp_service

3.Monitor update:

docker service ps myapp_service

Notes:

Tasks update one by one → service remains live.

Low downtime and safer for users.

This is Hot deployment in action for microservices.

📘 Page 6 — Hot Deployment in Kubernetes

Rolling Update (default in K8s)

Deployment YAML snippet:

strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1

Steps:

1.Build and push image:

docker build -t registry/myapp:2.0 .
docker push registry/myapp:2.0

2.Update deployment:

kubectl set image deployment/myapp myapp=registry/myapp:2.0 --record

3.Monitor rollout:

kubectl rollout status deployment/myapp
kubectl get pods -l app=myapp -w

Notes:

New pods must pass readiness probes before old pods terminate.

Ensures zero downtime.

Rollback is easy:

kubectl rollout undo deployment/myapp

📘 Page 7 — Blue-Green Deployment

Concept:

Run old (blue) and new (green) versions simultaneously.

Switch traffic instantly to green after validation.

Steps:

  1. Deploy green version (new image) with label version=green.

  2. Test green deployment:

kubectl port-forward deployment/myapp-green 8080:8080

  1. Switch Service selector to green:

kubectl patch svc myapp -p '{"spec":{"selector":{"version":"green"}}}'

  1. If issues → rollback to blue.

Notes:

Pros → Instant rollback, minimal user impact.

Cons → Requires double resources while both versions run.

📘 Page 8 — Canary Deployment

Concept:

Release new version to small % of users first.

Gradually increase traffic if no errors.

Steps (Nginx Ingress example):

annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10"

Monitor logs and metrics.

Adjust traffic percentage gradually.

Notes:

Very safe method for production-grade hot deployment.

Requires Ingress controller or service mesh (Istio, Linkerd, Argo Rollouts).

📘 Page 9 — Cold vs Hot Deployment Comparison

Downtime:

Cold → Yes

Hot → No / Minimal

Traditional Web:

Cold → Stop server → Replace artifact → Start server

Hot → Tomcat Manager / Load Balancer rolling update

Microservices:

Cold → Stop containers → Start new ones

Hot → Rolling / Blue-Green / Canary

Rollback:

Cold → Manual re-deploy old version

Hot → Easy rollback (undo rollout or switch traffic)

Risk:

Cold → High (downtime for users)

Hot → Low (tested, automated, zero downtime)

📘 Page 10 — Best Practices

Always use readiness/liveness probes.

Keep services stateless.

Use feature flags for toggling features without redeploying.

Follow expand-contract DB migration pattern.

Monitor deployment metrics → rollback if error threshold exceeded.

Run smoke tests before routing traffic.

Keep logs centralized for troubleshooting (ELK / EFK).

📘 Page 11 — Conclusion

Cold deployments → Simple, but downtime for users.

Hot deployments → Zero-downtime, safer for production.

Microservices + Kubernetes → rolling, blue-green, canary deployments are industry standard.

Real engineering is about deploying safely and reliably, not just fast.

💡 Tip: Combine CI/CD automation + proper deployment strategy + monitoring to achieve zero-downtime production

📘 Page 12 — Jenkins CI/CD Pipeline for Hot Deployments in Kubernetes

Scenario:

We have a microservice app in a Git repository.

We want automatic build, test, dockerize, and deploy to Kubernetes using hot deployment strategies.

We’ll include rolling update + rollback.

1️⃣ Jenkinsfile (Declarative Pipeline)

pipeline {
agent any

environment {
    REGISTRY = 'registry.example.com/myapp'
    K8S_NAMESPACE = 'production'
    APP_NAME = 'myapp'
}

stages {

    stage('Checkout') {
        steps {
            git url: 'https://github.com/yourorg/myapp.git', branch: 'main'
        }
    }

    stage('Build & Test') {
        steps {
            sh 'mvn clean package -DskipTests'
        }
    }

    stage('Docker Build & Push') {
        steps {
            script {
                def imageTag = "${REGISTRY}:${env.GIT_COMMIT}"
                sh "docker build -t ${imageTag} ."
                sh "docker push ${imageTag}"
            }
        }
    }

    stage('Deploy to Kubernetes') {
        steps {
            script {
                def imageTag = "${REGISTRY}:${env.GIT_COMMIT}"

                // Rolling update deployment
                sh "kubectl set image deployment/${APP_NAME} ${APP_NAME}=${imageTag} -n ${K8S_NAMESPACE} --record"
                sh "kubectl rollout status deployment/${APP_NAME} -n ${K8S_NAMESPACE} --timeout=120s"
            }
        }
    }

    stage('Smoke Test') {
        steps {
            sh "curl -f http://myapp.example.com/health || exit 1"
        }
    }

}

post {
    failure {
        // Automatic rollback on failure
        sh "kubectl rollout undo deployment/${APP_NAME} -n ${K8S_NAMESPACE}"
    }
}
Enter fullscreen mode Exit fullscreen mode

}

2️⃣ Kubernetes Deployment YAML (Rolling Update + Readiness Probe)

apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: production
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: registry.example.com/myapp:latest
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 5

3️⃣ Notes & Best Practices

Rolling Update Strategy → Ensures zero downtime by updating pods gradually.

Readiness Probe → Prevents traffic to unready pods.

Automatic Rollback → Jenkins post-failure block rolls back deployment.

Smoke Test → Confirms new version is healthy before pipeline finishes.

Versioned Images → Always use commit hash or semantic version for Docker tags to avoid confusion.

Namespace Isolation → Use separate K8s namespaces for staging, QA, production.

4️⃣ Optional Blue-Green / Canary Strategy

Blue-Green: Create a new deployment myapp-green → switch service selector after verification.

Canary: Use ingress annotations or service mesh to route small % traffic → gradually increase → full rollout.

CI/CD can integrate canary by modifying the Jenkinsfile to deploy to myapp-canary first, run smoke tests, then switch traffic.

✅ This setup ensures:

Hot deployment → minimal downtime.

Safe rollback → automatic if deployment fails.

Continuous delivery → fully automated CI/CD pipeline from Git commit to production.

Top comments (0)