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在我的另外一篇文章中有写如何制作镜像 //www.greatytc.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遇到的一些问题, 如有问题可以留言~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,647评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,690评论 2 374
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,739评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,692评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,552评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,410评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,819评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,463评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,752评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,789评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,572评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,414评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,833评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,054评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,345评论 1 254
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,810评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,016评论 2 337

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,155评论 25 707
  • Docker — 云时代的程序分发方式 要说最近一年云计算业界有什么大事件?Google Compute Engi...
    ahohoho阅读 15,490评论 15 147
  • 以下原文转载于(https://docs.docker.com/docker-for-mac/)(想找中文版的最新...
    Veekend阅读 7,532评论 0 17
  • 向来都 身俗心也俗 还好是 身硬心尚不硬 费劲 吃力 会抖 会酸 会麻 小小痛感 僵硬中还能觉知 可重新认识自己
    静轩茶香阅读 107评论 1 3
  • 对神的认识 公义的神,第4节,第8节,说按公义审判人,也就是说神不会放过任何一个罪人,任何一个,只要犯罪了都要受到...
    UncleTea阅读 1,379评论 0 0