通过Docker部署FastAPI应用程序
🌞欢迎来到PyTorch深度学习实战的世界
🌈博客主页:卿云阁💌欢迎关注🎉点赞👍收藏⭐️留言📝
📆首发时间:🌹2026年5月24日🌹
✉️希望可以和大家一起完成进阶之路!
🙏作者水平很有限,如果发现错误,请留言轰炸哦!万分感谢!
目录
Docker 是什么
安装 Docker Desktop
准备文件
用 Xftp 连接服务器
Step 1:先确认你本地的项目文件
Step 2:在项目目录新增 3 个文件
Step 3:检查项目最终结构
Step 4:把文件传到服务器
Step 5:在服务器上验证文件
Step 6:在服务器上安装 Docker
Step 7:构建 Docker 镜像
Step 8:启动容器
Step 9:在服务器内部测试
Step 10:配置阿里云防火墙(让外部能访问)
Step 11:从本地电脑测试外部访问
常用 Docker 命令清单
组 1:容器生命周期
组 2:查看状态
组 3:调试和诊断
组 4:清理资源
模型/代码更新流程
Docker 是什么
一个真实场景:假设你这个曝气预测 API 训练好了,要部署到污水厂的服务器上。没有 Docker 时
你会面临什么?
你电脑上 厂里服务器上 ───────── ───────────── Windows 11 CentOS 7 Python 3.10 Python 3.6 PyTorch 2.1 未安装 你的代码 什么都没有 模型文件 什么都没有你需要做的事:
远程连服务器
装 Python 3.10(系统自带 3.6 不能用,但又不能卸载,可能依赖系统)
装 pip
装 PyTorch(可能因为网络问题失败,下载 800MB)
装其他依赖
上传你的代码
上传模型文件
试着跑 → 各种"找不到 xxx"的报错
修 bug,调环境
终于跑起来了 → 重启服务器后又挂了,因为没配开机自启
...
一个流程下来 2~3 天,而且换一台服务器还得重来一遍。
Docker 怎么解决这个问题?
Docker 的核心思想:把"代码 + 运行环境 + 依赖"打包成一个完整的盒子,搬到任何机器上都能直
接跑。
你电脑上 厂里服务器上 ───────── ───────────── [Docker 镜像] ───复制/推送──> [Docker 镜像] ├─ Python 3.10 ↓ ├─ PyTorch 2.1 docker run ├─ 你的代码 ↓ ├─ 模型文件 [运行中的容器] └─ 所有配置 服务正常运行 ✅整个部署过程从"2~3 天"变成"5 分钟"。
没 Docker 时: 你做了顿菜想给朋友吃 → 跑到朋友家 → 借他的厨具 → 用他的食材 → 现场做菜 → 朋友家没烤箱 → 凉了 有 Docker 时: 你做好菜装进保温饭盒 → 拎到朋友家 → 朋友直接吃 → 不管朋友家有没有厨房, 菜的味道都一样Docker 镜像 = 保温饭盒:里面装好了菜(代码)+ 餐具(运行环境)+ 调料(依赖) Docker 容
器 = 端上桌的那份饭:从饭盒拿出来的可吃的状态
三个必须懂的核心概念
┌─────────────────────────────────────────────────────┐ │ │ │ Dockerfile ──build──> Image ──run──> Container│ │ (菜谱) (饭盒) (上桌的饭)│ │ │ └─────────────────────────────────────────────────────┘| 概念 | 通俗解释 | 例子 |
|---|---|---|
| Dockerfile | 写明"怎么打包"的菜谱文件 | "先装 Python,再装 PyTorch,再放代码" |
| Image (镜像) | 打包好的文件包,不可变 | aeration-api:v1 |
| Container (容器) | 镜像运行起来的活跃实例 | 一个正在跑的 API 服务 |
比喻:
Dockerfile 是类的定义
Image 是类的代码(编译后的)
Container 是类的实例(new 出来的对象)
重要关系:
一个 Dockerfile 可以构建出一个镜像
一个镜像可以启动出多个容器(就像一个类可以实例化多个对象)
安装 Docker Desktop
Docker Desktop是什么?
Docker Desktop 是给个人电脑(Mac/Windows)用的 Docker 图形化软件,它把"Docker 引擎 +
命令行工具 + 图形界面 + 一些常用功能"打包成了一个安装包。
| 系统 | 下载链接 | 注意事项 |
|---|---|---|
| Mac (Intel) | https://www.docker.com/products/docker-desktop/ | 选 "Mac with Intel chip" |
| Mac (M1/M2/M3) | 同上 | 选 "Mac with Apple chip" |
| Windows 10/11 | 同上 | 需要先启用 WSL 2 (下面讲) |
| Linux | https://docs.docker.com/engine/install/ | 装 Docker Engine 即可 |
Windows 用户特别注意
Windows 装 Docker 要先启用WSL 2(Windows Subsystem for Linux):
# 用管理员权限打开 PowerShell wsl --install # 重启电脑装完后验证
打开终端(Mac/Linux)或 PowerShell(Windows),运行:
docker run hello-world这会下载一个超小的测试镜像并运行,预期输出:
Hello from Docker! This message shows that your installation appears to be working correctly. ...但是它的内存占用还是很大的,为了方便我们从阿里租一台服务器
| 项目 | 大小 |
|---|---|
| Docker Desktop 软件本身 | 约1.5~2 GB |
| 自带的 Linux 虚拟机 | 约2~4 GB |
| 拉一个 Python 基础镜像 | 约150 MB |
| 拉一个 PyTorch 镜像 | 约2~6 GB(这是大头!) |
| 构建你的镜像(含 PyTorch) | 约1~3 GB(会复用基础镜像层) |
准备文件
本地操作: 1. 准备文件 (Dockerfile, requirements.txt, .dockerignore) 2. 把所有文件上传到服务器 ↓ 服务器操作: 3. 安装 Docker (如果还没装) 4. 构建镜像 5. 启动容器 6. 测试 API ↓ 对外开放: 7. 配置阿里云防火墙 (放行 8000 端口) 8. 外部测试用 Xftp 连接服务器
第一次连接
打开 Xftp
文件菜单 → 新建会话(或按 Ctrl + N)
填写连接信息: 名称: Aeration Server (随便起) 协议: SFTP 主机: 你的服务器公网 IP (比如 47.123.45.67) 端口号: 22 用户名: root 密码: 你设置的服务器密码点 "连接"
第一次会弹"SSH 主机密钥"提示,点 "接受并保存"
Step 1:先确认你本地的项目文件
你本地应该有这些文件,全部需要上传到服务器:
你的项目目录/ ├── app.py ✅ FastAPI 服务 (你已经有) ├── predictor.py ✅ 预测器 (你已经有) └── deploy_t+1h/ ✅ 模型文件夹 ├── model.pt └── scaler.pklStep 2:在项目目录新增 3 个文件
2.1 创建requirements.txt
新建文件requirements.txt:
--extra-index-url https://download.pytorch.org/whl/cpu torch==2.1.0+cpu numpy==1.26.4 scikit-learn==1.4.2 joblib==1.3.2 fastapi==0.110.0 uvicorn[standard]==0.29.0 pydantic==2.6.4 EOF可以使用下面这个命令,只会安装本项目需要的包
# 1. 在你本地电脑的项目目录 cd D:\vscode-water\D_LSTM\aeration # 2. 装 pipreqs pip install pipreqs # 3. 生成 requirements.txt pipreqs . --force # 4. 看一下 cat requirements.txt # 或在 Windows: type requirements.txt2.2 创建Dockerfile
新建文件Dockerfile(没有后缀):
# 基础镜像: Python 3.10 精简版 (比完整版小 600MB) FROM python:3.10-slim # 设置工作目录 (容器内的路径) WORKDIR /app # 先复制依赖文件 (利用 Docker 缓存层, 后续改代码不用重装依赖) COPY requirements.txt . # 安装依赖 # -i 用清华镜像源 (国内构建快 10 倍) RUN pip install --no-cache-dir -r requirements.txt \ -i https://pypi.tuna.tsinghua.edu.cn/simple # 复制代码和模型文件 COPY app.py predictor.py ./ COPY deploy_t+1h ./deploy_t+1h # 声明端口 (仅做说明, 实际靠 docker run 的 -p 参数映射) EXPOSE 8000 # 启动命令 CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]逐行解释:
| 行 | 作用 |
|---|---|
FROM python:3.10-slim | 用官方精简 Python 镜像作为起点 |
WORKDIR /app | 容器内进入/app目录工作 |
COPY requirements.txt . | 先单独复制依赖文件 |
RUN pip install ... | 装依赖(这一步会被缓存,下次改代码很快) |
COPY app.py predictor.py ./ | 复制 Python 代码 |
COPY deploy_t+1h ./deploy_t+1h | 复制模型文件夹 |
EXPOSE 8000 | 文档性质,说明容器用 8000 端口 |
CMD [...] | 容器启动时执行的命令 |
重要点:--host 0.0.0.0不能省!容器内默认监听127.0.0.1是只能内部访问,必须用0.0.0.0
才能从外部访问。
2.3 创建.dockerignore
新建文件.dockerignore:
__pycache__ *.pyc *.pyo .git .gitignore .vscode .idea *.ipynb *.csv data/ notebooks/ features/ *.png *.pdf README.md .DS_Store .env venv/ .pytest_cache作用:构建镜像时跳过这些不必要的文件,让镜像更小、构建更快。
Step 3:检查项目最终结构
应该是这样的:
你的项目目录/ ├── app.py ├── predictor.py ├── deploy_t+1h/ │ ├── model.pt │ └── scaler.pkl ├── requirements.txt ⭐ 新增 ├── Dockerfile ⭐ 新增 (注意: 没有后缀名!) └── .dockerignore ⭐ 新增Step 4:把文件传到服务器
Step 5:在服务器上验证文件
通过 SSH 连接到服务器后:
cd /root/aeration ls -la应该看到:
-rw-r--r-- app.py -rw-r--r-- predictor.py -rw-r--r-- Dockerfile -rw-r--r-- requirements.txt -rw-r--r-- .dockerignore drwxr-xr-x deploy_t+1h/Step 6:在服务器上安装 Docker
如果还没装 Docker:
# 一键安装 (用阿里云镜像源, 国内快) curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun # 启动 systemctl start docker systemctl enable docker # 验证 docker --version docker run hello-world如果报这个错误,网络连不上 Docker 官网,被防火墙挡住了,所以安装失败。
进行下面的操作
解决方案:用 apt 直接装(最稳)
按下面顺序执行(一行一行来,每行执行完看看有没有报错):
Step 1:更新包索引
apt updateStep 2:装必要的工具
apt install -y ca-certificates curl gnupg lsb-releaseStep 3:用阿里云的 Docker 源(关键!)
# 创建 keyring 目录 install -m 0755 -d /etc/apt/keyrings # 下载阿里云的 Docker GPG key curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg # 设置权限 chmod a+r /etc/apt/keyrings/docker.gpg # 添加阿里云的 Docker 软件源 echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | tee /etc/apt/sources.list.d/docker.list > /dev/nullStep 4:再更新一次(加载新源)
apt updateStep 5:装 Docker
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin这一步会下载几百 MB,等几分钟。
出现这个页面之后
直接选 OK 就行
操作方式:
不需要勾选任何一项(不影响你装 Docker)
按 Tab 键 或 方向键 移动到 <Ok>
按 回车 确认
弹窗会消失,继续之前的命令。
这个提示是什么意思
| 选项 | 是什么 | 要不要重启 |
|---|---|---|
dbus.service | 系统消息总线 | 不用,会影响登录 |
getty@tty1.service | 终端登录服务 | 不用,可能踢掉你 |
networkd-dispatcher | 网络配置 | 不能选,可能让你 SSH 断开 |
systemd-logind | 登录管理 | 不用 |
unattended-upgrades | 自动更新 | 不用 |
全部不勾选最安全,避免远程连接断掉。这些服务等服务器下次重启时自然就用新库了。
安装成功了!这是 Docker 安装完成后的正常输出。
输出解释
✅
Running kernel seems to be up-to-date— 内核是最新的✅
Service restarts being deferred— 服务重启被推迟(这正是你选<Ok>不勾选服务的结果,正确操作)✅
No containers need to be restarted— 没有正在运行的容器需要重启✅
No user sessions are running outdated binaries— 没有用户会话用着旧的二进制✅
No VM guests are running outdated hypervisor binaries— 没有虚拟机受影响
Step 6:启动并验证
systemctl start docker systemctl enable docker docker --version应该看到:
Docker version 24.x.x, build xxxxxStep 7:验证能运行容器
docker run hello-world第一次会下载 hello-world 镜像,看到:
Hello from Docker! This message shows that your installation appears to be working correctly.就说明 Docker 装好了 ✅
如果出现这个问题,进行下面的操作
Step 1:获取你的专属加速地址
浏览器打开:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
如果是第一次访问,会让你**"开通服务"**——免费,点开通
进去后左侧菜单点 "镜像加速器"
你会看到属于你的专属加速地址,格式类似:
https://xxxxxxxx.mirror.aliyuncs.com复制这个地址,每个账号不一样。
Step 2:在服务器上配置
重要:把下面命令中的你的专属地址替换成 Step 1 复制的地址。
mkdir -p /etc/docker cat > /etc/docker/daemon.json <<'EOF' { "registry-mirrors": [ "https://你的专属地址.mirror.aliyuncs.com", "https://docker.m.daocloud.io", "https://hub-mirror.c.163.com", "https://mirror.baidubce.com" ] } EOF注意:我多加了几个备用镜像源(DaoCloud、网易、百度),万一阿里云的加速器某天慢了,会
自动尝试其他源。
Step 3:让配置生效
systemctl daemon-reload systemctl restart dockerStep 4:验证配置已加载
docker info | grep -A 5 "Registry Mirrors"应该看到:
Registry Mirrors: https://xxxxxxxx.mirror.aliyuncs.com/ https://docker.m.daocloud.io/ https://hub-mirror.c.163.com/ https://mirror.baidubce.com/Step 5:再试 hello-world
bash
docker run hello-world这次应该秒级下载并运行:
Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world e6590344b1a5: Pull complete Digest: sha256:xxxx Status: Downloaded newer image for hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly. ...成功
Step 7:构建 Docker 镜像
确认你在~/aeration目录下:
cd ~/aeration pwd # 应该显示 /root/aeration ls # 应该看到 Dockerfile 等文件构建镜像:
docker build -t aeration-api:v1 .注意最后那个.—— 它表示"用当前目录作为构建上下文"。不要漏掉。
你会看到这样的输出
[+] Building 0.2s (2/2) FINISHED => [internal] load build definition from Dockerfile => => transferring dockerfile: 533B => [internal] load .dockerignore Step 1/7 : FROM python:3.10-slim 3.10-slim: Pulling from library/python ... Step 2/7 : WORKDIR /app ... Step 3/7 : COPY requirements.txt . ... Step 4/7 : RUN pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple Collecting torch==2.1.0 Downloading https://pypi.tuna.tsinghua.edu.cn/.../torch-2.1.0-cp310-cp310-...whl (200 MB) ...这一步会比较慢(5~10 分钟),因为要下载 PyTorch。耐心等,看到Successfully tagged
aeration-api:v1就成功了。
构建成功后验证
docker images应该看到:
REPOSITORY TAG IMAGE ID CREATED SIZE aeration-api v1 abc123def456 2 minutes ago 1.2GB python 3.10-slim ... ... 125MBStep 8:启动容器
docker run -d \ --name aeration \ -p 8000:8000 \ --restart=always \ aeration-api:v1| 参数 | 含义 |
|---|---|
-d | 后台运行(detach) |
--name aeration | 给容器起个名字(方便后续操作) |
-p 8000:8000 | 把容器内的 8000 端口映射到服务器的 8000 端口 |
--restart=always | 重要!服务器重启或容器崩溃后自动重启 |
aeration-api:v1 | 用哪个镜像启动 |
验证容器在跑
docker psCONTAINER ID IMAGE COMMAND ... PORTS NAMES abc123... aeration-api:v1 "uvicorn..." ... 0.0.0.0:8000->8000/tcp aerationSTATUS显示Up xxx seconds就说明在跑。
查看日志(确认服务正常启动)
docker logs aeration应该看到:
INFO: Started server process [1] INFO: Waiting for application startup. INFO: Application startup complete. INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)Step 9:在服务器内部测试
# 测试根路径 curl http://localhost:8000/ # 测试预测接口 curl -X POST http://localhost:8000/predict \ -H "Content-Type: application/json" \ -d '{"history": [520.1, 525.3, 530.0, 528.4, 535.2, 540.1, 545.6, 550.0, 548.3, 552.1, 555.7, 560.0]}'应该看到:
{"message":"Aeration API is running. Visit /docs for documentation."} {"prediction":554.88}如果走到这里都成功了,你的 API 已经在云服务器上跑起来了! 🎉
Step 10:配置阿里云防火墙(让外部能访问)
服务器内部能访问不够,外部要能访问还需要开放端口。
登录阿里云控制台
进入"轻量应用服务器"
点你的实例
左侧菜单 → "防火墙"
点 "添加规则":
应用类型: 自定义 协议: TCP 端口: 8000 备注: Aeration API6.保存
Step 11:从本地电脑测试外部访问
在本地电脑(不是服务器)打开浏览器:
http://你的服务器公网IP:8000/docs应该看到 FastAPI 自动生成的文档页面,和你本地跑的时候一样。
或者用 Python 测试:
import requests response = requests.post( 'http://你的服务器公网IP:8000/predict', json={'history': [520.1, 525.3, 530.0, 528.4, 535.2, 540.1, 545.6, 550.0, 548.3, 552.1, 555.7, 560.0]} ) print(response.json()) # {'prediction': 554.88}java测试
import java.io.OutputStream; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; public class Main { public static void main(String[] args) throws Exception { String json = "{\"history\":[520.1,525.3,530.0,528.4,535.2,540.1," + "545.6,550.0,548.3,552.1,555.7,560.0]}"; // 建立连接 URL url = new URL("http://139.224.165.33:8000/predict"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "application/json"); conn.setDoOutput(true); // 发送请求体 try (OutputStream os = conn.getOutputStream()) { os.write(json.getBytes("UTF-8")); } // 读响应 try (BufferedReader br = new BufferedReader( new InputStreamReader(conn.getInputStream(), "UTF-8"))) { StringBuilder sb = new StringBuilder(); String line; while ((line = br.readLine()) != null) sb.append(line); System.out.println(sb.toString()); // 输出: {"prediction":554.88} } } }常用 Docker 命令清单
# 查看运行中的容器 docker ps # 查看所有容器(含已停止) docker ps -a # 查看日志 docker logs aeration # 实时查看日志(像 tail -f) docker logs -f aeration # 进入容器内部(调试用) docker exec -it aeration bash # 停止容器 docker stop aeration # 启动已停止的容器 docker start aeration # 重启容器 docker restart aeration # 删除容器(必须先停止) docker stop aeration && docker rm aeration # 查看镜像 docker images # 删除镜像 docker rmi aeration-api:v1 # 查看资源占用 docker stats aeration┌─────────────────────────────────────────────────┐ │ 组 1: 容器生命周期 (最常用) │ │ - 启动 / 停止 / 重启 / 删除 │ ├─────────────────────────────────────────────────┤ │ 组 2: 查看状态 │ │ - ps / images / stats │ ├─────────────────────────────────────────────────┤ │ 组 3: 调试和诊断 │ │ - logs / exec │ ├─────────────────────────────────────────────────┤ │ 组 4: 清理资源 │ │ - rm / rmi │ └─────────────────────────────────────────────────┘组 1:容器生命周期
容器有 4 个状态,命令负责状态切换:
┌──── docker stop ────┐ ▼ │ [运行中] [已停止] ▲ │ │ ▼ docker start docker rm │ ▼ [删除]命令 作用 通俗类比 重要说明 docker stop aeration 停止容器(优雅退出) 正常点 “关机” 给程序 10 秒保存数据,安全推荐 docker stop -t 30 aeration 延长优雅退出时间 给程序多留点时间保存 自定义等待 30 秒再强制关闭 docker kill aeration 强制立即杀死容器 直接拔电源 不推荐,可能造成数据丢失 docker start aeration 启动已停止的容器 开机 只重启旧容器,不创建新容器 docker restart aeration 重启容器 重启电脑 = stop + start,快速重启 docker rm aeration 删除容器 彻底删掉这台电脑 只能删已停止的容器 docker stop aeration && docker rm aeration 停止并删除容器 关机后彻底删除 最标准、最安全的删除方式 docker rm -f aeration 强制删除运行中容器 强行粉碎电脑 不推荐,风险高组 2:查看状态
看运行中的容器
docker psroot@iZuf65n4utc5xziyru8dowZ:~/aeration# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c7280984d5a9 aeration-api:v2 "uvicorn app:app --h…" 2 hours ago Up 2 hours 0.0.0.0:8000->8000/tcp, [::]:8000->8000/tcp aeration| 列名 | 你看到的内容 | 中文含义 |
|---|---|---|
| CONTAINER ID | c7280984d5a9 | 容器唯一 ID(相当于身份证号) |
| IMAGE | aeration-api:v2 | 容器用的镜像(软件包) |
| COMMAND | "uvicorn app:app --h…" | 容器启动时运行的命令 |
| CREATED | 2 hours ago | 容器创建时间(2 小时前) |
| STATUS | Up 2 hours | 运行状态:已运行 2 小时 |
| PORTS | 0.0.0.0:8000->8000/tcp | 端口映射:服务器 8000 端口 → 容器 8000 端口 |
| NAMES | aeration | 容器名字(你自己起的) |
查看所有容器
docker ps -aroot@iZuf65n4utc5xziyru8dowZ:~/aeration# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c7280984d5a9 aeration-api:v2 "uvicorn app:app --h…" 2 hours ago Up 2 hours 0.0.0.0:8000->8000/tcp, [::]:8000->8000/tcp aeration ef3e71dc643f hello-world "/hello" 12 hours ago Exited (0) 12 hours ago| 列名 | 含义 | 第一行(你的项目) | 第二行(测试容器) |
|---|---|---|---|
| CONTAINER ID | 容器唯一 ID(身份证) | c7280984d5a9 | ef3e71dc643f |
| IMAGE | 镜像(软件包) | aeration-api:v2(你的项目) | hello-world(测试用) |
| COMMAND | 启动命令 | 后台 API 服务 | 测试运行命令 |
| CREATED | 创建时间 | 2 小时前 | 12 小时前 |
| STATUS | 运行状态 | Up 2 hours(正在运行) | Exited (0) 12 小时前(已退出 / 停止) |
| PORTS | 端口映射 | 8000 端口开放(可访问) | 无端口 |
| NAMES | 容器名字 | aeration(你命名的) | brave_booth(系统随机命名) |
看所有镜像
| 字段名 | 含义 | 你的项目镜像 | 测试镜像 |
|---|---|---|---|
| IMAGE | 镜像名称(软件包名) | aeration-api:v2(你的项目) | hello-world:latest(测试用) |
| ID | 镜像唯一 ID | b5e484b9505e | 2498fce14358 |
| DISK USAGE | 磁盘占用大小 | 8.21GB | 25kB |
| CONTENT SIZE | 镜像实际内容大小 | 2.87GB | 4.47kB |
| EXTRA | 状态:U = 正在使用 | U(正在用) | U(用过) |
实时资源占用
docker stats aeration| 列名 | 你的容器数据 | 中文含义 | 说明 |
|---|---|---|---|
| CONTAINER ID | c7280984d5a9 | 容器唯一 ID | 容器的 “身份证号”,全局唯一 |
| NAME | aeration | 容器名称 | 你给容器起的名字,更易识别 |
| CPU % | 0.11% | CPU 使用率 | 容器占用宿主机 CPU 的比例。0.11% 表示负载极低,完全不卡 |
| MEM USAGE / LIMIT | 318.4MiB / 1.571GiB | 内存使用 / 限制 | 当前用了 318.4MB,最大可用 1.571GB |
| MEM % | 19.79% | 内存使用率 | 占用了可用内存的 19.79%,还有大量富余 |
| NET I/O | 10.4kB / 8.44kB | 网络入 / 出流量 | 容器接收了 10.4kB,发送了 8.44kB 数据,说明网络通信正常 |
| BLOCK I/O | 1.12GB / 8.09MB | 磁盘读写流量 | 容器从磁盘读了 1.12GB,写了 8.09MB 数据 |
| PIDS | 9 | 进程数 | 容器内当前运行的进程总数,状态健康 |
组 3:调试和诊断
| 命令 | 作用 | 通俗解释 | 使用场景 |
|---|---|---|---|
docker logs aeration | 查看容器历史日志 | 翻一翻容器过去输出了什么 | 查报错、看启动是否成功 |
docker logs -f aeration | 实时跟踪日志 | 像看直播一样,持续刷新最新日志 | 调试接口、看实时运行状态 |
docker exec -it aeration bash | 进入容器内部 | 像 “远程登录” 进容器里操作 | 看文件、测试环境、手动执行命令 |
组 4:清理资源
镜像 (Image) = 安装包 → docker rmi 删除 容器 (Container) = 运行的程序 → docker rm 删除镜像 vs 容器到底是什么
┌──────────────────────────────────────────────────┐ │ │ │ 软件世界 Docker 世界 │ │ ──────── ──────── │ │ │ │ 软件安装包 ←→ 镜像 (Image) │ │ (.exe, .dmg) aeration-api:v2 │ │ │ │ 安装运行的程序 ←→ 容器 (Container) │ │ (任务管理器里跑着的) aeration │ │ │ └──────────────────────────────────────────────────┘镜像(Image)
是个静态文件,不动
放在磁盘上,占空间
可以从这一个镜像,启动多个容器(就像同一个安装包能装到多台电脑)
容器(Container)
是运行的实例,活的
占内存和 CPU
一个容器只能从一个镜像启动
实物对应到你的服务器
跑docker images,你看到的是镜像:
REPOSITORY TAG SIZE aeration-api v2 8.21GB ← 一个镜像 (静态文件) python 3.10-slim 140MB ← 另一个镜像跑docker ps,你看到的是容器:
NAMES IMAGE STATUS aeration aeration-api:v2 Up 5 hours ← 一个容器 (基于上面的镜像启动)关系图:
┌─────────────────────────────────┐ │ 镜像: aeration-api:v2 │ (磁盘上, 8.21GB) └────────────┬────────────────────┘ │ docker run 一次 ▼ ┌─────────────────────────────────┐ │ 容器: aeration │ (运行中, 占内存) │ 正在响应 API 请求 │ └─────────────────────────────────┘实际操作演示
删除容器:docker rm
# 容器必须先停止才能删除 docker stop aeration # 1. 停止容器 docker rm aeration # 2. 删除容器 # 或者一行搞定 docker stop aeration && docker rm aeration # 强制删除 (跳过停止, 不推荐) docker rm -f aeration直接删运行中的容器会报错:
docker rm aeration # Error response from daemon: cannot remove a running container # 必须先 stop, 或加 -f删除镜像:docker rmi
# 删除指定版本的镜像 docker rmi aeration-api:v1 # 删多个镜像 docker rmi aeration-api:v1 hello-world # 强制删除 (即使有容器关联) docker rmi -f aeration-api:v1有容器在用这个镜像时,删除会报错:
docker rmi aeration-api:v2 # Error response from daemon: conflict: unable to remove repository reference # "aeration-api:v2" - container c7280984d5a9 is using its referenced image正确做法:
# 1. 先停掉用这个镜像的容器 docker stop aeration && docker rm aeration # 2. 现在能删镜像了 docker rmi aeration-api:v2两者的依赖关系
容器依赖镜像,镜像可以独立存在:
┌─────────────────────────────────────────────┐ │ 镜像 v1 ──────► 容器 A (运行中) │ │ └────► 容器 B (运行中) │ │ │ │ 镜像 v2 ──────► 容器 C (运行中) │ │ │ │ 镜像 v3 (无容器使用) ← 这是"孤立"的镜像 │ └─────────────────────────────────────────────┘操作规则:
| 想做 | 限制 |
|---|---|
| 删容器 | 容器必须先停止(或用-f) |
| 删镜像 | 没有容器在用它(运行中或停止的都算) |
┌──────────────────────────────────────────────────────┐ │ │ │ docker build │ │ ────────────► ┌──────────────────────────┐ │ │ 从 Dockerfile │ 镜像 (Image) │ │ │ 构建 │ ───────────── │ │ │ │ - 磁盘上的静态文件 │ │ │ │ - 可以创建多个容器 │ │ │ │ - 删除用 docker rmi │ │ │ └────────────┬─────────────┘ │ │ │ │ │ │ docker run │ │ │ (创建并启动容器) │ │ ▼ │ │ ┌──────────────────────────┐ │ │ │ 容器 (Container) │ │ │ │ ───────────── │ │ │ │ - 运行中的实例 │ │ │ │ - 占用内存和 CPU │ │ │ │ - 删除用 docker rm │ │ │ │ (需先 stop) │ │ │ └──────────────────────────┘ │ │ │ └──────────────────────────────────────────────────────┘模型/代码更新流程
以后你重新训练了模型,或者改了代码,怎么更新部署?
# 1. 进入项目目录 cd ~/aeration # 2. 在本地改完代码后, 上传新文件 (覆盖旧的) # 3. 构建新版本镜像 docker build -t aeration-api:v3 . # 4. 停掉旧容器 docker stop aeration && docker rm aeration # 5. 启动新容器 (用新镜像) docker run -d --name aeration -p 8000:8000 --restart=always aeration-api:v3 # 6. 验证服务正常 sleep 5 docker logs aeration --tail 10 curl http://localhost:8000/ # 7. 确认新版本没问题后, 删除旧镜像 !!!关键步骤!!! docker rmi aeration-api:v2