返回博客

18 Docker 不是虚拟机,是给你的项目打包个行李箱

18 Docker 不是虚拟机,是给你的项目打包个行李箱

导语:"在我电脑上能跑"是程序员最大的谎言。Docker 就是治这个病的:把代码和环境一起打包,行李箱提到哪都能开张。

你已经会部署了:装依赖、配 Nginx、连数据库……但你很快会遇到一个经典问题:代码在你电脑上跑得好好的,放到服务器上就崩了。

版本不对、依赖缺失、路径不同——环境一换就翻车。这就是 Docker 要解决的问题。

一、问题:为什么"换个环境就崩"

你的项目不是只有代码,还有一堆环境:Python/Node 版本、各种依赖库、配置文件、系统设置。就像一道菜,不光要食材(代码),还要调料、火候、锅具(环境)。

你电脑上的"厨房"和服务器上的"厨房"不一样:

差异 举例
软件版本 本地 Python 3.12,服务器 3.8,语法不兼容
依赖库 本地装了某库,服务器没装
系统差异 Windows 和 Linux 路径、权限完全不同
配置差异 数据库地址、环境变量没同步

部署一次,配置半天—— 这就是没有 Docker 的日子。

二、Docker 怎么解决:打包行李箱

Docker 的核心思路一句话:把"代码 + 环境"打包成一个行李箱(镜像),行李箱提到哪都能开张。

  • 镜像(Image) = 行李箱:代码、运行环境、依赖、配置全部装好,开箱即用。
  • 容器(Container) = 行李箱打开后的"店铺":镜像运行起来的实例。一个镜像可以开很多个容器(开很多家店)。

和虚拟机的区别:虚拟机是"把整间厨房搬过去"(重,要装整个系统);Docker 是"只打包你需要的锅碗瓢盆"(轻,共享系统内核)。所以 Docker 启动以秒计,虚拟机以分钟计。

三、Dockerfile:打包说明书

怎么把项目装进行李箱?写一份说明书叫 Dockerfile,AI 帮你生成,但你要看懂每行:

FROM python:3.12            # 基础:用哪个"行李箱空箱"(带 Python 3.12)
WORKDIR /app                # 进去后站哪(工作目录)
COPY . .                    # 把项目文件全部装进去
RUN pip install -r requirements.txt   # 装依赖(装调料)
CMD ["python", "app.py"]    # 开箱后启动什么(开店的第一件事)

你要看懂的只有四行:FROM(基底)、COPY(装代码)、RUN(装依赖)、CMD(启动命令)。生成后让 AI 逐行解释一遍,确认没有多余或危险的步骤。

构建并运行:

docker build -t 我的项目 .     # 按说明书打包成行李箱(镜像)
docker run -p 8000:8000 我的项目  # 开箱营业,把容器 8000 端口映射到本机

四、docker-compose:一键开箱全家桶

你的项目不是孤零零一个容器——通常有应用 + 数据库 + Redis 三个"行李箱"。一个一个开太麻烦,用 docker-compose.yml 写一份"开箱清单":

services:
  app:
    build: .
    ports: ["8000:8000"]      # 应用开在 8000
    depends_on: [db, redis]   # 先开数据库和 Redis,再开应用
  db:
    image: mysql:8            # 数据库直接用官方行李箱
    environment:
      MYSQL_ROOT_PASSWORD: 改我  # 密码用环境变量管理,别写死
  redis:
    image: redis:7

然后一条命令全开:

docker compose up -d    # -d 表示后台运行

经验:docker compose up -d 就能把整套环境拉起来——这是现代部署的"一键启动",也是 AI 帮你搭环境最常用的方式。

五、常用命令速查

命令 做什么
docker ps 看正在运行的容器
docker logs 容器名 看容器日志(排查第一现场)
docker compose up -d 按清单启动全部服务
docker compose down 停止并移除全部容器
docker exec -it 容器名 bash 钻进容器里看(调试用)

六、避坑清单

  • 容器删了,数据就没了:容器是"临时的店铺",删掉后里面的一切(包括数据库数据)都消失。数据库、上传文件必须用数据卷(volume)挂载,数据存在宿主机上——这是 Docker 新手最大的坑。
  • 别随便 pull 来路不明的镜像:镜像 = 别人的行李箱,可能带私货。尽量用官方镜像(mysql、redis、python 这种,认准官方源)。
  • 端口映射冲突:-p 8000:8000 报"端口被占用",说明本机 8000 已被占——换个端口映射(如 8001:8000)即可。
  • 改了代码不生效:代码改完要重新 build(docker compose up -d --build),不是只 restart——行李箱里的内容没变,开多少家店都还是旧的。
  • AI 生成 Dockerfile 要审阅:让 AI 逐行解释,重点看有没有多余的安装、危险的命令(如清库、删除操作)、写死的密码。

总结

  • 问题:代码 + 环境才是一个完整的项目,环境差异导致"我电脑上能跑"到服务器就崩。
  • Docker:把代码和环境打包成行李箱(镜像),开箱即用(容器),轻量(不是虚拟机)。
  • Dockerfile = 打包说明书,核心四行:FROM(基底)、COPY(装代码)、RUN(装依赖)、CMD(启动命令)。
  • docker-compose = 全家桶开箱清单,docker compose up -d 一键启动应用+数据库+Redis。
  • 避坑四条:数据要挂载卷(容器删了数据不能没)、认准官方镜像、端口冲突换映射、改代码要重新 build。

10 分钟小任务:在服务器上装好 Docker(官方教程一条命令),然后跑 docker run -d -p 8080:80 nginx 试试——用浏览器访问 http://你的IP:8080,看到 Nginx 欢迎页就说明你的第一个容器开张了。下一篇,我们回到"从输入网址到看到页面"这条链路,讲透域名和 DNS。

下一篇:域名和 DNS:从用户输入网址到看到页面,中间发生了什么。