Dockerfile COPY и RUN в один слой - PullRequest
1 голос
/ 04 июля 2019

У меня есть сценарий, использованный при подготовке изображения Docker. У меня есть это в Dockerfile:

COPY my_script /
RUN bash -c "/my_script"

Файл my_script содержит секреты, которые мне не нужны на изображении (он удаляет себя после завершения).

Проблема в том, что файл остается на изображении, несмотря на то, что он удален, потому что КОПИЯ - это отдельный слой. Мне нужно, чтобы COPY и RUN воздействовали на один и тот же слой.

Как я могу скопировать и запустить скрипт, чтобы оба действия влияли на один и тот же слой?

Ответы [ 4 ]

1 голос
/ 04 июля 2019

По состоянию на 18.09 вы можете использовать docker build --secret для использования секретной информации в процессе сборки. Секреты монтируются в среду сборки и не сохраняются в окончательном образе.

RUN --mount=type=secret,id=script,dst=/my_script \
    bash -c /my_script
$ docker build --secret id=script,src=my_script.sh

Скрипту не нужно удалять себя.

1 голос
/ 04 июля 2019

взгляните на многоэтапный :

Использовать многоэтапные сборки

В многоэтапных сборках вы используете несколько операторов FROM в своихDockerfile.Каждая инструкция FROM может использовать различную базу, и каждая из них начинает новый этап сборки.Вы можете выборочно копировать артефакты с одной стадии на другую, оставляя после себя все, что вам не нужно, в конечном изображении .Чтобы показать, как это работает, давайте адаптируем Dockerfile из предыдущего раздела для использования многоэтапных сборок.

Dockerfile:

FROM golang:1.7.3
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html  
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

FROM alpine:latest  
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]  
0 голосов
/ 04 июля 2019

Это может быть обработано BuildKit:

# syntax=docker/dockerfile:experimental
FROM ...
RUN --mount=type=bind,target=/my_script,source=my_script,rw \
    bash -c "/my_script"

Затем вы должны построить:

DOCKER_BUILDKIT=1 docker build -t my_image .

Это также звучит так, как будто вы пытаетесь ввести секреты в сборку, например, вытащить из частного репозитория git. BuildKit также позволяет указать:

# syntax=docker/dockerfile:experimental
FROM ...
RUN --mount=type=secret,target=/creds,id=cred \
    bash -c "/my_script -i /creds"

Затем вы должны построить с:

DOCKER_BUILDKIT=1 docker build -t my_image --secret id=creds,src=./creds .

При использовании обоих параметров BuildKit команда mount фактически никогда не добавляет файл в образ. Он делает файл доступным только в качестве привязки при этом единственном шаге RUN. Пока этот шаг RUN не выводит секрет в другой файл на вашем изображении, секрет никогда не вводится в изображение.

Подробнее об экспериментальном синтаксисе BuildKit см. https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md

0 голосов
/ 04 июля 2019

Я думаю, вы можете использовать обходной путь для этого:

Поместите my_script на локальный http-сервер, который, например, использует python -m SimpleHTTPServer, а затем к файлу можно получить доступ с помощью http://http_server_ip:8000/my_script

Затем в Dockerfile используйте следующее:

RUN curl http://http_server_ip:8000/my_script > /my_script && chmod +x /my_script && bash -c "/my_script"

Этот обходной путь гарантирует добавление и удаление файла в том же слое, конечно, вам может потребоваться добавить curl установить в Dockerfile.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...