Расширение локального файла Dockerfile

Я пытаюсь основать 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?

Ответ 2

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

Я предлагаю прочитать Руководство пользователя, в котором объясняется, как работать с изображениями и контейнерами

Ответ 3

Для этого я написал простой сценарий 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

Ответ 4

Я использую условные выражения:

Dockerfile

Установите 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 \
  .

Docker Compose

version: "3.7"

services:

  app:
    build:
      context: .
      args:
        APP_ENVIRONMENT: "${APP_ENVIRONMENT:-local}"