Skip to content

一个问题

既然Docker部署如此简单,那可不可以把系统的前后端应用、数据库都放在一个容器里面,那样岂不是更方便?

这是一个非常经典且深刻的问题。对于初学者来说,最容易产生的直觉就是:“既然 Docker 是个集装箱,我能不能把代码、数据库、前端全装进一个箱子里?”

简单直接的回答是:技术上可以实现,但生产环境中绝对不建议这么做。

在 Docker 的哲学里,有一个核心原则:一个容器只做一件事(One Process Per Container)。

一、为什么不建议“全家桶”打包?

如果你把 Spring Boot、Vue 和 MySQL 全部打包成一个镜像,你会面临以下“灾难”:

  • 体积臃肿:这个镜像可能会达到几个GB,推送到云端或下载时会慢到让你怀疑人生。
  • 无法独立扩展:如果你的后端压力大,想多开两个实例,结果连带着数据库也多开了两个。这会导致数据冲突,且极度浪费资源。
  • 版本管理混乱:如果你只是改了前端的一个错别字,却不得不重新打包整个后端和数据库镜像。
  • 数据丢失风险:数据库的核心是持久化。如果数据库死在容器里,随着容器重启,你的数据可能会面临丢失的风险。

二、标准“三足鼎立”方案

在真实的开发中,我们通常采用 “多容器协作” 的模式。你会拥有三个独立的“集装箱”:

1. 容器 A:MySQL(数据库)

  • 职责:只负责存取数据。
  • 特点:使用官方现成的镜像,通过 Volume(挂载卷)把数据存在宿主机硬盘上。

2. 容器 B:Spring Boot(后端)

  • 职责:处理业务逻辑,连接数据库。
  • 特点:通过环境变量(如 DB_URL)动态连接到容器 A。

3. 容器 C:Nginx + Vue(前端)

  • 职责:存放静态资源,并作为反向代理。
  • 特点:用户访问 Nginx,Nginx 再把请求转发给后端的 Spring Boot。

三、如何让它们协同工作?(Docker Compose)

你可能会问:“分开了,我怎么管理它们呢?” 答案是 Docker Compose

它就像是一个**“总指挥”**。你只需要写一个 docker-compose.yml 配置文件,一键就能启动这三个互相关联的服务。

yaml
services:
  mysql:
    image: mysql:8.0
    # ...配置数据库...

  backend:
    build: ./pjone-server
    depends_on:
      - mysql  # 告诉 Docker,先启动数据库再启动后端

  frontend:
    build: ./pjone-vue
    ports:
      - "80:80"