方向:AI 应用开发后端 写作日期:2026-08-18

一、缘起:为什么一个想做 AI 后端的我,要先学 Docker
我给自己定的未来方向是 AI 应用开发后端 。在很多人的想象里,"AI 后端"等于调模型接口、写 prompt、搭 RAG。但真正开始做之后我发现,一个能用的 AI 应用,落到工程层面其实是一堆服务在协作:模型推理服务、向量数据库、对话缓存(Redis)、用户与业务数据(MySQL)、网关与代理......
这些服务各自有严格的环境与版本要求。Python 要 3.10,CUDA 要对应某个版本,Node 要 16,Redis 要 7。装在一个机器上,互相踩版本、互相污染环境,是我最先撞上的墙。
于是我问了自己一个问题:那些大规模生产环境里的 AI 应用,基础设施到底是怎么搭的? 顺着这个问题,我走到了 Docker 面前。
二、第一课:集装箱思维 ------ Docker 到底是什么
学习 Docker 时,最先让我"开窍"的是这个类比:

Docker 就像海运里的万吨巨轮和集装箱。
一艘万吨巨轮,可以同时运送成千上万个集装箱。每个集装箱里装着完全不同的货物------有的装着汽车,有的装着服装,有的装着水果。它们互不干扰,装进船里就能漂洋过海,到达任何一个港口,卸下来就能用。
我们的应用也是这样。过去交付一个软件,是"交一堆代码 + 一堆环境要求文档"。到部署方手里,还要现场配环境、对版本、踩坑。而 Docker 把代码和运行环境一起打包成一个标准化的容器,任何一台装了 Docker 的机器,拉下来就能跑,就像集装箱在任何港口都能吊装一样。
我用一句话把 Docker 的本质记了下来:
ini
Agent = LLM + Harness(tool + mcp + rag + skill + ...)
Docker = 应用 + 运行环境
这行对照是我自己的一个小心得。我在做 AI Agent 时理解了"一个 Agent 不是只有模型,而是模型加上一整套工具、上下文、技能的装载"。同样的思维模型,放在 Docker 身上就通了------一个应用不是只有代码,而是代码加上它依赖的一整套运行环境。打包这个"整体",正是容器化干的事情。
三、我踩过的坑:为什么需要"隔离"
道理是空的,坑是实的。让我真正想做这件事的,是一个身边真实的场景:
你到公司接手一个 n 年前写的 Vue2 项目,要求 Node16 + npm 8。而你的电脑装的是 Node 22,代码一跑就报错,跑不起来。
这不是罕见情况,而是后端日常。Java 有 JDK 版本之争,Python 有 2/3 之争,Node 有版本飞速迭代,更别提 C 系的依赖地狱。每一个版本差异,都是一次环境冲突;每一次环境冲突,都是一次无效加班。
容器化技术把各个依赖隔离化安装:每个项目一个容器,各装各的 Node 版本、各装各的依赖,互不打扰。你不需要在自己的机器上为了一个老项目把 Node 卸了重装------就像一辆万吨巨轮不会因为其中一个集装箱里的水果需要冷藏,就把整艘船都改造成冷库。
这个"隔离"的思想,对我后面理解 AI 后端的服务治理特别重要:模型服务、向量库、业务库,本质上是各自独立的集装箱,跑在各自的容器里,通过端口和网络互相协作。
四、核心概念:镜像与容器
理解了"集装箱"这个心智模型,Docker 里最重要的两个概念就顺了:
- 镜像(Image) :一个打包好的、只读的模板 ,包含应用和环境。我把它类比成
git pull------从远程仓库拉一份代码。Docker 则是从镜像仓库pull一个镜像。 - 容器(Container) :镜像运行起来的实例 。我把它类比成一张 DVD------镜像像母盘,可以复制出很多张,每一张运行起来就是一个独立的容器;或者说,镜像像一张光盘模板,
run一次就烧录出一个能播放的"播放器"。
bash
# 拉取镜像(类比:git pull)
docker pull nginx
# 运行镜像,成为可运行的容器
docker run --name my-nginx-demo -d nginx
# 停掉所有容器 / 删除所有容器 / 删除镜像
docker stop $(docker ps -q)
docker rm $(docker ps -aq)
docker rmi <镜像名>
还有一个一开始困扰我的点:端口。
我们访问网站时输入 www.juejin.cn:3000,域名后跟的 :3000 就是端口。默认的 :80 是 HTTP 的默认端口,所以访问 www.example.com 其实访问的是 www.example.com:80,只是浏览器帮我们隐藏了。
Docker 里容器是隔离的,外部访问不进来,所以要端口映射:把宿主机(我们这台机器)的一个端口,映射到容器内部的端口。比如:
bash
docker run --name my-nginx-demo -p 80:80 -d nginx
# ↑ 容器的名字 ↑ 本机80端口:容器80端口
-p 80:80 表示"本机的 80 端口 对应 容器内部的 80 端口"。用户浏览器输入 http://localhost:80,请求被转发映射进容器的 80。
五、动手实践:用 nginx 反向代理部署一个 Node 服务

理论讲再多,不如跑一遍。我照着笔记做了一个最简单但完整的实践:一个 Node 服务 + nginx 反向代理。
先写一个最朴素的 Node 服务,监听 1314 端口,返回 "hello world":
js
// demo/index.js
const http = require('http');
const server = http.createServer((req, res) => {
res.end("hello world");
});
server.listen(1314, '0.0.0.0', () => {
console.log('node server run on 1314');
});
在 demo/conf.d/nginx.conf 里配置 nginx 反向代理,把 80 端口的请求转发给 1314 端口的 Node 服务:
nginx
# demo/conf.d/nginx.conf
server {
listen 80;
location / {
proxy_pass http://host.docker.internal:1314;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
然后启动 nginx 容器,把本机配置挂载进去:
powershell
docker run `
--name my-nginx-demo `
-p 80:80 `
-v D:\workspace\sw_ai\backend\docker\demo\conf.d:/etc/nginx/conf.d `
-d nginx
这条命令拆开看:
| 参数 | 作用 |
|---|---|
--name my-nginx-demo |
给容器起名 |
-p 80:80 |
本机 80 端口 映射 容器 80 端口 |
-v 本机目录:容器目录 |
把本机的 nginx 配置文件挂载进容器,改配置不用重新打包镜像 |
-d nginx |
以后台方式运行 nginx 镜像 |
跑起来后,完整的请求链路是:
csharp
用户浏览器(chrome)
→ localhost:80(正向代理出网)
→ docker -p 端口映射 → 容器内部 :80
→ nginx 收到 80 端口的访问
→ 按配置文件反代到 :1314(host.docker.internal 指向宿主机)
→ Node 服务返回 "hello world"
六、反身思考:反向代理到底意味着什么
这个 demo 看起来简单,但它让我想明白了一件后端的关键事:反向代理。
用户访问 localhost:80,浏览器(正向代理)帮我们出网;而 nginx 在 80 端口"替后端服务器接收请求"------用户根本不知道后端真正跑在哪个端口、哪台机器上。这个动作叫反向代理。
它的意义远不止"转发":
- 隐藏后端集群:真实的后端服务躲在内网,外面只看到一个 80 端口,安全得多。
- 高并发承接 :nginx 能扛很高的并发,把请求按规则分摊给后面多个后端实例,这就是负载均衡的雏形。
- 可扩展:后端想加一台、减一台机器,前端完全无感。
运维知识:服务器软件把所有在 80 端口的请求,代理给 3000(或 1314)端口。
这个"外面一个口,里面一群服务"的形态,正是所有现代后端(包括 AI 后端)的标准姿势。
七、Docker 在我 AI 后端路线图里的位置
这是这篇博客我最想讲的部分。学 Docker 不是单纯补一门运维知识,而是我发现 AI 应用后端的整个基础设施,几乎都能用这套"集装箱"思维来理解:
1. 模型服务化:LLM 本身就是一个容器
生产环境里,你几乎不会在代码里直接 import 一个千亿参数模型。通常是把模型推理封装成一个独立的模型服务(比如一个跑着 vLLM / Ollama 的容器),对外暴露 HTTP 接口,业务后端去调用它。这跟上面 Node 服务 + nginx 的模型一模一样------模型服务就是一个躲在代理后面的 1314。
2. MCP / Agent 工具链:每个工具都可以容器化
我理解的 Agent 是 LLM + Harness(tool + mcp + rag + skill...)。这些 tool、MCP server,本质上是独立的服务。把它们各自容器化,就能独立升级、独立扩容、独立部署------今天升级某个工具,不影响主服务,就像船上一个集装箱的货物损坏,不影响其他集装箱。
3. RAG 基础设施:Redis + MySQL + 向量库
一个 RAG 应用背后挂着缓存(Redis)、业务数据(MySQL)、向量数据库。我在笔记里用 Docker 装 mysql 时第一次体会到:

bash
docker exec -it mysql-demo /bin/bash # 进入容器
mysql -uroot -p123456 # 连上 mysql
create database blog; # 建库
这些"数据库服务"完全不需要在我自己的电脑上装任何东西------拉个镜像、起个容器就完事。我笔记本上干干净净,却能同时跑 MySQL、Redis、Postgres 好多个版本。这就是隔离的价值。
4. 环境一致性的终极方案
AI 领域的环境地狱比普通后端更夸张:CUDA 版本、Python 版本、推理框架(PyTorch / vLLM / llama.cpp)......每个人的机器都不一样,同一个 prompt 在不同环境可能跑出不同结果。Docker 把整个运行环境(包括 GPU 驱动依赖、CUDA 版本)锁进镜像,开发和生产的每一步都在同一个"集装箱"里,从根上消灭"在我电脑上是好的"。
八、下一步计划
学完 Docker 基础,我的路线图是这样的:
- 补全 Docker 实践 :用
docker-compose.yml一次性编排 Node + Redis + MySQL + 一个模型服务,搭出"类生产"的本地 AI 后端。 - 写一个真正的 AI 应用后端:基于 NodeJS(我的主力后端框架)实现一个带 RAG 的服务,把模型服务、向量库、Redis 缓存都容器化跑起来。
- 深入 MCP 与 Agent 服务化:把自研的工具封装成 MCP server,用 Docker 部署,体验"可插拔工具链"的后端形态。
- 理解 GPU 容器与生产部署:研究模型服务在带 GPU 的容器里怎么跑、怎么扩容,为将来上生产做准备。
九、结语
回过头看,Docker 教给我的第一课不是某个命令,而是一种思维:把一个复杂系统拆成一堆互不干扰、又能协作的"集装箱"。
这个思维模型,恰好和我做 AI Agent 时理解的东西同构------Agent 是 LLM + Harness,Docker 是 应用 + 环境,都是"核心 + 配套装载"的整体打包。而 AI 应用后端,说到底就是把这些集装箱合理编排、让它们协作运转。
从一杯咖啡的功夫写下一个返回 hello world 的 Node 服务,到把 nginx 反代、mysql、redis 一个个容器化跑起来------路还很长,但方向越来越清晰了。
我们搬进集装箱的,不只是代码,还有未来每一个 AI 应用赖以生存的基础设施。