【问题标题】:Dockerfile using variable built using Shell CommandDockerfile 使用使用 Shell 命令构建的变量
【发布时间】:2020-05-22 04:17:12
【问题描述】:

为了更清楚地说明目标,让我们用一个更好的例子,假设我想要一个可移植的.env 文件,它收集主机 IP 地址,然后在build 进程中使用它。 .env 文件应该在每次构建时动态生成变量,这样如果主机 IP 发生变化,构建就会调整。

我正在尝试使用我的主机操作系统版本作为 docker-compose 调用的 dockerfile 的构建变量。我也尝试将图像行注入 docker-compose 无济于事。

类似这样的:

cat .env
VER="$(cat /etc/lsb-release | grep -o 'DISTRIB_RELEASE.*' |  cut -f2- -d=)"
#VER=18.04

Dockerfile:

FROM ubuntu:${VER}

或者我把它从 dockerfile 中删除并使用了

码头工人撰写:

image: ubuntu:${VER}
build: .

但是我收到一个关于没有构建过程的错误,不确定它是否可以这样工作。知道如何将由工具构建的变量注入到这样的 docker 文件中吗? (和/或 Docker-Compose 用于未来的项目)。

更新:我尝试了以下方法,但仍然出现错误。

cat docker-compose.yaml
version: '3.7'

services:
 fileserver:
    container_name: ${CONTAINER_NAME}
    hostname: ${CONTAINER_NAME}
    privileged: true
    build:
      context: .
      args:
        VER: ${VERSION}

......

cat .env
#VERSION="$(cat /etc/lsb-release | grep -o 'DISTRIB_RELEASE.*' |  cut -f2- -d=)"
VERSION="$(cat /etc/lsb-release | grep -o 'DISTRIB_CODENAME.*' |  cut -f2- -d=)"

.......

cat Dockerfile
#ARG VER
#FROM ubuntu:${VER}
FROM ubuntu:bionic

.......

如果我使用变量取消注释 Dockerfile 中的任一行或两行,我会收到错误:

Step 1/5 : FROM ubuntu:${VER} ERROR: Service 'ubuntu' failed to build: invalid reference format

【问题讨论】:

  • 为什么不直接选择最新的 LTS 版本 FROM ubuntu:20.04?不要求容器分布与主机分布相匹配,而且每 2 年一次的主要版本之间有足够的变化,很难让你的镜像构建的其余部分正常工作。
  • (不要将build: .image: ubuntu 都放在你的docker-compose.yml 中。这将导致它用你构建的内容覆盖标准的ubuntu 图像,这将导致麻烦.)
  • @DavidMaze 我不想解释为什么。因为这是我项目的要求。我只是在寻找这个特定问题的解决方案,我最终可能会将其用于其他变量,并希望坚持手头的任务。
  • 我认为您错过了使用.env 文件。 .env 文件中包含一个 shell 命令,但这不会像您期望的那样工作。需要根据宿主机操作系统版本构建镜像吗?
  • 我不明白你的cat 行,现在我看到它将命令的结果注入到 .env 文件中的变量中,但现在这个.env 文件不是“可移植的” " 因为在另一个发行版上结果可能不同。

标签: docker docker-compose dockerfile


【解决方案1】:

ARG 是你的朋友。

Dockerfile

ARG VER=latest
FROM ubuntu:${VER}

上面的dockerfile定义了一个名为VER的构建参数,默认为latest

docker-compose.yml

version: '3'
services:
  demo:
    image: enix223/demo
    build:
      context: .
      args:
        VER: ${VERSION}

我们用环境变量VERSION替换图像构建参数VER

使用 shell 环境变量启动容器

VERSION="$(cat /etc/lsb-release | grep -o 'DISTRIB_RELEASE.*' |  cut -f2- -d=)" docker-compose up -d

使用.env文件启动容器

cat > .env << EOF
VERSION="$(cat /etc/lsb-release | grep -o 'DISTRIB_RELEASE.*' |  cut -f2- -d=)"
EOF

docker-compose up -d

【讨论】:

  • 我不想使用全局变量(使用 CLI 中的额外参数调用 docker-compose)或静态设置标签。它应该通过我在 dockerfile/docker-compose 中动态使用的常规工具生成。
  • 您可以创建包含VERSION 变量的.env 文件。 .env文件与shell环境变量作用相同。
  • 是的,但是您可以使用 ARG 将环境变量传递给您的 Dockerfile,我已经更新了我的答案以改用 .env 文件。
  • @FreeSoftwareServers 你能用你试过的代码更新这篇文章吗?
  • 除非有人告诉我一种方法来完成我想要的,否则赏金就是你的。至少使用您的方法,我不必同时编辑 Dockerfile 和 .env。我宁愿将所有变量保留在.env 文件中,对吧?!一些与docker-compose 相关,另一些与DockerFile 相关
猜你喜欢
  • 1970-01-01
  • 2017-12-21
  • 1970-01-01
  • 2014-04-24
  • 2022-01-09
  • 1970-01-01
  • 2017-10-03
  • 2017-09-07
  • 1970-01-01
相关资源
最近更新 更多