扩展本地Dockerfile
我正在尝试将一个扩展本地Dockerfile,docker,Docker,我正在尝试将一个Dockerfile建立在另一个本地文件的基础上 $ ls -lR total 0 -rw-r--r-- 1 me me 42 14 avr 10:42 Dockerfile drwxr-xr-x 3 me me 42 14 avr 10:42 prod ./prod: total 0 -rw-r--r-- 1 me me 42 14 avr 10:42 Dockerfile $ cat prod/Dockerfil
Dockerfile
建立在另一个本地文件的基础上
$ ls -lR
total 0
-rw-r--r-- 1 me me 42 14 avr 10:42 Dockerfile
drwxr-xr-x 3 me me 42 14 avr 10:42 prod
./prod:
total 0
-rw-r--r-- 1 me me 42 14 avr 10:42 Dockerfile
$ cat prod/Dockerfile
FROM ../Dockerfile
...
$ docker build - < prod/Dockerfile
$ls-lR
总数0
-rw-r--r--1 me me 42 14 avr 10:42 Dockerfile
drwxr-xr-x 3 me 42 14 avr 10:42产品
/产品:
总数0
-rw-r--r--1 me me 42 14 avr 10:42 Dockerfile
$cat prod/Dockerfile
来自../Dockerfile
...
$docker构建-
无法处理Dockerfile:无法分析存储库信息:存储库名称组件必须匹配“a-z0-9(?:[。]a-z0-9)*”
我知道,中的需要图像,而不是路径
如何从prod/Dockerfile
扩展Dockerfile
?Dockerfile不扩展Dockerfile而是图像,from
行的不是“include”语句
因此,如果要“扩展”另一个Dockerfile,则需要将原始Dockerfile构建为映像,并扩展该映像
比如,
Dockerfile1:
FROM alpine
RUN echo "foo" > /bar
Dockerfile2:
FROM myimage
RUN echo "bar" > /baz
构建第一个Dockerfile(因为它被称为Dockerfile1
,使用-f
选项作为docker默认查找名为Dockerfile
)的文件,并将其标记为myimage
docker build -f Dockerfile1 -t myimage .
# Sending build context to Docker daemon 3.072 kB
# Step 1 : FROM alpine
# ---> d7a513a663c1
# Step 2 : RUN echo "foo" > /bar
# ---> Running in d3a3e5a18594
# ---> a42129418da3
# Removing intermediate container d3a3e5a18594
# Successfully built a42129418da3
然后构建第二个Dockerfile,它扩展了刚刚构建的映像。我们将生成的图像标记为“myextendedimage”
要检查结果,请从图像运行容器,并验证两个文件(/bar
和/baz
)都在图像中
docker run -it --rm myextendedimage sh -c "ls -la ba*"
# -rw-r--r-- 1 root root 4 Apr 14 10:18 bar
# -rw-r--r-- 1 root root 4 Apr 14 10:19 baz
我建议阅读,它解释了如何使用图像和容器我为此编写了简单的bash脚本。它的工作方式如下:
示例结构:
|
|_Dockerfile(base)
|_prod
|_Dockerfile(extended)
Dockerfile(扩展):
运行脚本:
./script.sh prod
它将基本dockerfile与扩展和生成合并文件合并。
脚本:
#/bin/bash
fromLine=$(头-n 1$1/Dockerfile)
read-一个fromLineArray重新排序器
码头工人
docker构建-
看看多阶段构建,它可以帮助您
我使用的是条件句:
Dockerfile
仅在本地版本上安装
sudo
建造
#生产
码头工人建造\
-这不是我的形象\
--构建arg应用程序\u环境='prod'\
.
#本地的
码头工人建造\
-这不是我的形象\
.
Docker Compose
如果使用Docker 20.10+,则可以执行以下操作:
# syntax = edrevo/dockerfile-plus
INCLUDE+ ../Dockerfile
RUN ...
INCLUDE+
指令由Dockerfile中的第一行导入。您可以在上阅读有关dockerfile plus的更多信息,谢谢,我知道
中的需要图像,而不是dockerfile
路径(正如我在问题中所说的)。我想知道如何扩展Dockerfile
以提高环境配置的可维护性。但我现在有了我的答案:不,你不能:)哦,孩子,哈哈,在你的问题中完全错过了这一点;是的,这是不可能的(至少目前不可能),除非你使用一个外部工具/脚本来完成这项工作。是的,我开始考虑保持我的Dockerfiles不变,并用于我的不同环境。这取决于你需要改变什么;在大多数情况下,配置不应该是映像的一部分,而是在运行时传递的内容(通过环境变量、绑定装载配置文件或类似confd的内容)。在某些情况下,你可能想要建立一个不同的形象;还可以考虑使用构建时参数(ARG
),这对配置docker环境很有用。要配置docker环境,请使用docker compose
。它旨在构建多容器系统,但也提供了一种配置环境变量等的简单方法。如果需要为每个容器自定义配置文件,请使用卷来存储配置文件,或者在容器启动时添加bash脚本来配置您的环境。这是一个想法,我会给它一个tryDockerfile不应该扩展dockerfile而是图片@Auzias是关于精确扩展dockerfile的问题。我同意这是个坏主意,因为它使层缓存变得无用。我的脚本只是合并了两个DockerFile。我只是证明了这是可能的。缓存仍然应该被使用,因为它是基于文件的内容(将是相同的)哪个文件的内容?在我看来,多阶段构建太具体了,采取了错误的方式:它允许在大多数情况下需要附加指令时,将指令预先附加到Dockerfile。一般来说,这将更为通用,以允许类似于“来自xxx的<代码>作为我的\u容器”
,并进一步在“来自我的\u容器的<代码>文件中”
,以便可以单独处理指令。
./script.sh prod
#!/bin/bash
fromLine=$(head -n 1 $1/Dockerfile)
read -a fromLineArray <<< $fromLine
extPath=${fromLineArray[1]}
tail -n +2 "$1/Dockerfile" > strippedDocker
cat $1/$extPath strippedDocker > resDocker
rm strippedDocker
docker build - < resDocker
rm resDocker
FROM ubuntu:latest
ARG APP_ENVIRONMENT=local
RUN apt-get update && bash -c "set -ex ; \
apt-get install -y $([ ${APP_ENVIRONMENT} = local ] \
&& echo 'curl sudo' \
|| echo 'curl' \
)"
CMD bash -c "set -ex ; \
[ ${APP_ENVIRONMENT} = local ] \
&& { app debug ; exit $? ; } \
|| { app start ; exit $? ; } \
"
version: "3.7"
services:
app:
build:
context: .
args:
APP_ENVIRONMENT: "${APP_ENVIRONMENT:-local}"
# syntax = edrevo/dockerfile-plus
INCLUDE+ ../Dockerfile
RUN ...