手记

docker-compose 实用示例

简单来说, docker compose就是一键启动/关闭多个容器的工具, 它能够帮你解决容器之间依赖的问题, 哪个先启动, 依赖哪个容器等.

当开发的系统越来越复杂, 开发环境和部署都没那么简单的时候, 可以试试docker compose.

下面会把我实际经验中的一个例子简化出来,一步步教大家如何搭建docker compose,对踩过的坑进行总结,希望对docker能有更深的了解.

1. 搭建环境背景

以我目前在做的一个用python开发的web应用为例, 需要搭建一个依赖mysql, localstack, presto, celery, python flask等多项docker容器.

2. 配置文件

通过官网的介绍, 创建docker-compose.yml, 配置上面提到的几个services.

version: '3'services:
  mysql:
    # mysql 镜像
    image: registry.docker-cn.com/library/mysql:latest    environment:
      # 初始化mysql环境变量
      MYSQL_DATABASE: test      MYSQL_ROOT_PASSWORD: "123456"
    # 暴露端口号
    ports:
      - "3306:3306"

  localstack:
    image: atlassianlabs/localstack:latest    environment:
      # localstack主要是为了模拟aws s3, 方便单元测试
      AWS_ACCESS_KEY_ID: unit-test-user      AWS_SECRET_ACCESS_KEY: unit-test-user      AWS_DEFAULT_REGION: cn-north-1
      AWS_DEFAULT_OUTPUT: text      SERVICES: s3    ports:
      - "4572:4572"

  presto:
    # presto在我的另外一篇文章中有写如何制作镜像 https://www.jianshu.com/p/bb5181008cd7
    image: presto:v0.180
    ports:
      - "8888:8888"

  web:
    # 这个镜像可以根据代码中依赖的包进行build, 节省每次安装的时间
    image: python-web-base:v0.1
    command: bash /base/sbin/docker_compose_web_entrypoint.sh    # 暴露端口号, 成功启动之后可以通过 http://localhost:8081 进行访问
    ports:
      - "8081:8081"
    # 环境变量的设置
    environment:
      S3_PORT: 4572
      S3_HOST: localstack      AWS_ACCESS_KEY_ID: unit-test-user      AWS_SECRET_ACCESS_KEY: unit-test-user      AWS_DEFAULT_REGION: cn-north-1
      AWS_DEFAULT_OUTPUT: text      # 在docker-compose中, 想要在web service中访问
      # mysql, localstack or presto, 需要给一个hostname, 
      # hostname跟service name一致.
      PRESTO_HOST: presto      MYSQL_HOST: mysql      MYSQL_DATABASE: test      MYSQL_ROOT_PASSWORD: "123456"

    depends_on:
      - mysql
      - localstack
      - presto    volumes:#   code base
      - .:/base#   query result shared volume: /tmp/
      - /tmp:/tmp

  celery:
    image: python-web-base:v0.1
    command: bash /base/sbin/docker_compose_celery_entrypoint.sh    environment:
      C_FORCE_ROOT: "true"

      PRESTO_HOST: presto      MYSQL_HOST: mysql      MYSQL_DATABASE: test      MYSQL_ROOT_PASSWORD: "123456"

      AWS_ACCESS_KEY_ID: unit-test-user      AWS_SECRET_ACCESS_KEY: unit-test-user      AWS_DEFAULT_REGION: cn-north-1
      AWS_DEFAULT_OUTPUT: text    depends_on:
      - mysql
      - presto
      - localstack    volumes:#   code base
      - .:/base#   query result shared volume: /tmp/
      - /tmp:/tmp

完整的代码我放到了github中 https://github.com/yamyamyuo/docker/tree/master/docker-compose

3. 遇到的坑

3.1 host name问题

配置mysql的时候由于不知道docker-compose中网络通信是怎么样的, 就用localhost:3306 或者127.0.0.1:3306去连mysql, 总是报错, 无法连接该mysql. 发现原来在docker-compose环境下, 不管是mysql还是其他servers如presto, 想要连接这些服务, 都要用这些服务的名字进行连接. 如下所示

version: '3'services:
  mysql:
    ...
  presto:
    ...
  localstack:
    ...

可以连接的服务的名称分别为mysql, prestolocalstack. 于是我在环境变量中export这些HOST name, 方便我在程序中去判断是否存在这些环境变量, 如果有的话就连接这个hostname.

3.2 服务启动的先后顺序

当mysql还没有成功启动, celery会一直报错, 并不断地重复连接mysql, 于是我想设置这些服务的启动先后顺序, 用了docker compose的 depens_on, 但是depens_on只是表达服务之间的依赖关系, 并不会按照次序来启动service.

depends_on does not wait for db and redis to be “ready” before starting web - only until they have been started. If you need to wait for a service to be ready, see Controlling startup order for more on this problem and strategies for solving it.

看来如果想让web或者celery服务等mysql启动完毕后再启动, 需要一个wait-for-it脚本的帮忙. 这个人写的脚本还比较清晰简单的: https://github.com/yamyamyuo/wait-for-it
可以在command添加一个脚本, 脚本中使用wait-for-it去轮询依赖的services, 一旦services启动成功, web 和 celery就可以继续进行启动了.

3.3 暴露端口号

服务对外暴露的端口号不要忘记填写, 否则其他docker container无法找到该服务. 注意事项:
当通过HOST:CONTAINER 格式来映射端口号的时候, 低于60的端口号会有错误提示, 因为YAML解析格式例如 xx:yy的数字是基于base-60的. 因此强烈建议用双引号把 "HOST:CONTAINER" 括起来.

3.4 volumes

为了能够持久化和共享容器中的数据, Docker提出了volume的概念. Volume可以让容器中的联合文件系统, 以目录或文件的形式存于宿主机上.
我最初遇到的一个问题是celery service 通过异步的方式执行一些任务, 任务结束后会把结果写到本地文件, web service 查询的时候会到本地文件中查看是否有相关结果. 这个时候volume排上用场. 只要把容器内用到的文件地址映射到宿主机, 同时让webcelery service 都共享该volume即可.

以上就是本次docker compose遇到的一些问题, 如有问题可以留言~



作者:小熊说_BruinTalk
链接:https://www.jianshu.com/p/46db38b94200

0人推荐
随时随地看视频
慕课网APP