#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 вверх