Docker 和 Docker Compose 完整指南:命令和最佳实践
Docker 和 Docker Compose 完整指南:命令和最佳实践
Docker 基本概念
Docker 用容器化解决了一个经典问题:在我机器上能跑,到你服务器上就挂了。它把应用程序连同依赖打包成自包含的单元,到哪都能跑。
核心组件
镜像(Images) 是轻量级、自包含的软件包,代码、运行时、库、配置全在里面,本质上是创建容器的模板。
容器(Containers) 是镜像的运行时实例。和宿主环境隔离,同一台机器上可以同时跑很多个。
Docker Hub 是 Docker 官方的镜像仓库,找镜像、分享镜像都在这。
Docker CLI 命令(基础)
| 任务 | CLI 命令 | 描述 |
|---|---|---|
| 镜像 | ||
| 构建镜像 | docker build -t <image_name> . | 从当前目录的 Dockerfile 构建镜像。 |
| 不使用缓存构建 | docker build -t <image_name> . --no-cache | 强制重新构建而不使用缓存。 |
| 列出镜像 | docker images | 显示所有本地镜像。 |
| 删除镜像 | docker rmi <image_name> | 删除本地镜像。 |
| 删除未使用的镜像 | docker image prune | 删除所有未使用的镜像。 |
| 发布到 Docker Hub | docker push <user>/<image_name> | 将镜像上传到 Docker Hub。 |
| 容器 | ||
| 运行容器(带名称) | docker run --name <container_name> <image_name> | 从镜像创建并运行容器。 |
| 后台运行 | docker run -d <image_name> | 在分离模式(后台)运行容器。 |
| 运行并发布端口 | docker run -p <host_port>:<container_port> <image_name> | 将容器端口映射到主机。 |
| 列出容器(运行中) | docker ps | 显示当前运行的容器。 |
| 列出所有容器(运行和停止) | docker ps --all | 显示所有容器,无论其状态如何。 |
| 启动/停止/重启 | docker start|stop|restart <container_name> | 启动或停止现有容器。docker stop 发送 SIGTERM 信号以优雅关闭。 |
| 删除容器 | docker rm <container_name> | 删除已停止的容器。 |
| 进入容器 | docker exec -it <container_name> sh | 在运行的容器内打开交互式 shell。 |
| 查看日志 | docker logs -f <container_name> | 显示并跟踪容器日志。 |
| 检查容器 | docker inspect <container_name> | 显示容器详细信息,通常为 JSON 格式。 |
| 监控资源 | docker stats | 显示运行时资源使用统计信息。 |
高级 Docker:镜像和安全最佳实践
多阶段构建
多阶段构建能让你的生产镜像又小又安全。原理很简单:用多个 FROM 指令,每个开始一个新阶段,最后只把需要的二进制文件或产物 COPY --from=<stage> 出来。开发工具和构建依赖留在构建阶段,不进最终镜像。
几个实用建议:用 FROM <image> AS <NAME> 给阶段命名,引用方便,重新排序指令也不容易出错。调试时可以 docker build --target <stage> -t hello . 只构建到某个阶段。用 BuildKit 构建器,它只处理目标阶段依赖的阶段,比传统构建器高效。
镜像和容器安全
| 实践 | 详细信息 |
|---|---|
| 基础镜像 | 使用来自可靠来源的官方或已验证镜像。从最小基础镜像开始,只包含基本依赖项以最小化漏洞。 |
| 扫描 | 定期扫描镜像和容器的已知漏洞(例如使用 Trivy 或 Docker Scout 等工具)。 |
| 权限 | 遵循最小权限原则。以非 root 用户身份运行容器。 |
| 文件系统 | 尽可能使用只读文件系统。 |
| 内容签名 | 启用Docker 内容信任(DCT)以确保只使用已签名的镜像。 |
Docker Compose(多容器应用管理)
Docker Compose 管理多容器应用。一个 YAML 文件(docker-compose.yml)定义所有服务、网络、卷,一条命令拉起整个环境。
Docker 管单个容器,Compose 协调多个容器协同工作。开发和测试环境特别适合,Web 应用加数据库加前端,一条 docker compose up 全起来。
版本方面,V1(docker-compose,带连字符)已经停更。V2 用 docker compose(空格,不带连字符),建议直接上 V2。
Compose 结构和基本命令
docker-compose.yml 文件定义结构:
# 注意:在最新的 Docker Compose 版本中,不再需要版本
# version: '3.8' # 在现代版本中可选
services:
service1: # 容器/服务定义
# 服务配置
networks:
network1: # 自定义网络配置
# 网络配置
volumes:
volume1: # 命名卷定义
# 卷配置| 任务 | CLI 命令(V2) | 描述 |
|---|---|---|
| 构建和部署 | docker compose up | 构建并运行 yml 中定义的容器。 |
| 后台部署 | docker compose up -d | 部署并将应用程序留在后台运行。 |
| 停止应用 | docker compose stop | 停止容器。 |
| 停止并删除 | docker compose down | 停止并删除服务和网络。默认不删除命名卷。 |
| 删除并删除卷 | docker compose down --volumes 或 -v | 强制删除服务、网络和命名卷。 |
| 扩展服务 | docker compose up --scale service=n | 增加特定服务的容器数量(n)。 |
| 服务状态 | docker compose ps | 显示容器的当前状态。 |
| 日志 | docker compose logs | 显示定义容器的日志。 |
持久数据管理(卷)
卷 是容器数据持久化的关键。容器停了、重启了,数据还在。
命名卷有用户定义的名字,在 yml 的 volumes 部分定义,然后挂载到服务里。绑定挂载(bind mount)把宿主机目录共享给容器,语法是 /path/on/host:/path/in/container。
| 任务 | CLI 命令(Docker,适用于 Compose 卷) |
|---|---|
| 列出卷 | docker volume ls |
| 检查卷 | docker volume inspect <volume_name> |
| 删除卷 | docker volume rm <volume_name> |
| 清理未使用的卷 | docker volume prune |
Compose 的高级生产最佳实践
密钥和环境变量管理
数据库密码、API key 这类敏感配置,绝不能和代码混在一起。
铁律:永远不要在 Dockerfile 里硬编码密钥,也别意外暴露在镜像层里。
推荐做法:把环境变量放 .env 文件,docker-compose.yml 里用 env_file: .env 引用。.env 文件一定要加进 .gitignore,运行时加载但不进版本控制。
网络和访问安全
Compose 里的容器默认内部互通。数据库的端口暴露要格外小心,生产环境最好不要把数据库端口绑定到宿主机上。进程可以声明端口,但不绑定到宿主机,需要访问时走 SSH 隧道。这样数据库就不会暴露在公网上了。
资源限制和重启
共享环境里不限制资源,一个应用跑飞能拖垮其他所有应用。
deploy: resources 下可以设 limits(最大可用量,比如 cpus: 1、memory: 1GB)和 reservations(预留的 RAM 和 CPU)。重启策略用 restart: always 确保服务器重启后应用自动拉起来,更细的配置还能定义条件(on-failure)、延迟(delay)、最大尝试次数(max_attempts)和重启时间窗口(window)。
健康检查
健康检查让 Docker 主动验证容器是否真的在正常工作,而不只是进程还活着。可以定义 interval(检测频率)、retries(失败次数阈值)、timeout(最大等待时间)和 start_period(启动宽限期)。
主机安全和一般最佳实践
跑 Docker Engine 的 Linux 服务器,安全基线要打好。
Root 登录要限制(Ubuntu Server 默认就禁了)。SSH 认证用 RSA 密钥,别用密码,ssh-keygen 生成密钥,ssh-copy-id <user>@<server> 推公钥。装上 Fail2Ban(apt install fail2ban),靠防火墙规则自动封禁暴力破解 SSH 的 IP。Docker Engine 和依赖保持更新。监控系统要到位,docker stats 看资源占用,日志要收集,崩溃和资源短缺要能自动告警。
结论
Docker 和 Docker Compose 已经是现代软件开发的标配。命令熟了、最佳实践跟上了,开发效率和生产稳定性都会有质的提升。
接下来可以看 Kubernetes 编排策略,或者深入镜像优化,进一步压缩镜像大小和启动时间。