Ответ 1
Взгляните на сборки multi-stage
, которые могут вам помочь
Я пытаюсь основать 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
не удалось обработать файл Docker: невозможно разобрать информацию о репозитории: компонент имени репозитория должен соответствовать "a-z0-9 (?: [._] a-z0-9) *"
Я знаю, что FROM
ожидает изображение, а не путь.
Как я могу расширить Dockerfile
из prod/Dockerfile
?
Взгляните на сборки multi-stage
, которые могут вам помочь
Dockerfiles не расширяют Dockerfiles, но изображения, строка FROM
не является выражением "include".
Итак, если вы хотите "расширить" другой файл Docker, вам нужно создать оригинальный файл Docker в качестве изображения и расширить его.
Например;
Dockerfile1:
FROM alpine
RUN echo "foo" > /bar
Dockerfile2:
FROM myimage
RUN echo "bar" > /baz
Создайте первый файл Docker (так как он называется Dockerfile1
, используйте параметр -f
качестве параметров -f
по умолчанию для поиска файла под названием Dockerfile
), а "tag" - как 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";
docker build -f Dockerfile2 -t myextendedimage .
# Sending build context to Docker daemon 3.072 kB
# Step 1 : FROM myimage
# ---> a42129418da3
# Step 2 : RUN echo "bar" > /baz
# ---> Running in 609ae35fe135
# ---> 4ea44560d4b7
# Removing intermediate container 609ae35fe135
# Successfully built 4ea44560d4b7
Чтобы проверить результаты, запустите контейнер из изображения и убедитесь, что оба файла (/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 (расширенный):
FROM ../Dockerfile
...
Запустить скрипт:
./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
Я использую условные выражения:
Установите sudo
только для локальной сборки.
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 $? ; } \
"
# Production
docker build \
-t my-image \
--build-arg APP_ENVIRONMENT='prod' \
.
# Local
docker build \
-t my-image \
.
version: "3.7"
services:
app:
build:
context: .
args:
APP_ENVIRONMENT: "${APP_ENVIRONMENT:-local}"