Как использовать образ docker для создания статических файлов для обслуживания из образа nginx?

#node.js #docker #nginx #docker-compose #yarnpkg

#node.js #docker #nginx #docker-compose #yarnpkg

Вопрос:

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

У меня есть следующие образы docker (упрощенные), которые я связываю вместе с помощью docker-compose:

  • интерфейс (a Vue.js приложение)
  • серверная часть (приложение Django)
  • nginx
  • postgres

В разработке я не использую nginx, а вместо Vue.js приложение запускается как наблюдатель yarn serve и использует Django manage.py runserver .

Что я хотел бы сделать для производства (в CI / CD):

  • создайте и отправьте бэкэнд-образ
  • создайте и отправьте образ nginx
  • создайте внешний образ с yarn build помощью command
  • получить сгенерированные файлы в контейнере nginx (через том?)
  • разверните новые образы

Проблема в том, что если я помещаю yarn build as CMD в Dockerfile, компиляция происходит при запуске контейнера, и я хочу, чтобы это было сделано на этапе сборки в CI / CD. Но если я добавлю RUN yarn build изображение, что я помещу как CMD ? И как мне получить сгенерированные статические файлы в nginx?

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

Я чувствую, что это проблема, которая была решена многими, но я не могу найти пример. Предложения приветствуются!

Ответ №1:

Создайте том в вашем файле docker-compose.yml и смонтируйте один и тот же том как в вашем интерфейсном контейнере (в пути, где находятся встроенные файлы, например dist , папка), так и в контейнере nginx (в корневом пути вашего веб-сайта). Таким образом, оба контейнера будут иметь доступ к одному и тому же тому.

А также сохраните свою yarn build команду as RUN.

Редактировать:

Контейнеры должны запускать программу или команду, чтобы их можно было классифицировать как контейнер, Чтобы их можно было запускать, останавливать и т. Д. Это сделано специально.

Если вы не планируете обслуживать из контейнера внешнего интерфейса с помощью команды, то вам следует либо удалить его как сервис (поскольку его нет) из docker-compose.yml и добавить его в качестве этапа сборки в свой nginx dockerfile, либо вы можете использовать какую-то команду, которая будет выполняться бесконечно в вашемнапример, внешний контейнер tail -f index.html . Первое решение — лучшая практика.

В вашем докер-файле nginx добавьте файл dockerfile сборки интерфейса в качестве первого этапа сборки:

 From: node as frontend-build
WORKDIR /app
RUN yarn build

From:nginx
COPY --from=frontend-build /app/dist /usr/shared/nginx/html
...
CMD ["nginx"]
  

Комментарии:

1. Что бы я тогда поставил в качестве CMD ? Я могу использовать многослойные сборки, чтобы в основном иметь образ, содержащий только скомпилированные ресурсы (в dist папке, как вы говорите), и подключить общий том к этому каталогу и nginx, но с чего бы мне запустить контейнер? Кроме того, я полагаю, что пустой том инициализируется данными, которые были в каталоге контейнера, но как мне развернуть новую версию ресурсов?

2. Я думаю, возможно, я мог бы запустить контейнер с cp помощью команды, которая копирует папку dist на общий том, перезаписывая любую предыдущую версию, и контейнер просто остановится после команды копирования.

3. Если вы ничего не обслуживаете из контейнера внешнего интерфейса, это не относится к разделу сервисов по дизайну. Вы должны использовать только те службы, которые действительно запущены. Поэтому вместо этого используйте его как многоступенчатую сборку. Я обновлю свой ответ

4. Честно говоря, я думаю, что запускать контейнер, который ничего не делает, глупо. Но, как я упоминал в своем вопросе, я не хочу связывать nginx с моей службой внешнего интерфейса, поскольку она также подключается к внутренней службе, и я не хочу путать их. Возможно, я смогу найти способ сохранить внешний интерфейс чистым и автономным для разработки и тестирования, а также вставить встроенный образ в мой докер-файл nginx для копирования ресурсов, поскольку nginx в любом случае связывает внешний интерфейс и серверную часть. Спасибо за информацию!

5. вы можете оставить службу интерфейса как есть и просто добавить этап сборки в Dockerfile nginx. Кроме того, если вы не используете nginx в разработке, вы можете переместить его из docker-compose.yml, скажем, в docker-compose.production . yml, а затем используйте цепочку файлов docker-compose для запуска производственной среды следующим образом: docker-compose -f docker-compose.yml -f docker-compose.production. yml вверх