基础 / 已完成
Docker 入门到进阶
先理解镜像、容器、Compose 和运行环境。
返回学习路线Docker 可以先理解成一个“标准盒子”。
一个程序要跑起来,通常不只需要代码,还需要 Node.js、Python、数据库、配置文件等环境。Docker 做的事就是:把这些东西尽量装进同一个盒子里。盒子拿到别的电脑或服务器上,只要那里有 Docker,就能用差不多一样的方式跑起来。
一句话:
> Docker = 把程序和运行环境打包进标准盒子。
目录
- 一、用奶茶机理解 Docker
- 二、Docker 解决什么问题
- 三、Docker 和虚拟机的区别
- 四、核心概念
- 五、基础命令
- 六、写一个 Dockerfile
- 七、Docker Compose
- 八、容器之间怎么访问
- 九、进阶重点
- 十、常见问题
- 十一、命令速查
- 十二、学习顺序
---
一、用奶茶机理解 Docker

假设你会做一杯奶茶。
传统做法是:你告诉朋友买什么茶叶、用多少水、珍珠煮几分钟、糖放多少。朋友照着做,但味道可能还是不一样。
Docker 的做法是:你直接给朋友一台“小奶茶机”。茶叶、杯子、温度、步骤都放好了。朋友只要启动机器,就能做出差不多一样的奶茶。
程序也是这样。
没有 Docker 时,别人电脑上可能缺 Node.js、缺依赖、数据库版本不对。
有 Docker 后,我们把程序需要的环境一起打包,减少“我电脑能跑,你电脑不能跑”的问题。
二、Docker 解决什么问题
Docker 主要解决“环境不一致”。
常见问题:
- 你电脑是 Node.js 20,服务器是 Node.js 16
- 你装了某个依赖,别人没装
- 本地能连数据库,服务器连不上
- 新同事配置项目要花很久
- 上线时环境和开发环境不一样
Docker 的价值:
- 快速启动项目
- 减少环境配置问题
- 让开发和部署更接近
- 方便同时管理前端、后端、数据库、Redis 等服务
三、Docker 和虚拟机的区别
虚拟机像“重新造一整套房子”,里面有完整操作系统,比较重。
Docker 容器像“在大楼里隔出一个房间”,更轻,启动更快。
| 对比 | 虚拟机 | Docker 容器 |
|---|---|---|
| 像什么 | 一整套房子 | 一个独立房间 |
| 启动 | 慢 | 快 |
| 体积 | 大 | 小 |
| 适合 | 模拟完整电脑 | 运行应用 |
记住:Docker 不是完整电脑,它主要用来运行应用。
四、核心概念
1. 镜像 Image
镜像就是“模板”。
比如:
nginx:网页服务器模板mysql:8:MySQL 8 模板redis:7:Redis 7 模板
大白话:
> 镜像 = 菜谱,还没有真正开火做菜。
常用命令:
docker images
docker pull nginx
docker pull mysql:8
2. 容器 Container
容器就是镜像真正跑起来后的东西。
大白话:
> 容器 = 按菜谱做出来的那盘菜。
一个镜像可以启动多个容器。
docker run nginx
docker ps
docker ps -a
3. Dockerfile
Dockerfile 是“制作镜像的说明书”。
它告诉 Docker:
- 从哪个基础环境开始
- 把哪些代码复制进去
- 安装哪些依赖
- 启动时运行什么命令
4. Docker Hub
Docker Hub 是“镜像超市”。
很多常用镜像别人已经做好了,比如 Nginx、MySQL、Redis。我们可以直接下载使用。
5. 端口 Port
容器里跑了网站,外面默认访问不到。要用端口映射给它开门。
docker run -d -p 8080:80 nginx
意思是:
本机 8080 端口 -> 容器 80 端口
访问:
http://localhost:8080
6. 数据卷 Volume
容器可以删除,但数据库数据不能随便丢。
Volume 就像“容器外面的保险柜”,用来保存重要数据。
docker volume create mysql-data
docker run -d \
--name mysql-demo \
-e MYSQL_ROOT_PASSWORD=123456 \
-v mysql-data:/var/lib/mysql \
mysql:8
五、基础命令
1. 检查 Docker
docker version
docker info
如果报错连接不到 Docker,通常是 Docker Desktop 没启动。
2. 运行测试容器
docker run hello-world
能看到欢迎信息,说明 Docker 基本可用。
3. 启动 Nginx 网站
docker run -d -p 8080:80 --name my-nginx nginx
然后打开:
http://localhost:8080
参数解释:
-d 后台运行
-p 8080:80 端口映射
--name my-nginx 给容器起名字
nginx 使用 nginx 镜像
4. 管理容器
docker ps
docker ps -a
docker stop my-nginx
docker start my-nginx
docker restart my-nginx
docker rm my-nginx
5. 查看日志和进入容器
docker logs -f my-nginx
docker exec -it my-nginx sh
退出容器:
exit
六、写一个 Dockerfile
假设有一个 Node.js 项目:
my-app/
package.json
server.js
Dockerfile
.dockerignore
server.js:
const http = require("http");
http.createServer((req, res) => {
res.end("Hello Docker");
}).listen(3000);
package.json:
{
"scripts": {
"start": "node server.js"
}
}
Dockerfile:
FROM node:20
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
大白话解释:
FROM node:20 从 Node.js 20 环境开始
WORKDIR /app 进入 /app 文件夹
COPY package*.json 先复制依赖说明
RUN npm install 安装依赖
COPY . . 复制项目代码
EXPOSE 3000 说明服务使用 3000 端口
CMD npm start 启动项目
.dockerignore:
node_modules
.git
.env
.DS_Store
dist
构建镜像:
docker build -t my-node-app .
运行容器:
docker run -d -p 3000:3000 --name node-demo my-node-app
访问:
http://localhost:3000
Dockerfile 顺序为什么重要
推荐先复制 package.json,再安装依赖,最后复制代码:
COPY package*.json ./
RUN npm install
COPY . .
因为代码经常改,依赖不经常改。这样 Docker 可以复用缓存,构建更快。
七、Docker Compose
真实项目经常不止一个容器。
比如:
- 后端
- MySQL
- Redis
- Nginx
一个个 docker run 很麻烦。Docker Compose 可以用一个文件统一管理。
docker-compose.yml:
services:
app:
build: .
ports:
- "3000:3000"
environment:
DB_HOST: mysql
DB_USER: root
DB_PASSWORD: 123456
DB_NAME: demo
depends_on:
- mysql
mysql:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: demo
volumes:
- mysql-data:/var/lib/mysql
ports:
- "3306:3306"
volumes:
mysql-data:
启动:
docker compose up -d
查看日志:
docker compose logs -f
停止:
docker compose down
重新构建并启动:
docker compose up -d --build
大白话:
> Compose = 多个容器的总开关。
八、容器之间怎么访问
在 Docker Compose 里,容器之间用“服务名”访问。
例如:
services:
app:
mysql:
app 访问数据库时,数据库地址应该写:
mysql
不要写:
localhost
原因很简单:在容器里,localhost 指的是容器自己,不是另一个容器。
正确例子:
mysql://root:123456@mysql:3306/demo
九、进阶重点
1. 环境变量
不要把密码、端口、数据库地址全部写死在代码里。
单容器:
docker run -e NODE_ENV=production -e PORT=3000 my-node-app
Compose:
services:
app:
environment:
NODE_ENV: production
PORT: 3000
2. 生产镜像要小
开发时镜像大一点没关系,生产环境最好更小、更干净。
可以用轻量镜像:
FROM node:20-alpine
3. 多阶段构建
前端项目常用这种方式:
FROM node:20 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx
COPY --from=builder /app/dist /usr/share/nginx/html
大白话:
第一步:用 Node.js 打包
第二步:只把打包结果放进 Nginx
这样最终镜像更干净。
十、常见问题
1. Docker 命令连接不上
一般是 Docker Desktop 没启动。
docker info
2. 端口被占用
查端口:
lsof -i :8080
也可以换端口:
docker run -d -p 8081:80 nginx
3. 容器启动后马上退出
看日志:
docker logs 容器名
Compose 项目:
docker compose logs -f
4. 数据会不会丢
只放容器里,删除容器可能会丢。
用了 volume,数据会保存在容器外面,更安全。
5. Docker 占磁盘太多
查看:
docker system df
清理:
docker system prune
更彻底:
docker system prune -a
清理前要确认没有重要镜像或容器。
十一、命令速查
镜像:
docker images
docker pull nginx
docker rmi nginx
docker build -t my-app .
容器:
docker ps
docker ps -a
docker run -d -p 8080:80 --name my-nginx nginx
docker stop my-nginx
docker start my-nginx
docker restart my-nginx
docker rm my-nginx
docker logs -f my-nginx
docker exec -it my-nginx sh
数据卷:
docker volume ls
docker volume create my-data
docker volume rm my-data
Compose:
docker compose up -d
docker compose up -d --build
docker compose down
docker compose ps
docker compose logs -f
docker compose restart
清理:
docker system df
docker system prune
docker system prune -a
十二、学习顺序
建议按这个顺序学:
- 明白 Docker 是“标准盒子”
- 分清镜像和容器
- 学会
docker run、docker ps、docker logs - 学会端口映射
-p - 学会数据卷
-v - 学会写 Dockerfile
- 学会 Docker Compose
- 搞懂容器之间用服务名访问
- 再看环境变量、镜像瘦身、多阶段构建
最后记住这张表:
| 名词 | 小学生版理解 |
|---|---|
| 镜像 | 模板、菜谱 |
| 容器 | 跑起来的程序盒子 |
| Dockerfile | 做镜像的说明书 |
| Docker Hub | 镜像超市 |
| 端口 | 给容器开门 |
| Volume | 数据保险柜 |
| Compose | 多个容器的总开关 |
Docker 的重点不是背命令,而是理解:
> 它把程序需要的东西装进盒子,让程序换地方也更容易跑起来。