You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Docker Compose实现滚动更新?低停机优化方案咨询

Hey there! Let's work through a zero-downtime deployment solution for your Docker Compose setup that keeps your existing config as clean as possible. Since you've got a slow-starting Spring Boot backend, fast-updating Node SSR frontend, MySQL dependency, and Nginx handling proxy duties, here's a practical approach tailored to your stack:

Zero-Downtime Deployment for Your Docker Compose Stack

Quick Base Config Tweaks (Minimal Changes)

First, let's make tiny adjustments to set this up smoothly—nothing drastic, just enough to let services communicate internally without exposing unnecessary ports:

  • Add all services to a shared custom Docker network (so Nginx can reach backend/frontend via container names instead of host ports)
  • Remove direct host port mappings for backend (8080) and frontend (4000) — only keep Nginx's 80/443 mapped to the host

Example adjusted docker-compose.yml snippet:

version: '3.8'

networks:
  app-network:
    driver: bridge

services:
  mysql:
    # Your existing MySQL config goes here
    networks:
      - app-network

  backend:
    image: your-backend-image:latest
    # Remove ports: - "8080:8080"
    networks:
      - app-network
    environment:
      - SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/your_database
    # Rest of your backend config

  frontend:
    image: your-frontend-image:latest
    # Remove ports: - "4000:4000"
    networks:
      - app-network
    # Rest of your frontend config

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./static:/usr/share/nginx/html
    networks:
      - app-network
    depends_on:
      - backend
      - frontend

Backend Deployment (Slow-Starting Spring Boot)

Since your backend takes ~1 minute to boot, we'll start the new instance first, wait for it to be fully ready, then shift traffic over:

  1. Spin up the new backend instance Use a temporary container name to avoid conflicting with the running one:
    # If using pre-built images
    docker-compose run --name backend-new -d your-backend-image:v2
    # If building locally
    docker-compose build backend && docker-compose run --name backend-new -d backend
    
  2. Wait for the backend to be ready Use your backend's health check endpoint (like Spring Actuator) to confirm it's up:
    until curl -s http://backend-new:8080/actuator/health | grep "UP"; do
      sleep 5
      echo "Waiting for new backend to finish starting..."
    done
    
  3. Switch traffic to the new backend Update your nginx.conf to proxy backend requests to backend-new:8080 instead of the old backend:8080, then reload Nginx without downtime:
    docker exec nginx nginx -s reload
    
  4. Clean up the old backend Once you confirm traffic is flowing to the new instance, stop and remove the old container:
    docker stop backend && docker rm backend
    # Optional: Rename the new instance to match the original service name for consistency
    docker rename backend-new backend
    

Frontend Deployment (Fast Node SSR)

Since the frontend starts quickly, we can simplify the flow:

  1. Launch the new frontend instance
    docker-compose run --name frontend-new -d your-frontend-image:v2
    
  2. Switch traffic to the new frontend Update nginx.conf to proxy frontend requests to frontend-new:4000, then reload Nginx:
    docker exec nginx nginx -s reload
    
  3. Clean up the old frontend
    docker stop frontend && docker rm frontend
    docker rename frontend-new frontend
    

Optional (Low-Effort) Upgrade

If you want to avoid manual health check scripts, add a built-in health check to your backend's docker-compose.yml—Docker will handle readiness checks for you:

backend:
  # Your existing config
  healthcheck:
    test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
    interval: 10s
    timeout: 5s
    retries: 5
    start_period: 60s # Account for the 1-minute boot time

Key Notes

  • Keep MySQL running continuously during deployments—don't restart it unless absolutely necessary, as it's a shared dependency.
  • For the SSR frontend, double-check the new instance can connect to the backend before switching traffic to avoid 502 errors.
  • Backup your nginx.conf before making changes, just in case you need to roll back quickly.

内容的提问来源于stack exchange,提问作者Marcin Kunert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:01:39