Docker 完全指南:容器化技术的实践之路
在软件开发领域,环境一致性问题长期困扰着开发者。“在我电脑上能运行”成为团队协作的常见痛点。Docker 的出现彻底改变了这一局面,它通过容器化技术将应用及其依赖打包成轻量级、可移植的镜像,实现了“一次构建,处处运行”的承诺。
本文将带你从零开始,在 Ubuntu 上系统学习 Docker,涵盖核心概念、安装配置、镜像管理、容器操作、自定义镜像构建、数据持久化、网络通信以及 Docker Compose 编排,助你掌握现代应用部署的核心技能。
1. Docker 是什么?
1.1 容器 vs 虚拟机
Docker 是一种容器化技术,与传统的虚拟机不同:
| 特性 | 容器(Docker) | 虚拟机(VM) |
|---|---|---|
| 启动速度 | 毫秒级 | 分钟级 |
| 资源占用 | 共享宿主机内核,轻量 | 每个 VM 包含完整操作系统,资源开销大 |
| 隔离性 | 进程级隔离 | 硬件级隔离,安全性更高 |
| 镜像大小 | MB 级别 | GB 级别 |
1.2 核心概念
- 镜像(Image):只读模板,包含应用及其运行环境。类比 OOP 中的“类”。
- 容器(Container):镜像的运行实例,可创建、启动、停止、删除。类比 OOP 中的“对象”。
- 仓库(Repository):存储和分发镜像的地方,如 Docker Hub。
- Dockerfile:描述如何构建镜像的脚本。
1.3 Docker 架构
Docker 采用 C/S 架构:
- Docker Daemon:后台守护进程,管理容器、镜像等。
- Docker Client:命令行工具,向 Daemon 发送指令。
- Registry:镜像仓库,如 Docker Hub。
2. 安装 Docker
2.1 使用官方脚本安装(推荐)
# 更新软件包索引sudo apt update
# 安装依赖sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
# 添加 Docker 官方 GPG 密钥curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 添加稳定版仓库echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装 Docker Enginesudo apt updatesudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin2.2 验证安装
sudo docker run hello-world若看到 Hello from Docker! 信息,则安装成功。
2.3 管理 Docker 服务
# 启动 Dockersudo systemctl start docker
# 设置开机自启sudo systemctl enable docker
# 查看状态sudo systemctl status docker2.4 非 root 用户使用 Docker(可选)
为避免每次使用 sudo,可将当前用户加入 docker 组:
sudo usermod -aG docker $USERnewgrp docker # 刷新组权限3. 镜像管理
3.1 镜像仓库
Docker Hub 是默认的公共镜像仓库,国内可使用镜像加速器。
配置镜像加速(以阿里云为例):
sudo mkdir -p /etc/dockersudo tee /etc/docker/daemon.json <<-'EOF'{ "registry-mirrors": ["https://your-mirror.aliyuncs.com"]}EOFsudo systemctl restart docker3.2 常用镜像命令
| 操作 | 命令 |
|---|---|
| 搜索镜像 | docker search nginx |
| 拉取镜像 | docker pull nginx:latest |
| 列出本地镜像 | docker images 或 docker image ls |
| 查看镜像详情 | docker inspect nginx |
| 删除镜像 | docker rmi nginx |
| 清理无用镜像 | docker image prune |
3.3 镜像分层与大小
Docker 镜像采用分层存储,每层都是只读的。查看镜像历史:
docker history nginx4. 容器管理
4.1 运行容器
# 运行并进入交互式容器docker run -it ubuntu:22.04 /bin/bash
# 后台运行 Nginx 容器docker run -d --name mynginx -p 80:80 nginx
# 运行一次性容器(执行完命令退出)docker run --rm alpine echo "Hello"参数说明:
-i:保持 STDIN 打开-t:分配伪终端-d:后台运行--name:指定容器名称-p:端口映射宿主机:容器--rm:容器退出后自动删除
4.2 查看容器
# 查看运行中的容器docker ps
# 查看所有容器(含停止的)docker ps -a
# 查看容器日志docker logs mynginx
# 实时跟踪日志docker logs -f mynginx4.3 停止与删除
# 停止容器docker stop mynginx
# 启动已停止的容器docker start mynginx
# 重启容器docker restart mynginx
# 删除容器(需先停止)docker rm mynginx
# 强制删除运行中的容器docker rm -f mynginx4.4 进入运行中的容器
# 使用 exec 进入(推荐)docker exec -it mynginx /bin/bash
# 使用 attach(会直接附着到主进程,退出会导致容器停止)docker attach mynginx5. 构建自定义镜像
5.1 Dockerfile 基础
Dockerfile 是一个文本文件,包含构建镜像的指令。以构建一个简单的 Python Flask 应用为例:
# 使用官方 Python 镜像作为基础FROM python:3.9-slim
# 设置工作目录WORKDIR /app
# 复制依赖文件并安装COPY requirements.txt .RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码COPY . .
# 暴露端口EXPOSE 5000
# 启动命令CMD ["python", "app.py"]5.2 常用指令
| 指令 | 说明 |
|---|---|
FROM | 指定基础镜像 |
WORKDIR | 设置工作目录 |
COPY / ADD | 复制文件到镜像(ADD 支持自动解压) |
RUN | 执行命令(构建时) |
CMD | 容器启动时执行的命令(可被覆盖) |
ENTRYPOINT | 容器启动入口(不可被覆盖) |
ENV | 设置环境变量 |
EXPOSE | 声明端口(仅文档用途) |
VOLUME | 声明数据卷 |
ARG | 构建参数 |
5.3 构建镜像
# 在 Dockerfile 所在目录执行docker build -t my-flask-app:1.0 .
# 指定不同 Dockerfiledocker build -f Dockerfile.prod -t my-app .5.4 优化建议
- 利用构建缓存:将变化少的指令(如安装依赖)放在前面
- 使用 .dockerignore:排除不需要的文件
- 减少层数:合并 RUN 命令(
&& \) - 选择合适的基础镜像:如
alpine版本体积小
6. 数据持久化
容器是短暂的,其文件系统在容器删除后会丢失。Docker 提供三种数据持久化方式:
6.1 数据卷(Volume)
由 Docker 管理,独立于容器生命周期。
# 创建数据卷docker volume create mydata
# 挂载数据卷到容器docker run -d -v mydata:/data --name app alpine tail -f /dev/null
# 查看数据卷docker volume ls
# 删除数据卷docker volume rm mydata6.2 绑定挂载(Bind Mount)
将宿主机目录挂载到容器中,便于开发调试。
docker run -d -v /host/path:/container/path nginx6.3 临时存储(tmpfs)
数据存储在内存中,容器停止后消失。
docker run -d --tmpfs /tmp alpine7. 网络通信
Docker 提供多种网络驱动,实现容器间通信及与外部网络的连接。
7.1 默认网络
- bridge:默认网络,容器通过虚拟网桥通信,外部需端口映射访问。
- host:容器使用宿主机网络栈,性能高但隔离性弱。
- none:无网络。
7.2 自定义网络
推荐使用自定义桥接网络,实现容器名解析。
# 创建自定义网络docker network create mynet
# 运行容器并加入网络docker run -d --name app1 --network mynet nginxdocker run -d --name app2 --network mynet nginx
# 在 app1 中 ping app2(通过容器名)docker exec app1 ping app27.3 端口映射
# 将容器 80 端口映射到宿主机 8080docker run -d -p 8080:80 nginx
# 映射到随机端口docker run -d -P nginx7.4 网络管理命令
# 列出网络docker network ls
# 查看网络详情docker network inspect mynet
# 断开/连接网络docker network disconnect mynet app1docker network connect mynet app18. Docker Compose
Docker Compose 用于定义和运行多容器应用,通过 YAML 文件配置服务、网络、数据卷等。
8.1 安装 Compose(已随 Docker Engine 安装)
验证:docker compose version
8.2 编写 docker-compose.yml
以 Nginx + MySQL 为例:
version: '3.8'
services: web: image: nginx:latest ports: - "80:80" volumes: - ./html:/usr/share/nginx/html networks: - app-net
db: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: secret MYSQL_DATABASE: myapp volumes: - db-data:/var/lib/mysql networks: - app-net
volumes: db-data:
networks: app-net:8.3 常用命令
# 启动所有服务(后台)docker compose up -d
# 查看日志docker compose logs -f
# 停止并删除容器、网络docker compose down
# 停止并删除数据卷docker compose down -v
# 重新构建并启动docker compose up -d --build9. 镜像仓库与分发
9.1 登录 Docker Hub
docker login9.2 标记镜像
docker tag my-app:1.0 username/my-app:1.09.3 推送镜像
docker push username/my-app:1.09.4 私有仓库
运行私有仓库:
docker run -d -p 5000:5000 --name registry registry:2推送镜像到私有仓库:
docker tag my-app localhost:5000/my-appdocker push localhost:5000/my-app10. 资源限制
为防止容器耗尽宿主机资源,可设置资源限制。
# CPU 限制(最多使用 1.5 核)docker run -d --cpus=1.5 nginx
# 内存限制(最多 512MB)docker run -d --memory=512m --memory-swap=512m nginx
# 查看容器资源使用docker stats11. 常用 Docker 命令速查
| 类别 | 命令 |
|---|---|
| 镜像 | docker images, docker pull, docker rmi, docker build |
| 容器 | docker run, docker ps, docker stop/start/restart, docker rm, docker logs, docker exec |
| 数据卷 | docker volume ls, docker volume create, docker volume rm |
| 网络 | docker network ls, docker network create, docker network inspect |
| 系统 | docker info, docker system prune, docker version |
12. 最佳实践
- 每个容器只运行一个进程:保持单一职责。
- 使用 .dockerignore:减少构建上下文,提高构建速度。
- 以非 root 用户运行:增强安全性。
- 及时清理无用资源:
docker system prune -a定期清理。 - 标签管理:为镜像打上版本标签,避免使用
latest。 - 健康检查:在 Dockerfile 中添加
HEALTHCHECK指令。 - 日志驱动:配置日志轮转,防止磁盘占满。
13. 常见问题与解决
| 问题 | 解决方法 |
|---|---|
| 权限拒绝(Permission denied) | 将用户加入 docker 组,或使用 sudo |
| 端口被占用 | 检查是否已有容器占用,或更改映射端口 |
| 容器无法访问外网 | 检查防火墙及 Docker 网络配置 |
| 镜像拉取缓慢 | 配置国内镜像加速器 |
| 数据卷权限问题 | 使用 :Z 或 :z 标志,或调整容器内用户权限 |
| 容器退出后数据丢失 | 使用数据卷或绑定挂载持久化 |
14. 总结
Docker 通过容器化技术彻底改变了应用的交付和运行方式。本文从安装配置到镜像构建、容器管理、数据持久化、网络通信和 Compose 编排,全面介绍了 Docker 的核心功能。
掌握 Docker 不仅能够解决环境一致性问题,还能极大地提升开发和运维效率。随着微服务和云原生架构的普及,Docker 已成为现代软件开发者的必备技能。
进一步学习资源:
温馨提示:在生产环境中使用 Docker 时,务必关注安全配置(如限制权限、使用私有仓库、定期扫描镜像漏洞),确保容器化应用安全稳定运行。
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时









