Zademy

Docker 和 Docker Compose 完整指南:命令和最佳实践

Docker; DevOps; 容器; 指南; CLI
words 字

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 Hubdocker 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 编排策略,或者深入镜像优化,进一步压缩镜像大小和启动时间。