Skip to content

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多容器编排文件一键启动脚本

从镜像到容器

mermaid
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

bash
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 页面,说明容器已经工作。

常用查看命令:

bash
docker ps
docker logs my-nginx
docker stop my-nginx
docker rm my-nginx

Dockerfile 入门

下面是一个 Spring Boot 应用的最小 Dockerfile:

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容器启动时执行的命令

构建和运行:

bash
docker build -t demo-app:1.0.0 .
docker run -d --name demo-app -p 8080:8080 demo-app:1.0.0

端口映射

容器内部端口默认只在容器网络里可见。要让宿主机访问,需要做端口映射。

bash
docker run -p 宿主机端口:容器端口 镜像名

例如:

bash
docker run -p 3307:3306 mysql:8

表示访问宿主机的 3307,实际会转发到容器内 MySQL 的 3306

数据卷挂载

容器删除后,容器内部写入的数据通常也会丢失。数据库、上传文件、配置文件这类数据要挂载到容器外。

bash
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 文件描述多个容器。

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:

启动:

bash
docker compose up -d
docker compose ps
docker compose logs -f
docker compose down

常见问题

现象可能原因排查命令
访问不到容器端口没有映射或端口写反docker ps
容器启动后退出启动命令报错、配置缺失docker logs 容器名
数据丢失没有挂载 volumedocker volume ls
镜像很大基础镜像过大、复制了无关文件查看 Dockerfile 和 .dockerignore
容器间无法访问网络不同或服务名写错docker network ls

学习路线

mermaid
flowchart TD
    A["会运行现成镜像"] --> B["理解端口映射"]
    B --> C["理解数据卷"]
    C --> D["能写 Dockerfile"]
    D --> E["能用 Compose 启动依赖"]
    E --> F["能查看日志和进入容器排障"]
    F --> G["把镜像用于 CI/CD 或 K8s"]

练习

  1. 用 Docker 启动 Redis,并用本地客户端连接。
  2. 用 Docker 启动 MySQL,删除容器后重新启动,验证数据是否还在。
  3. 给一个简单 Spring Boot 或 Node 项目写 Dockerfile。
  4. 写一个 docker-compose.yml,同时启动 MySQL 和 Redis。
  5. 故意把应用端口写错,通过 docker psdocker logs 找到问题。

小结

Docker 入门要抓住四条主线:镜像负责打包,容器负责运行,端口负责访问,数据卷负责持久化。掌握这些之后,再学习 Dockerfile、Compose、镜像仓库和 Kubernetes,整体理解会顺畅很多。

下一步不要停在最小示例:进入 Dockerfile 从构建原理到生产镜像,完整学习构建上下文、镜像层与缓存、CMD/ENTRYPOINT、JDK 8/17、多阶段构建、非 root 权限、密钥和生产排查。

当需要同时启动应用、MySQL 和 Redis 时,继续进入 Docker Compose 从项目模型到商业编排,学习变量插值、生命周期、健康依赖、服务发现、Volume、Secret、多文件覆盖和故障排查,而不是只记住 up -d

所有操作命令统一回到 Docker命令从对象模型到生产操作 学习,重点掌握对象生命周期、输出判读和删除边界,不使用无条件删除全部容器、镜像或卷的速查命令。

继续学习: