Rolling Update deployment setup for web application

Our company is engaged in the development, support and maintenance of sites of any complexity. From simple one-page sites to large-scale cluster systems built on micro services. Experience of developers is confirmed by certificates from vendors.
Development and maintenance of all types of websites:
Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:
Development stages
Latest works
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    822
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    847
  • image_website-sbh_0.png
    Website development for SBH Partners
    999
  • image_website-_0.png
    Website development for Red Pear
    451

Configuring Rolling Update Deployment for Web Applications

Rolling Update is a gradual replacement of application instances: first 1–2 pods/containers are updated, their health is checked, then the next ones. Unlike Blue-Green, it doesn't require double resources, but old and new versions briefly coexist.

Rolling Update in Kubernetes

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 6
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 2         # allow up to 2 extra pods during update
      maxUnavailable: 1   # max 1 pod unavailable at any time
  minReadySeconds: 30     # pod considered ready 30 sec after start

  selector:
    matchLabels: { app: myapp }

  template:
    metadata:
      labels: { app: myapp }
    spec:
      containers:
        - name: myapp
          image: registry.example.com/myapp:v1.1.0
          readinessProbe:
            httpGet:
              path: /health/ready
              port: 8080
            initialDelaySeconds: 10
            periodSeconds: 5
            failureThreshold: 3
          livenessProbe:
            httpGet:
              path: /health/live
              port: 8080
            initialDelaySeconds: 30
            periodSeconds: 10
      terminationGracePeriodSeconds: 60  # allow time to finish request processing
# Update image
kubectl set image deployment/myapp myapp=registry.example.com/myapp:v1.2.0

# Watch progress
kubectl rollout status deployment/myapp

# History
kubectl rollout history deployment/myapp

# Rollback
kubectl rollout undo deployment/myapp
kubectl rollout undo deployment/myapp --to-revision=3

Graceful Shutdown

// Node.js/Express — proper shutdown on SIGTERM
process.on('SIGTERM', async () => {
    console.log('SIGTERM received, shutting down gracefully');

    // Stop accepting new connections
    server.close(() => {
        console.log('HTTP server closed');
    });

    // Allow time to finish current requests
    await new Promise(resolve => setTimeout(resolve, 30_000));

    // Close DB connections
    await db.destroy();

    process.exit(0);
});
// Laravel/Octane — graceful stop
// Octane handles SIGTERM itself, waiting for request completion
// Use in Dockerfile:
STOPSIGNAL SIGTERM

Rolling Update in Docker Swarm

# docker-compose.yml
services:
  web:
    image: registry.example.com/myapp:latest
    deploy:
      replicas: 4
      update_config:
        parallelism: 1    # update 1 at a time
        delay: 30s        # 30 seconds between updates
        failure_action: rollback
        monitor: 60s      # monitor 60 sec after pod update
        max_failure_ratio: 0.1
      rollback_config:
        parallelism: 2
        delay: 0s
        failure_action: pause
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
# Update service
docker service update --image registry.example.com/myapp:v1.2.0 myapp_web

# Watch
docker service ps myapp_web

# Rollback
docker service rollback myapp_web

Health Check Endpoint

Proper rolling update requires health checks distinguishing liveness and readiness:

// Laravel — health check routes
Route::get('/health/live', function () {
    // Just check that the process is alive
    return response()->json(['status' => 'ok']);
});

Route::get('/health/ready', function () {
    // Check readiness to accept traffic
    try {
        DB::connection()->getPdo();
        Cache::store()->get('health-check');
    } catch (\Exception $e) {
        return response()->json(['status' => 'not ready', 'error' => $e->getMessage()], 503);
    }
    return response()->json(['status' => 'ready']);
});

Problem of Incompatible Migrations

During Rolling Update, two app versions briefly run together. DB schema must be compatible with both:

Rule: Run migrations before deploying new code. Migration must be backward-compatible.

// CANNOT: rename column immediately
// Schema breaks old version

// CAN: three-stage deploy
// Deploy 1: add new_column (nullable)
// Deploy 2: fill new_column, switch code to it
// Deploy 3: drop old_column

Implementation Timeline

  • Kubernetes Rolling Update with health checks: 2–3 days
  • Docker Swarm rolling update: 1–2 days
  • Strategy for backward-compatible migrations: 1 day