Docker容器进阶使用教程:从入门到生产级部署的实战指南

引言

你已经掌握了Docker的基本命令,会拉取镜像、运行容器、构建简单的镜像。但是,当面对真实的生产环境时,你会发现容器管理远比想象中复杂。数据如何持久化?容器间如何通信?如何构建更小、更安全的镜像?如何编排多容器应用?本文将带你逐一攻克这些进阶难题,让你的容器化技能更上一层楼。

一、数据持久化:让容器数据不丢失

容器默认是临时的,当容器被删除时,其内部数据也会消失。但在实际应用中,数据库文件、日志、配置文件等需要持久保存。Docker提供了三种数据持久化方式:卷(Volumes)绑定挂载(Bind Mounts)tmpfs挂载

1.1 使用卷(Volumes)

卷是Docker推荐的数据持久化方式,由Docker管理,存储在宿主机特定目录(Linux下为/var/lib/docker/volumes/)。卷独立于容器的生命周期,多个容器可以共享同一个卷。

创建卷:

1
docker volume create mydata

挂载卷到容器:

1
docker run -d --name myapp -v mydata:/app/data myapp:latest

1.2 使用绑定挂载(Bind Mounts)

绑定挂载将宿主机上的文件或目录挂载到容器中。适合开发环境,可以实时同步代码修改。

示例:

1
docker run -d --name devapp -v /host/code:/app/code devimage

注意:绑定挂载依赖于宿主机的目录结构,可移植性较差。

1.3 使用tmpfs挂载(仅内存)

tmpfs挂载将数据存储在内存中,适合存储临时敏感数据,容器停止后数据自动清除。

示例:

1
docker run -d --name tempcache --tmpfs /app/cache:noexec,nosuid,size=64m mycache

1.4 实战:持久化MySQL数据库

1
2
3
4
5
6
7
8
9
# 创建卷
docker volume create mysql_data

# 运行MySQL容器,挂载卷到/var/lib/mysql
docker run -d --name mysql-db \
-e MYSQL_ROOT_PASSWORD=rootpass \
-v mysql_data:/var/lib/mysql \
-p 3306:3306 \
mysql:8.0

即使删除并重新创建容器,数据依然保留。

二、网络配置:容器间高效通信

Docker默认提供三种网络驱动:bridgehostnone。此外还有 overlay 用于跨主机通信。

2.1 理解默认桥接网络

启动容器时若不指定网络,默认连接到 bridge 网络。容器通过IP地址通信,但IP会变化,不推荐生产使用。

2.2 创建自定义桥接网络

自定义桥接网络提供DNS解析,容器可以通过容器名互相访问,更加稳定。

1
2
3
4
5
6
7
8
9
# 创建网络
docker network create mynet

# 运行两个容器在同一网络
docker run -d --name web --network mynet nginx
docker run -d --name db --network mynet mysql

# 从web容器中ping db容器名
docker exec web ping db

2.3 使用host网络

容器直接使用宿主机网络栈,性能好但端口冲突风险高。

1
docker run -d --name nginx-host --network host nginx

2.4 实战:搭建WordPress + MySQL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 创建网络
docker network create wpnet

# 启动MySQL
docker run -d --name wpdb \
--network wpnet \
-e MYSQL_ROOT_PASSWORD=rootpass \
-e MYSQL_DATABASE=wordpress \
mysql:8.0

# 启动WordPress,连接到同一网络
docker run -d --name wp \
--network wpnet \
-p 8080:80 \
-e WORDPRESS_DB_HOST=wpdb \
-e WORDPRESS_DB_USER=root \
-e WORDPRESS_DB_PASSWORD=rootpass \
wordpress:latest

访问 http://localhost:8080 即可安装WordPress。

三、多阶段构建:打造最小化镜像

多阶段构建允许在一个Dockerfile中使用多个 FROM 语句,每个阶段可以基于不同基础镜像,最终只将必要文件复制到最终镜像,极大减小镜像体积。

3.1 示例:构建Go应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 第一阶段:编译
FROM golang:1.20 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main .

# 第二阶段:运行
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/main .
EXPOSE 8080
CMD ["./main"]

构建镜像:

1
docker build -t mygoapp:latest .

最终镜像仅包含二进制文件和运行时依赖,体积从GB级降到几十MB。

3.2 优化技巧

  • 使用 --from 指定阶段名称。
  • 利用缓存:先复制依赖文件再下载,避免每次重新下载。
  • 选择基础镜像时,考虑 alpinescratch 等精简镜像。

四、容器编排:使用Docker Compose管理多容器应用

Docker Compose通过YAML文件定义和运行多容器应用,适合单机环境。

4.1 编写docker-compose.yml

以WordPress为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
version: '3.8'

services:
db:
image: mysql:8.0
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: wordpress
networks:
- wpnet

wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: root
WORDPRESS_DB_PASSWORD: rootpass
volumes:
- wp_data:/var/www/html
networks:
- wpnet

volumes:
db_data:
wp_data:

networks:
wpnet:

4.2 启动应用

1
docker-compose up -d

常用命令:

  • docker-compose down:停止并删除容器、网络等。
  • docker-compose logs:查看日志。
  • docker-compose ps:查看服务状态。

五、生产环境最佳实践

5.1 安全加固

  • 不使用root用户运行容器:在Dockerfile中添加 USER 指令。
  • 限制容器资源:使用 --memory--cpus 参数。
  • 使用只读根文件系统:--read-only
1
docker run -d --name secure-app --read-only --tmpfs /tmp --memory=512m --cpus=0.5 myapp

5.2 日志管理

容器日志默认输出到标准输出,使用 docker logs 查看。生产环境建议将日志发送到集中式日志系统。

1
docker run -d --name app --log-driver=fluentd --log-opt fluentd-address=localhost:24224 myapp

5.3 健康检查

Docker支持健康检查,自动重启不健康的容器。

1
2
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD curl -f http://localhost:8080/health || exit 1

或在运行容器时指定:

1
docker run --health-cmd="curl -f http://localhost:8080/health || exit 1" --health-interval=30s myapp

5.4 使用Docker Swarm或Kubernetes

对于多主机场景,考虑使用Docker Swarm(内置)或Kubernetes(更强大)。

六、总结

本文从数据持久化、网络配置、多阶段构建、容器编排到生产最佳实践,全面覆盖了Docker容器进阶使用的核心要点。掌握这些技巧,你将能够构建更可靠、更高效、更安全的容器化应用。记住,实践是掌握的关键,建议在测试环境中反复演练。如果你有任何疑问,欢迎在评论区留言,我们一起探讨。