Docker Compose中如何在command指令中使用env_file定义的环境变量
我之前也碰到过类似的问题,其实这是Docker Compose处理命令和环境变量的机制导致的——默认情况下,Compose会优先尝试自己解析command里的变量,而不是把变量交给容器内部的shell去处理。所以你直接写$NODES或者${NODES},Compose会先在自身运行的环境里找这个变量,找不到就替换成空值,自然就不生效了。
给你两种靠谱的解决方案:
方案一:用容器内的shell执行命令(最推荐)
把整个命令用shell包裹起来,让容器内部的shell去读取并解析env_file里的环境变量。修改后的配置如下:
selenoid: image: "aerokube/selenoid:latest" container_name: selenoid network_mode: bridge ports: - "0.0.0.0:4444:4444" volumes: - ".:/etc/selenoid" - "./target:/output" - "/var/run/docker.sock:/var/run/docker.sock" - "./target:/opt/selenoid/video" environment: - "OVERRIDE_VIDEO_OUTPUT_DIR=$PWD/target" env_file: - variables.env command: ["/bin/sh", "-c", "selenoid -limit $NODES -enable-file-upload -conf /etc/selenoid/browsers.json -video-output-dir /opt/selenoid/video"]
核心就是用/bin/sh -c来包裹完整的selenoid启动命令,这样容器里的shell会负责解析$NODES,就能正确读取到你在variables.env里定义的数值了。
方案二:让Compose直接传递变量
如果你不想用shell执行,也可以让Compose直接读取env_file里的变量,再传递给command。这种情况下,command里要用${NODES}的写法,还可以给变量加个默认值,比如${NODES:-5}(这里的5是默认节点数,你可以改成自己需要的数值),这样就算变量没加载成功,也能有个兜底值。
修改后的command部分是这样的:
command: ["-limit", "${NODES:-5}","-enable-file-upload", "-conf", "/etc/selenoid/browsers.json", "-video-output-dir", "/opt/selenoid/video"]
不过这种方式要注意:Compose必须能读取到NODES变量——要么你的variables.env能被Compose正确加载,要么你在运行docker-compose up之前,已经把NODES变量export到当前的shell环境里了。
验证是否生效
不管用哪种方案,你都可以启动容器后,用下面的命令检查环境变量是否正确加载:
docker exec selenoid env
如果能看到NODES和你设置的数值,再用这个命令检查进程参数:
docker exec selenoid ps aux
看看selenoid进程的启动参数里,-limit后面的数值是不是你设置的NODES值就可以了。
内容的提问来源于stack exchange,提问作者Nonyck

