一个问题
既然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"