Docker 入门路线
Docker 用来把应用和运行环境一起打包。它让应用不再强依赖某台机器已经安装了什么,而是通过镜像描述“运行这个应用需要哪些文件、依赖、启动命令和端口”。
一句话理解:镜像像安装包,容器像安装包启动后的进程。
这只是入门类比。真正深入学习时要继续阅读 Docker容器运行底层原理,理解容器为什么是宿主机进程、namespace与cgroup分别做什么、镜像层如何通过OverlayFS合并,以及 docker run 如何经过daemon、containerd、shim和runc创建应用进程。
Docker 解决什么问题
| 没有 Docker 时 | 使用 Docker 后 |
|---|---|
| 每台机器都要手动装 JDK、Node、MySQL 等环境 | 环境写进镜像或 Compose 文件 |
| 本地、测试、生产环境差异大 | 镜像版本一致,运行方式一致 |
| 新人搭环境耗时 | 执行几条命令即可启动依赖 |
| 应用和依赖混在服务器上 | 每个服务运行在独立容器中 |
| 发布缺少版本记录 | 镜像 tag 可以对应发布版本 |
核心概念
| 概念 | 说明 | 类比 |
|---|---|---|
| Image | 镜像,包含应用文件和运行环境 | 程序安装包 |
| Container | 容器,镜像启动后的实例 | 正在运行的程序 |
| Dockerfile | 构建镜像的脚本 | 安装说明书 |
| Registry | 镜像仓库 | Maven 仓库、npm 仓库 |
| Volume | 数据卷,把数据保存到容器外 | 外接硬盘 |
| Network | 容器网络,让容器之间通信 | 局域网 |
| Compose | 多容器编排文件 | 一键启动脚本 |
从镜像到容器
flowchart TD
A["Dockerfile"] --> B["docker build"]
B --> C["Image 镜像"]
C --> D["docker run"]
D --> E["Container 容器"]
E --> F["应用进程"]
E --> G["端口映射"]
E --> H["数据卷挂载"]理解这张图后,很多命令就不再难记:
docker build:根据 Dockerfile 构建镜像。docker images:查看本地镜像。docker run:用镜像启动容器。docker ps:查看运行中的容器。docker logs:查看容器日志。docker exec:进入容器内部执行命令。
第一个容器:启动 Nginx
docker run -d --name my-nginx -p 8080:80 nginx:latest参数解释:
| 参数 | 含义 |
|---|---|
-d | 后台运行 |
--name my-nginx | 给容器起名,方便后续操作 |
-p 8080:80 | 把宿主机 8080 端口映射到容器 80 端口 |
nginx:latest | 使用的镜像名称和版本 |
访问 http://localhost:8080 能看到 Nginx 页面,说明容器已经工作。
常用查看命令:
docker ps
docker logs my-nginx
docker stop my-nginx
docker rm my-nginxDockerfile 入门
下面是一个 Spring Boot 应用的最小 Dockerfile:
FROM eclipse-temurin:17-jre
WORKDIR /app
COPY target/app.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]逐行解释:
| 指令 | 说明 |
|---|---|
FROM | 选择基础镜像,这里表示容器里已经有 JDK 17 运行环境 |
WORKDIR | 设置容器内工作目录 |
COPY | 把本地 jar 复制进镜像 |
EXPOSE | 声明应用使用 8080 端口 |
ENTRYPOINT | 容器启动时执行的命令 |
构建和运行:
docker build -t demo-app:1.0.0 .
docker run -d --name demo-app -p 8080:8080 demo-app:1.0.0端口映射
容器内部端口默认只在容器网络里可见。要让宿主机访问,需要做端口映射。
docker run -p 宿主机端口:容器端口 镜像名例如:
docker run -p 3307:3306 mysql:8表示访问宿主机的 3307,实际会转发到容器内 MySQL 的 3306。
数据卷挂载
容器删除后,容器内部写入的数据通常也会丢失。数据库、上传文件、配置文件这类数据要挂载到容器外。
docker run -d --name mysql8 \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-v mysql-data:/var/lib/mysql \
mysql:8这里的 mysql-data 是 Docker 管理的数据卷,容器删除后数据卷仍然存在。
Docker Compose 入门
当一个项目需要 MySQL、Redis、后端服务一起启动时,单独写多条 docker run 会很乱。Compose 用一个 YAML 文件描述多个容器。
services:
redis:
image: redis:7
ports:
- "6379:6379"
mysql:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: demo
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
volumes:
mysql-data:启动:
docker compose up -d
docker compose ps
docker compose logs -f
docker compose down常见问题
| 现象 | 可能原因 | 排查命令 |
|---|---|---|
| 访问不到容器 | 端口没有映射或端口写反 | docker ps |
| 容器启动后退出 | 启动命令报错、配置缺失 | docker logs 容器名 |
| 数据丢失 | 没有挂载 volume | docker volume ls |
| 镜像很大 | 基础镜像过大、复制了无关文件 | 查看 Dockerfile 和 .dockerignore |
| 容器间无法访问 | 网络不同或服务名写错 | docker network ls |
学习路线
flowchart TD
A["会运行现成镜像"] --> B["理解端口映射"]
B --> C["理解数据卷"]
C --> D["能写 Dockerfile"]
D --> E["能用 Compose 启动依赖"]
E --> F["能查看日志和进入容器排障"]
F --> G["把镜像用于 CI/CD 或 K8s"]练习
- 用 Docker 启动 Redis,并用本地客户端连接。
- 用 Docker 启动 MySQL,删除容器后重新启动,验证数据是否还在。
- 给一个简单 Spring Boot 或 Node 项目写 Dockerfile。
- 写一个
docker-compose.yml,同时启动 MySQL 和 Redis。 - 故意把应用端口写错,通过
docker ps和docker logs找到问题。
小结
Docker 入门要抓住四条主线:镜像负责打包,容器负责运行,端口负责访问,数据卷负责持久化。掌握这些之后,再学习 Dockerfile、Compose、镜像仓库和 Kubernetes,整体理解会顺畅很多。
下一步不要停在最小示例:进入 Dockerfile 从构建原理到生产镜像,完整学习构建上下文、镜像层与缓存、CMD/ENTRYPOINT、JDK 8/17、多阶段构建、非 root 权限、密钥和生产排查。
当需要同时启动应用、MySQL 和 Redis 时,继续进入 Docker Compose 从项目模型到商业编排,学习变量插值、生命周期、健康依赖、服务发现、Volume、Secret、多文件覆盖和故障排查,而不是只记住 up -d。
所有操作命令统一回到 Docker命令从对象模型到生产操作 学习,重点掌握对象生命周期、输出判读和删除边界,不使用无条件删除全部容器、镜像或卷的速查命令。
继续学习:
