容器启动后如何在docker-compose中使用表达式中的值设置环境变量

时间:2019-01-11 12:18:42

标签: docker docker-compose

我有这样的docker-compose.yml:

version: '3'
services:
  php-fpm:
    command: php-fpm --allow-to-run-as-root
    restart: always
    links:
      - postgresql
    build: ./php
    ports:
      - '9090:9000'
    volumes:
      - ../../:/var/www/html/
      - ./php/config/php.ini:/usr/local/etc/php/php.ini
    networks:
      - backend

我想用php-fpm容器的ip将环境变量设置为相同的容器。例如,如果我致电

docker exec -it php-fpm /bin/sh export ALLOWED_ID 

我看到我的容器172.21.0.4的动态IP地址(例如)

我尝试将以下代码添加到Dockerfile:

RUN export ALLOWED_ID=$(ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1')

但是当我进入容器时它不起作用。

我尝试将sh命令添加到docker-compose命令部分,如下所示:

command: php-fpm --allow-to-run-as-root && export ALLOWED_ID=<some expression>

但这不是正确的语法。我还阅读了docker-compose文件中的入口点部分,但我不了解它的工作方式以及如何保留此“ php-fpm --allow-to-run-as-root”代码。

2 个答案:

答案 0 :(得分:0)

需要知道容器的Docker内部IP地址是非常不寻常的。 Docker提供了一个内部DNS服务,其中每个Docker Compose块的名称都解析为该IP地址。您可以像平常一样使用诸如php-fpmpostgresql之类的块名称作为主机名(没有links:块;我建议根据一般原理将其删除)。

当Docker启动时,如果容器具有入口点,它将运行入口点(仅),并将命令(如果有)作为命令行参数传递给它。因此,如果您确实需要进行这样的初次设置,那么一条非常典型的路径是将一个入口点编写为Shell脚本,以设置环境变量,然后运行给出的命令。在您的情况下,该脚本可能看起来像

#!/bin/sh
export ALLOWED_ID=$(ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1')
exec "$@"

(假设ifconfig已安装在您的容器中;通常存在,特别是在基于Debian / Ubuntu的映像上,但实际上很少使用。)

在Dockerfile中,在应用程序代码中COPY的同一位置,在此入口点脚本中也进行COPY,并将其设置为映像的默认入口点(请小心使用方括号形式)。

...
COPY . /var/www/html
COPY entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]
CMD ["php-fpm", "--allow-to-run-as-root"]

(因为此模式非常有用,所以我倾向于建议默认情况下将主容器进程作为CMD运行,这样,如果确实需要添加ENTRYPOINT包装器,则不必重新设计所有内容。)

答案 1 :(得分:0)

我找到了解决方法:

COPY entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]
ENV ALLOWED_IP=${ALLOWED_IP}

和entrypoint.sh

#!/bin/sh
set -e
export ALLOWED_IP="$(hostname -i)"
exec "$@"

然后如果我运行容器

docker-compose run --rm php-fpm env

我看到带有容器ip的ALLOWED_IP变量