Docker 学习系列6 Docker Compose 中的环境变量使用注意事项

学习技能光看不做是不行的,强烈推荐按照教程敲一遍
https://docs.docker.com/compose/gettingstarted/

Compose项目由 Python编写 ,实现上调用了 Docker服务提供的 API来对容器进行管理。 因此只要所操作的平台支持 Docker,就可以在其上利用 Compose来进行编排管理。

本人提炼出了几点技巧:

1. 多用 docker-compose config

命令校验和查看配置信息,
当修改了docker-compose.yml文件,不要急于执行docker-compose up启动,可以先检查下配置。很多时候是yml格式不规范导致的。

2. docker-compose up

docker-compose up 包含了构建镜像,创建服务,启动服务等一系列操作。一般配好文件执行这个命令就可以了。

3. 使用.env环境变量配置文件

一些敏感信息如,数据库密码等不建议写死到docker-compose.yml中,可以写在.env环境配置文件中(使用Laravel的同学对这个文件肯定不陌生)。
因为docker-compose.yml一般跟随项目受版本控制,.env可以不受版本控制。
优化前:
docker-compose.yml

  mysql:
      build: ./docker-build/mysql
      ports:
        - "33060:3306"
      volumes:
        - ./docker-build/mysql/data:/var/lib/mysql
      environment:
        MYSQL_ROOT_PASSWORD: 123456

优化后:
同级目录建立.env文件

  mysql:
      build: ./docker-build/mysql
      ports:
        - "33060:3306"
      volumes:
        - ./docker-build/mysql/data:/var/lib/mysql
      environment:
       # 先从.env找DOCKER_MYSQL_PASSPORD,找不到使用后面的默认值
        MYSQL_ROOT_PASSWORD: ${DOCKER_MYSQL_PASSPORD-123456}

.env

# define env var default value.
DOCKER_MYSQL_PASSPORD=root
4. 使用docker-compose.yml中的env_file语法

service节点下支持 env_file属性,即环境变量从额外的文件中读取。
如下面的例子,如果local.env和common.env有相同key。则下面的优先级高。

  php:
      build:
        context: ./docker-build/php
        args:
          - INSTALL_COMPOSER=${PHP_INSTALL_COMPOSER}
          - INSTALL_MONGO=${PHP_INSTALL_MONGO}
          - INSTALL_REDIS=${PHP_INSTALL_REDIS}
          - INSTALL_XDEBUG=${PHP_INSTALL_XDEBUG}
      ports:
        - "9001:9000"
      links:
        - "mysql"
      volumes:
        - .:/www
      env_file:
        - ./common.env
        - ./local.env

假设 local.env 中内容是A:1,common.env 是 A:2

      environment:
        A: 3
      env_file:
        - ./common.env
        - ./local.env

最终生效的是 A:3

5. 配置不同场景下的环境变量

我们可以把不同场景下的环境变量定义在不同的 shell 脚本中并导出,然后在执行 docker-compose 命令前先执行 source 命令把 shell 脚本中定义的环境变量导出到当前的 shell 中。通过这样的方式可以减少维护环境变量的地方,下面的例子中我们分别在 docker-compose.yml 文件所在的目录创建 test.sh 和 prod.sh,test.sh 的内容如下:

#!/bin/bash
# define env var default value.
export IMAGETAG=web:v1
export APPNAME=HelloWorld
export AUTHOR=Nick Li
export VERSION=1.0

prod.sh 的内容如下:

#!/bin/bash
# define env var default value.
export IMAGETAG=webpord:v1
export APPNAME=HelloWorldProd
export AUTHOR=Nick Li
export VERSION=1.0LTS

在测试环境下,执行下面的命令:

$ source test.sh
$ docker-compose config
image.png

此时 docker-compose.yml 中的环境变量应用的都是测试环境相关的设置。
而在生产环境下,执行下面的命令:

image.png

此时 docker-compose.yml 中的环境变量应用的都是生产环境相关的设置。

6. 环境变量的优先级

docker-compose.yml 文件中引用的环境变量,它们的优先级如下:

  • Compose file
  • Shell environment variables
  • Environment file
  • Dockerfile
  • Variable is not defined

首先,在 docker-compose.yml 文件中直接设置的值优先级是最高的。
然后是在当前 shell 中 export 的环境变量值。
接下来是在环境变量文件中定义的值。
再接下来是在 Dockerfile 中定义的值。
最后还没有找到相关的环境变量就认为该环境变量没有被定义。

额外内容,使用 extends 继承扩展docker-compose.yml

基于其他模板文件进行扩展 。 例如,我们已经有了一个 webapp 服务,定义一个基础模板文件为 common.yml,如下所示:
common.yml:

webapp
  build : . /webapp 
  environment:
    - DEBUG=false
    - SEND EMAILS=false

再编写一个新的 development .yml 文件,使用 common.yml 中的 webapp 服务进行扩展:

development .yml:

web:
  extends:
    file: common .yml
    service: webapp 
    ports :
      - "8000:8000" 
    links:
      - db environment:
      - DEBUG=true 
  db:
    image : postgres

后者会自动继承common.yml中的webapp服务及环境变量定义。 使用extends需要注意以下两点:

  • 要避免出现循环依赖,例如 A 依赖 B, B 依赖 C, C 反过来依赖 A 的情况 。
  • extends 不会继承 links 和 volumes_from 中定义的容器和数据卷资源 。 一般情况下,推荐在基础模板中只定义一些可以共享的镜像和环境变量,在扩展模板中
    具体指定应用变量、链接、数据卷等信息 。

额外内容

RUN vs CMD vs ENTRYPOINT 的区别

  1. Dockerfile中,在基础镜像上安装软件使用 RUN
  2. CMD命令是当Docker镜像被启动后Docker容器将会默认执行的命令。一个Dockerfile中只能有一个CMD命令。通过执行docker run $image $other_command启动镜像可以重载CMD命令。
  3. 使用 docker-compose run 命令可以在服务上运行一次性命令,如 docker-compose run web env 查看服务为web的环境变量
image.png

参考:

https://www.cnblogs.com/sparkdev/p/9826520.html
https://docs.docker.com/compose/reference/envvars/
https://docs.docker.com/compose/environment-variables/

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

推荐阅读更多精彩内容