四种部署方式全集对比:传统部署 / Docker / Docker Compose / Kubernetes(含 Redis & MySQL)

场景约束:
两台 CentOS 服务器 —— server01(对外)server02(数据层)
数据库 MySQL
缓存 Redis
项目 Spring Boot + Vue3(前后端分离)


0) 拓扑与产物

flowchart LR
User((用户)) --> |80/443| Nginx

subgraph server01[server01(对外:Web+API)]
  W[Vue3 静态资源 (Nginx)]
  A[Spring Boot API]
  W -->|/api| A
end

subgraph server02[server02(数据层)]
  M[(MySQL 8.0)]
  R[(Redis 7.x)]
end

A <--3306--> M
A <--6379--> R

通用构建产物

  • 后端:app-<version>.jar

  • 前端:dist/(静态文件)

  • 运行时统一用环境变量注入:

    • DB_HOST/DB_USER/DB_PASS
    • REDIS_HOST/REDIS_PORT/REDIS_PASS

Spring Boot(片段,所有方案通用)

spring:
  datasource:
    url: jdbc:mysql://${DB_HOST:server02}:3306/myapp?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
    username: ${DB_USER}
    password: ${DB_PASS}

  data:
    redis:
      host: ${REDIS_HOST:server02}
      port: ${REDIS_PORT:6379}
      password: ${REDIS_PASS:}
      timeout: 2000ms
      lettuce.pool.max-active: 32

前端(Vite) .env.production

VITE_APP_API_BASE=/api

1) 总览对比(一眼看懂)

维度 传统部署(systemd+Nginx) Docker(单容器) Docker Compose(单机编排) Kubernetes(集群编排)
抽象层级 主机进程 镜像→容器 多容器应用 控制面编排的工作负载
环境一致性 一般 很好 最好(声明式期望态)
依赖隔离 最强
自愈与伸缩 基本(systemd) 基本(重启策略) 基本(healthcheck/依赖) 完整(探针、自愈、HPA)
发布/回滚 包/软链切换 切镜像 tag 改 yml tag,up -d rollout/蓝绿/金丝雀
编排与网络 手工 中(项目网络/卷) 强(Service/Ingress/流量治理)
观测集成 需自建 容器日志标准化 同左 原生贴合 Prom/Loki 等
成本/门槛
适用规模 少量服务/简单上线 单服务容器化 单机多服务/测试预发 多副本/高可靠生产
适合本场景 ✔(最快) ✔(推荐) 可行(较重)

2) 传统部署(systemd + Nginx)

放置

  • server02:安装并运行 MySQL + Redis(建议仅内网开放端口)。
  • server01:安装 JDK + Nginx,落地 app.jardist/

Redis(server02,最小配置)

sudo yum -y install epel-release redis
sudo sed -i 's/^# requirepass.*/requirepass redis_secret/' /etc/redis.conf
# 如需远程(内网)访问:设置 bind/防火墙策略;开启持久化
# appendonly yes; maxmemory 与 policy 依内存设置
sudo systemctl enable --now redis
sudo firewall-cmd --permanent --add-port=6379/tcp && sudo firewall-cmd --reload

后端 systemd(server01 /etc/systemd/system/myapp.service

[Unit]
Description=MyApp Spring Boot
After=network.target

[Service]
WorkingDirectory=/srv/myapp/current/api
Environment=DB_HOST=server02
Environment=DB_USER=myapp_user
Environment=DB_PASS=StrongPass!123
Environment=REDIS_HOST=server02
Environment=REDIS_PORT=6379
Environment=REDIS_PASS=redis_secret
Environment=JAVA_OPTS=-Xms512m -Xmx1024m
ExecStart=/usr/bin/java $JAVA_OPTS -jar app.jar --spring.profiles.active=prod
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

前端 Nginx(server01 /etc/nginx/conf.d/myapp.conf

server {
  listen 80;
  server_name your.domain.com;

  root /srv/myapp/current/web;
  index index.html;

  location / { try_files $uri $uri/ /index.html; }

  location /api/ {
    proxy_pass http://127.0.0.1:8080/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}

发版/回滚

  • 发版:上传新包到 releases/ → 切 current 软链 → systemctl restart myappnginx -s reload
  • 回滚:软链指回旧版本 → 重启服务/重载 Nginx。

优点:最少变动、上手快。
注意:依赖与环境一致性差;需要手工规范。


3) Docker 部署(单容器 + 主机 Nginx)

后端 Dockerfile

FROM maven:3.9-eclipse-temurin-17 as build
WORKDIR /src
COPY . .
RUN mvn -q -DskipTests -Pprod clean package

FROM eclipse-temurin:17-jre
WORKDIR /app
COPY --from=build /src/target/app-*.jar /app/app.jar
ENV SPRING_PROFILES_ACTIVE=prod
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app/app.jar"]

运行(server01)

docker run -d --name myapp-api --restart=always \
  -e SPRING_PROFILES_ACTIVE=prod \
  -e DB_HOST=server02 -e DB_USER=myapp_user -e DB_PASS=StrongPass!123 \
  -e REDIS_HOST=server02 -e REDIS_PORT=6379 -e REDIS_PASS=redis_secret \
  -p 8080:8080 registry.example.com/myapp/api:1.2.4

前端仍由主机 Nginx托管 dist/(与传统部署同(Nginx 配置复用))。

优点:环境可复制、回滚切 tag、主机更干净。
注意:编排弱,多容器依赖靠脚本/文档维持。


4) Docker Compose(单机多容器编排)(两台机最推荐)

方案

  • server02:MySQL + Redis(主机跑或容器跑均可,生产更建议主机/托管)。
  • server01:用 docker-compose.yml 一次性编排 web(Nginx)+ api(Spring Boot)

docker-compose.yml(server01)

version: "3.9"
services:
  api:
    image: registry.example.com/myapp/api:1.2.4
    container_name: myapp-api
    environment:
      SPRING_PROFILES_ACTIVE: prod
      DB_HOST: server02
      DB_USER: myapp_user
      DB_PASS: StrongPass!123
      REDIS_HOST: server02
      REDIS_PORT: 6379
      REDIS_PASS: redis_secret
    ports: ["8080:8080"]
    restart: always
    healthcheck:
      test: ["CMD","curl","-fsS","http://localhost:8080/actuator/health"]
      interval: 15s
      timeout: 3s
      retries: 5

  web:
    image: registry.example.com/myapp/web:1.2.4  # 用 Nginx 托管 dist 的镜像
    container_name: myapp-web
    ports: ["80:80"]
    depends_on:
      - api
    restart: always

如需把 Redis 也容器化放 server01(非强制):再加

 redis:
   image: redis:7-alpine
   command: ["redis-server","--requirepass","redis_secret","--appendonly","yes"]
   ports: ["6379:6379"]           # 仅限内网开放
   volumes: ["redisdata:/data"]
   restart: always
volumes:
 redisdata: {}

然后 REDIS_HOST 改为 redis(容器服务名)。

一键操作

docker compose up -d
docker compose ps
docker compose logs -f api
# 升/回级:修改镜像 tag -> up -d 即可
docker compose pull && docker compose up -d

优点:声明式、单机多服务最顺手;可读可审计;回滚容易。
注意:单机编排;跨机多副本/灰度需 K8s/更强工具。


5) Kubernetes(K8s 小集群)

方案

  • server01:control-plane + node
  • server02:worker node
  • MySQL/Redis 仍在 server02(集群外或独立主机),API 通过内网访问。
  • Ingress-Nginx 对外统一暴露域名。

API 部署(节选)

apiVersion: apps/v1
kind: Deployment
metadata: { name: myapp-api }
spec:
  replicas: 2
  selector: { matchLabels: { app: myapp-api } }
  template:
    metadata: { labels: { app: myapp-api } }
    spec:
      containers:
      - name: api
        image: registry.example.com/myapp/api:1.2.4
        ports: [{containerPort: 8080}]
        env:
          - name: SPRING_PROFILES_ACTIVE
            value: "prod"
          - name: DB_HOST      # 指向 server02
            value: "server02"
          - name: DB_USER
            valueFrom: { secretKeyRef: { name: db-secret, key: user } }
          - name: DB_PASS
            valueFrom: { secretKeyRef: { name: db-secret, key: pass } }
          - name: REDIS_HOST
            value: "server02"
          - name: REDIS_PORT
            value: "6379"
          - name: REDIS_PASS
            valueFrom: { secretKeyRef: { name: redis-secret, key: pass } }
        readinessProbe:
          httpGet: { path: /actuator/health, port: 8080 }
          initialDelaySeconds: 10
        livenessProbe:
          httpGet: { path: /actuator/health, port: 8080 }
---
apiVersion: v1
kind: Service
metadata: { name: myapp-api-svc }
spec:
  selector: { app: myapp-api }
  ports: [{ port: 80, targetPort: 8080 }]

Web(Nginx 静态)+ Ingress

apiVersion: apps/v1
kind: Deployment
metadata: { name: myapp-web }
spec:
  replicas: 1
  selector: { matchLabels: { app: myapp-web } }
  template:
    metadata: { labels: { app: myapp-web } }
    spec:
      containers:
      - name: web
        image: registry.example.com/myapp/web:1.2.4
        ports: [{containerPort: 80}]
---
apiVersion: v1
kind: Service
metadata: { name: myapp-web-svc }
spec:
  selector: { app: myapp-web }
  ports: [{ port: 80, targetPort: 80 }]
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata: { name: myapp-ing }
spec:
  ingressClassName: nginx
  rules:
  - host: your.domain.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend: { service: { name: myapp-api-svc, port: { number: 80 } } }
      - path: /
        pathType: Prefix
        backend: { service: { name: myapp-web-svc, port: { number: 80 } } }

运维要点

  • 发版:kubectl set imagerollout status;回滚:rollout undo
  • 健康:readiness/liveness 探针
  • 弹性:HPA(基于 CPU 或自定义指标)
  • 观测:Prometheus/Grafana + Loki/ELK;Spring Actuator 暴露指标

优点:自愈/扩缩/灰度完善,生产级可靠。
注意:两台机也能跑,但学习与维护成本较高。


6) 发布策略与数据库/缓存协同

  • 蓝绿:两套实例(或两套镜像 tag),切 Nginx upstream(传统/Docker/Compose)或 Ingress 权重(K8s)。
  • 滚动:逐个替换(Compose up -d、K8s 默认)。
  • 金丝雀:K8s + Ingress/Istio 支持按流量百分比放量。
  • MySQL 迁移:Flyway/Liquibase,向前兼容(先扩展字段/双写,后切读,最终清理)。
  • Redis 缓存:发布前可设置短 TTL;有需要时在切换后执行精确失效/全量失效(谨慎)。

7) 安全与网络

  • 开放端口:server01 仅 80/443;server02 仅内网放行 3306/6379。
  • Redisrequirepass、仅内网访问、持久化策略(AOF/RDB)、内存上限与淘汰策略。
  • 机密:环境变量或(K8s)Secret,避免写死在仓库。
  • HTTPS:Nginx/Ingress 终止 TLS(Let’s Encrypt/证书)。
  • 备份:MySQL 定时备份;Redis AOF/RDB 备份;前端静态可归档。

8) 选型建议(两台 CentOS,Spring Boot + Vue3 + MySQL + Redis)

  • 要快、可控且成本低:传统部署(加上软链回滚与简单脚本)就能稳上线。
  • 要环境一致性与易回滚Docker Compose(首选) —— server01 编排 web+api,server02 跑 MySQL+Redis。
  • 要多副本/弹性/金丝雀:K8s 可上,但两台机的小集群性价比不如 Compose;除非你明确要走长期平台化。

最小清单(拎包即用)

  • 传统myapp.service + myapp.conf(本文给出)、软链结构 /srv/myapp/{releases,current,logs}
  • Docker:后端/前端 Dockerfile + 主机 Nginx 配置。
  • Compose:文中 docker-compose.yml
  • K8sDeployment/Service/Ingress 清单(上文节选)。
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐