Как я могу обойти ограничения Докера на использование символических ссылок? - PullRequest
1 голос
/ 20 мая 2019

У меня есть несколько наборов файлов, которые я хочу включить в качестве данных для веб-сервера. Некоторые из этих наборов являются статическими активы для поддержки статического сайта.

Предположим, что есть статические ресурсы для ровно двух сайтов, быть включены в качестве данных для веб-сервера. Каждый набор активов размещен в своей папке, возможно, в исходном коде (например, git) репозиторий. Они расположены по адресу:

/path/to/site1/public

и

/other/path/to/site2/public

На самом деле может быть несколько наборов таких статических активы, расположенные в разных подкаталогах папки в разных местах файловой системы.

Мне нужно установить их в образ Docker как, например, /var/www/http/site1 и /var/www/http/site2, и т. д.

Было бы очень полезно иметь хороший способ обойти Docker ограничения на использование символических ссылок без необходимость размещать эти наборы данных на веб-сервере где-то и обратитесь к их URL в Dockerfiles.

Ответы [ 2 ]

0 голосов
/ 20 мая 2019

Симлинки прекрасно работают внутри контейнеров Docker. Ограничение размещения символических ссылок в образах докеров и контейнерах заключается в том, что копируется только ссылка, а не файлы, на которые она указывает. Кроме того, внутри контейнера символическая ссылка относится к файлам и каталогам внутри файловой системы изображения / контейнера. Поэтому, чтобы использовать символические ссылки внутри контейнера, вам нужно сделать их относительно структуры каталогов, которая также будет существовать внутри контейнера. Например. если у вас есть следующее:

path1/projA/link-good -> ../projB/file
path1/projA/link-bad1 -> /host/path1/projB/file
path1/projA/link-bad2 -> ../../path2/projC/file
path1/projA/link-bad3 -> ../projD/file
path1/projB/file
path2/projC/file
path1/projD/file

И вы включаете их в свой Dockerfile с помощью:

COPY path1/projA/ /image/projA/
COPY path1/projB/ /image/projB/
COPY path2/projC/ /image/projC/

будет работать только ссылка link-good. Другие ссылки имеют следующие проблемы:

  • link-bad1 указывает на путь, который существует только на хосте, вместо него используйте относительный путь.
  • link-bad2 указывает на относительный путь, который не существует внутри изображения, потому что вы добавили каталоги как /image/proj*, поэтому внутри файловой системы изображения нет path2.
  • link-bad3 указывает на файл, который никогда не был включен в изображение, команда COPY не следует по ссылкам.
0 голосов
/ 20 мая 2019

Этот шаблон является гибким и хорошо сработал для меня.Текущий каталог в этом примере является родительским для каталога, содержащего статические ресурсы, которые находятся в папке с именем public.

В этой папке сценарий оболочки выглядит так:

#!/bin/bash

# Build a Docker image "site1-assets" with the static files.
docker build -f - --tag=site1-assets . <<EOF
FROM scratch
COPY public ./
EOF

Аналогичным образом действуйте для статических ресурсов для site2 и т. Д. Неважно, где находится каждый набор файлов, если они все находятся на одном компьютере.

Затем в любом Dockerfile, который нуждается в активахтакие строки:

FROM site1-assets as site1
COPY / /

FROM site2-assets as site2
COPY / /

# and so on.

# And now the step that uses the external files.
FROM alpine

# Some config lines here ...

# Copy in files in image "site1".
COPY from=site1 / /var/www/http/site1/
# Copy in files in image "site2".
COPY from=site2 / /var/www/http/site2/

# More config lines if needed.

CMD run-my-app args

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

Основная идея в основном такая же, как опция «поделиться базовым изображением» в https://stackoverflow.com/a/39382248/5022006,, ноболее гибкий, чем описанный там сценарий.

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