跳到主要内容

Docker Compose 基本使用

· 阅读需 5 分钟

我们安装 docker 之后,便会启动很多容器服务,但对应这些容器如何统一编排,网络组管理,启动顺序,挂载数据卷,成为了问题,于是 docker 团队开发了 docker-compose 组件来便于我们编排容器。

为什么需要编排

单个容器用 docker run 就能起,但真实的应用很少只有一个容器:一个 Web 服务往往还带着数据库、缓存、消息队列。这些容器之间有依赖关系,需要在同一个网络里互相访问,还各自要挂载数据卷。如果全靠手敲 docker run,参数一长就没人记得住,换台机器重新部署更是折磨。

docker-compose 解决的就是这个问题:把所有容器的启动参数固化成一份 YAML 文件,纳入版本管理,任何人拿到文件就能一条命令复现整套环境。

安装

开源项目地址:

https://github.com/docker/compose

从项目的 Releases 页面下载对应系统架构的二进制文件即可,安装分两步。

1、下载文件后上传至服务器 /usr/local/bin 文件夹。

放在 /usr/local/bin 是因为这个目录默认在 PATH 里,放进去之后在任意路径下都能直接敲 docker-compose 命令。

2、添加文件执行权限

# 赋予可执行权限,否则 shell 会提示 Permission denied
sudo chmod +x /usr/local/bin/docker-compose

装完可以执行 docker-compose version 验证一下,能打印出版本信息就说明装好了。

工作机制

docker-compose 只是一个二进制文件,可以直接运行在 linux 系统上,通过docker-compose 可以使用 yaml 文件来配置应用程序需要的所有容器。然后使用一个命令 docker-compose up -d,就可以从 yaml 文件配置中创建并启动所有服务。

它本身并不是另一套容器引擎,底层做的事和手动 docker run 完全一样——解析 YAML 之后调用 docker 的 API 去创建网络、卷和容器。几个关键机制:

1)项目(project):compose 默认以 yaml 文件所在目录名作为项目名,同一项目下创建的容器、网络、卷都会带上这个前缀,互相隔离。

2)默认网络up 的时候会自动创建一个桥接网络,把文件里定义的所有服务放进去。同一网络内的容器可以直接用服务名当主机名互相访问,不需要关心容器 IP。

3)声明式管理:再次执行 up 时,compose 会对比 yaml 和当前容器的状态,只重建有变化的服务,没变的原地不动。

一份典型的 docker-compose.yml 大致长这样:

version: "3"
services:
web:
image: nginx # 使用的镜像
ports:
- "80:80" # 宿主机端口:容器端口
volumes:
- ./html:/usr/share/nginx/html # 挂载数据卷
depends_on:
- app # 声明启动顺序:先起 app 再起 web
app:
build: ./app # 也可以从 Dockerfile 现场构建
restart: always # 容器异常退出时自动拉起

常用命令

以下命令都需要在 docker-compose.yml 所在目录下执行,或者用 -f 指定文件路径。

常用命令:

docker-compose up [启动容器 带 -d 后台启动]

docker-compose stop [停止容器]

docker-compose ps [查看当前所有编排服务]

docker-compose logs -f --tail=500 <容器Name> [查看容器实时日志]

docker-compose restart [重启容器]

docker-compose rm [删除容器]

docker-compose build [打包镜像]

几个补充说明:

  • up 不带 -d 会前台运行并把所有容器日志打到当前终端,调试时很方便,按 Ctrl+C 即停止;日常部署基本都是 up -d
  • logs--tail=500 表示只看最后 500 行再开始跟踪,不加的话历史日志全刷出来,日志量大时终端会卡很久。
  • stop 只停容器不删除,rm 删除的是已停止的容器;如果想一次性停止并删除容器和网络,用 docker-compose down
  • 改了 Dockerfile 之后直接 up -d 不会重新构建镜像,要么先 buildup,要么直接 up -d --build

踩坑与注意

1)修改 yaml 后记得重新 up:改完配置只 restart 是不生效的,restart 只是重启旧容器;要让新配置落地必须再执行一次 up -d,让 compose 重建有变化的容器。

2)depends_on 只管启动顺序:它保证容器按顺序启动,但不保证依赖的服务真正就绪。比如数据库容器起来了、进程还没接受连接,应用这时去连就会报错,应用侧要有重连逻辑。

3)数据卷用相对路径时注意执行目录:yaml 里的相对路径是相对于 yaml 文件位置解析的,换目录执行时最好用 -f 显式指定文件,避免挂错位置。

注意

docker-compose down 加上 -v 参数会连同数据卷一起删除,对有状态服务(数据库等)执行前务必确认卷里的数据可以丢弃。

小结

docker-compose 本质上是把一堆 docker run 参数固化成一份可版本管理的 YAML:一条 up -d 起整套服务,logspsrestart 覆盖日常运维。单机环境下它已经足够顺手,等服务规模大到需要多机调度时,再考虑 Kubernetes 这类编排系统也不迟。

评论 / COMMENTS