1.6 Docker Compose

1.6 Docker Compose #

docker-compose 是一个在单机环境里轻量级的容器编排工具。

在 Docker 把容器技术大众化之后,Docker 周边涌现出了数不胜数的扩展、增强产品,其中有一个名字叫 Fig 的项目。Fig 为 Docker 引入了 “容器编排” 的概念,使用 YAML 来定义容器的启动参数、先后顺序和依赖关系,让用户不再有 Docker 冗长命令行的烦恼,第一次见识到了 “声明式” 的威力。Docker 公司在 2014 年 7 月把 Fig 买了下来,集成进 Docker 内部,然后改名成了 docker-compose。

1.6.1 安装 #

docker-compose 的安装比较简单,它在 GitHub https://github.com/docker/compose 上提供了多种形式的二进制可执行文件,支持 Windows、macOS、Linux 等操作系统,也支持 x86_64、arm64 等硬件架构,可以直接下载。docker-compose 还可以安装成 docker 的插件,以子命令的形式使用,也就是docker compose(没有中间的横线),具体可以参看文档 Install the Compose plugin。建议使用传统的 docker-compose 的形式,这样兼容性更强。

sudo curl -SL https://github.com/docker/compose/releases/download/v2.17.2/docker-compose-linux-x86_64 \
  -o /usr/local/bin/docker-compose

chmod +x /usr/local/bin/docker-compose

docker-compose version

1.6.2 使用 #

docker-compose 里管理容器的核心概念是 service。service 就是一个容器化的应用程序,通常是一个后台服务,用 YAML 定义这些容器的参数和相互之间的关系。下面的这个就是私有镜像仓库 Registry 的 YAML 文件:

services:
  registry:
    image: registry
    container_name: registry
    restart: always
    ports:
      - 5000:5000

具体的 docker-compose 字段定义可以在官网 https://docs.docker.com/compose/compose-file/ 上查看。在 docker-compose 里,每个 service 都有一个自己的名字,它同时也是这个容器的唯一网络标识。可以使用命令 docker-compose up -d,同时还要用 -f 参数来指定 YAML 文件:

docker-compose -f reg-compose.yml up -d

docker-compose 在底层还是调用的 Docker,所以它启动的容器用 docker ps 也是能够看到的。不过,用 docker-compose ps 能够看到更多的信息:

docker-compose -f reg-compose.yml ps

如果想要停止应用,可以使用 docker-compose down 命令:

docker-compose -f reg-compose.yml down

1.6.3 搭建 wordpress #

第一步,定义数据库 MariaDB,环境变量可以使用字段 environment,直接定义:

services:
  mariadb:
    image: mariadb:10
    container_name: mariadb
    restart: always

    environment:
      MARIADB_DATABASE: db
      MARIADB_USER: wp
      MARIADB_PASSWORD: 123
      MARIADB_ROOT_PASSWORD: 123

第二步,定义 WordPress 网站,也使用 environment 来设置环境变量:

services:
  ...

  wordpress:
    image: wordpress:5
    container_name: wordpress
    restart: always

    environment:
      WORDPRESS_DB_HOST: mariadb  #注意这里,数据库的网络标识
      WORDPRESS_DB_USER: wp
      WORDPRESS_DB_PASSWORD: 123
      WORDPRESS_DB_NAME: db

    depends_on:
      - mariadb

因为 docker-compose 会自动把 MariaDB 的名字用做网络标识,所以在连接数据库的时候(字段 WORDPRESS_DB_HOST)就不需要手动指定 IP 地址了,直接用 service 的名字 mariadb 就可以了。

WordPress 定义里还有一个值得注意的是字段 depends_on,它用来设置容器的依赖关系,指定容器启动的先后顺序,这在编排由多个容器组成的应用的时候是一个非常便利且重要的特性。

第三步,定义 Nginx 反向代理了,docker-compose 里要加载配置必须用外部文件,无法集成进 YAML。Nginx 的配置文件在 proxy_pass 指令里不需要写 IP 地址了,直接用 WordPress 的名字就行:

server {
  listen 80;
  default_type text/html;

  location / {
      proxy_http_version 1.1;
      proxy_set_header Host $host;
      proxy_pass http://wordpress;  #注意这里,网站的网络标识
  }
}

然后就可以在 YAML 里定义 Nginx 了,加载配置文件用的是 volumes 字段:

services:
  ...

  nginx:
    image: nginx:alpine
    container_name: nginx
    hostname: nginx
    restart: always
    ports:
      - 80:80
    volumes:
      - ./wp.conf:/etc/nginx/conf.d/default.conf

    depends_on:
      - wordpress

完整的 wp-compose.yml 文件如下:

services:
  mariadb:
    image: mariadb:10
    container_name: mariadb
    restart: always

    environment:
      MARIADB_DATABASE: db
      MARIADB_USER: wp
      MARIADB_PASSWORD: 123
      MARIADB_ROOT_PASSWORD: 123

  wordpress:
    image: wordpress:5
    container_name: wordpress
    restart: always

    environment:
      WORDPRESS_DB_HOST: mariadb  #注意这里,数据库的网络标识
      WORDPRESS_DB_USER: wp
      WORDPRESS_DB_PASSWORD: 123
      WORDPRESS_DB_NAME: db

    depends_on:
      - mariadb

  nginx:
    image: nginx:alpine
    container_name: nginx
    hostname: nginx
    restart: always
    ports:
      - 80:80
    volumes:
      - ./wp.conf:/etc/nginx/conf.d/default.conf

    depends_on:
      - wordpress

用 docker-compose up -d 启动网站:

docker-compose -f wp-compose.yml up -d

启动之后,可以用 docker-compose ps 来查看状态:

可以用 docker-compose exec 来进入容器内部,验证一下这几个容器的网络标识是否工作正常:

docker-compose -f wp-compose.yml exec -it nginx sh

可以看到,分别 ping 了 mariadb 和 wordpress 这两个服务,网络都是通的,不过它的 IP 地址段用的是172.20.0.0/16,和 Docker 默认的172.17.0.0/16不一样。

当在浏览器中,直接访问 IP 地址,也是可以访问到 wordpress 服务的: