文章目录
- 介绍
- 核心要素
-
- [1. 镜像](#1. 镜像)
- [2. 容器](#2. 容器)
- [3. 仓库](#3. 仓库)
- Dockerfile
- 容器互联
- 多容器管理
- 数据持久化
-
- [1. 数据卷 (Volumes) ------ "Docker 官方管理的专属储物间"](#1. 数据卷 (Volumes) —— “Docker 官方管理的专属储物间”)
- [2. 绑定挂载 (Bind Mounts) ------ "指定服务器上的特定文件夹"](#2. 绑定挂载 (Bind Mounts) —— “指定服务器上的特定文件夹”)
- 项目部署
-
- [1. 项目盘点](#1. 项目盘点)
- [2. 编写Dockerfile](#2. 编写Dockerfile)
- [3. 编写docker-compose.yml 编排](#3. 编写docker-compose.yml 编排)
- [4. 服务器环境准备与搬家](#4. 服务器环境准备与搬家)
- [5. 一键启动与验证](#5. 一键启动与验证)
介绍
Docker 就像是软件领域的"集装箱"。在没有它之前,把代码从开发者的电脑搬到生产服务器上,往往会遇到"在我的电脑上明明能跑"的尴尬问题。Docker 通过将应用程序及其所有的依赖环境打包在一起,确保它在任何地方都能一致地运行。
核心要素
1. 镜像
类比:"蛋糕菜谱"。镜像是一个只读的、静态的打包模板。它包含了运行你的应用所需的所有内容:代码、运行环境、系统库文件、配置文件等。它就像一张写满了配料和烘焙步骤的菜谱,菜谱本身不能吃,但它精确规定了蛋糕该怎么做。
2. 容器
类比:"烤出来的蛋糕"。容器是镜像运行起来的实体。当你根据"菜谱"(镜像)真正去执行时,得到的活生生的、正在运行的程序就是"蛋糕"(容器)。你可以启动、停止、甚至销毁容器。最关键的特性是:它们之间是相互隔离的。
3. 仓库
类比:"菜谱分享社区"。仓库是集中存放和分发镜像的地方(最常用的是官方的 Docker Hub)。你可以从这里直接下载别人已经配置好的"菜谱"(比如直接拿来用的 MySQL 或 Python 环境),也可以把你自己打包好的"菜谱"推送到这里保存或分享给团队。
Dockerfile
文本文件,描述如何自动构建镜像。
编写Dockerfile:以python文件为例
-
选择基础镜像
DockerfileFROM python:3.9-slim用于构建python基本环境
-
将代码从个人电脑复制到镜像里面去
Dockerfile# 指定容器内的工作路径(相当于电脑终端里输入 cd /app) WORKDIR /app # 将电脑当前目录下的代码,复制到容器的 /app 目录里 COPY . /app -
运行启动文件(以app.py为例)
Dockerfile# 容器启动时默认执行的命令 CMD ["python", "app.py"]相当于执行命令:
python app.py
基于Dockerfile构建镜像
Dockerfile
# 构建镜像(基于当前目录的Dockerfile)
docker build -t my-app .
-
-t my-app:代表 tag(标签),相当于给刚出炉的"蛋糕"贴上一个名字,方便以后随时调用。 -
.:它是指代"当前目录",告诉 Docker 就在此时此刻的文件夹里寻找那份 Dockerfile 菜谱和应用代码。
启动镜像
Dockerfile
docker run my-app
Docker 会找到刚刚构建好的 my-app 镜像,在系统里划出一片独立的区域,然后按照 Dockerfile 里最后一步,执行 python app.py。应用就这样在一个干净、隔离的环境里成功运行了。
容器互联
默认情况下,Docker 非常强调隔离。如果你的 Python 应用在一个容器里,MySQL 数据库在另一个容器里,它们就像住在一栋公寓楼里互不认识的邻居,彼此的门都是紧闭的。
为了让它们能互相配合,需要建立一个 Docker 网络 (Network)。相当于给这几个特定的房间牵了一根专属的"内部对讲机"线路。
具体操作通常只需要两步:
- 建一个"内部局域网": 使用命令
docker network create my-app-net创建一个专属的虚拟网络。 - 把容器接入网络: 在启动容器时,加上
--network参数。比如:docker run --network my-app ...
这里 Docker 提供了一个非常实用且强大的特性:内置的自动域名解析 (DNS)。
在传统的物理机上,两台机器通信通常需要知道对方的具体 IP 地址(比如 192.168.1.100)。但容器每次重启,它的内部 IP 可能会发生变化。为了解决这个问题,只要容器加入了同一个自定义网络,它们就可以直接用容器的名字来找到彼此,Docker 会在后台自动把名字翻译成正确的 IP。
多容器管理
使用多容器编排工具------Docker Compose,不需要一句句去敲命令,只需要一个名为 docker-compose.yml 的配置文件
在这个文件里,你会像写清单一样把所有容器罗列出来:
- 服务名称与镜像版本: 比如
web使用nginx:latest,db使用mysql:8.0。 - 网络配置: 明确哪些容器在同一个网络里。
- 先后顺序(核心): 针对你提到的先后顺序,Docker Compose 提供了一个非常强大的参数叫
depends_on(依赖于)。例如,在 Python 后端的配置里写上depends_on: - db,就会知道必须先让数据库启动成功,才能去启动后端应用。
执行下方命令,会自动建网络、排顺序、把它们全部在后台(-d 参数代表后台运行)稳稳地跑起来。
Dockerfile
docker-compose up -d
数据持久化
容器就像是一间"短期租赁的公寓",而且这间公寓有一项极其严格的规定:退房时必须恢复原样,清空内部产生的所有私人物品。如果你的 MySQL 数据库容器把产生的数据(比如用户信息、订单记录)直接保存在公寓内部,一旦容器被删掉重建(退房),数据就全灰飞烟灭了。
为了解决这个问题,Docker 提供了两种主流的"挂载"方式,相当于给这个公寓配了两种不同类型的"外部存储":
1. 数据卷 (Volumes) ------ "Docker 官方管理的专属储物间"
Docker 最推荐的方式,尤其是用于数据库。
- 原理: Docker 会在你服务器的隐藏深处(通常是你平时不会去动的地方)开辟一块专属的存储空间。
- 特点: 完全由 Docker 大管家来管理,哪怕容器被炸毁了,这个储物间依然完好无损地存在。下次你启动一个新的数据库容器,只要再次把这个储物间"挂载"给它,新容器瞬间就能读取到所有历史数据。
2. 绑定挂载 (Bind Mounts) ------ "指定服务器上的特定文件夹"
该方式多用于日常开发调试。
- 原理: 你强制把宿主机(你的电脑或服务器)上某个具体的路径(比如
/Users/me/my_code)和容器内的某个路径"强行绑定"在一起。 - 特点: 就像插了一个双向同步的 U 盘。你在外面修改了代码保存,容器里面的代码立刻同步更新。这样你就不用每次改了一行代码都去重新
docker build镜像了。
项目部署
核心:盘点、造镜像、搞编排、做准备、一键起飞。
1. 项目盘点
- 技术栈: 搞清楚项目是用什么语言、什么框架写的,需要哪个版本的运行环境。
- 依赖服务: 项目是否需要 MySQL、Redis、MongoDB 等外部组件?
- 配置文件: 找出项目里控制连接地址、端口、密码的环境变量或配置文件。
2. 编写Dockerfile
- 为你的主应用(比如后端 API)写一个 Dockerfile。
- 核心原则: 选择轻量级基础镜像(如 -slim 或 -alpine),把你的代码
COPY进去,指定WORKDIR,写好启动命令CMD。
3. 编写docker-compose.yml 编排
- 如果项目包含"主应用 + 数据库",不要手动一个个去跑容器。
- 在项目根目录下建一个
docker-compose.yml,把应用、数据库罗列出来,配置好自定义网络(让它们能互相通信)和数据卷挂载(防止数据库丢失)。
4. 服务器环境准备与搬家
- 服务器端: 在你的云服务器上安装好 Docker 和 Docker Compose。
- 文件传输: 把项目的代码、Dockerfile、docker-compose.yml 压缩打包,通过 SSH/SCP 或者 Git 传到服务器指定的目录下。
5. 一键启动与验证
-
在服务器对应的项目目录下,执行
Dockerfiledocker-compose up -d -
检查状态:执行
docker ps查看容器是否都处于Up状态。 -
看日志:如果报错,执行
docker-compose logs -f [服务名]查看具体报错信息
以上为个人学习分享,如有问题,欢迎指出:)