Автор оригинала: Jellene Khoh.
Это было для проекта, который я недавно провел, что потребовало приложение для приспособления отчетности, которое будет подаваться из образа докера, и будет жить внутри небольших устройств Linux Linux.
Приложение должно было выполнить эти критерии:
- Это должно быть быстро воспроизведено для многих устройств
- Это должно быть маленьким, нет большого пространства
- Он должен быть в состоянии подключиться к базе данных Mariadb в сети localhost
- Определенные поля настраиваются от базы данных JSON, которая выставляется за пределами контейнера.
Контейнер Docker, содержащий приложение Expressjs, которое служит угловым приложением
Докер
1. Это должно быть быстро воспроизведено для многих устройств
Докер уже в течение значительного времени, выпущено на 2013 Он стремится решить проблему «Но она работает на моем компьютере».
Популярное использование Docker состоит в том, чтобы сопрянуть его с Kubernetes, чтобы раскрутить несколько микросервисов, чтобы обрабатывать большие шипы одновременных пользователей, а затем удалить их после накопления, чтобы сохранить ресурсы. Каждое микросервис – это крошечный сервер самостоятельно.
Поскольку Docker Images по сути, по существу, как резервная копия крошечного сервера, он всегда будет работать без особой конфигурации. Которые позволяет легко скопировать изображение на любое новое устройство, и включите новый контейнер Docker, запущенный приложение.
Архитектурное решение
- Используйте Docker для контейнерации приложения
- Expressjs служит веб-сервером для приложения Frontend углового приложения.
- Expressjs использует lowdb Для чтения/записи конфигураций к файлу JSON в папке под названием Data/.
- Expressjs использует Knex.js Чтобы запросить базу данных SQL.
Финальная рабочая папка выглядит что-то подобное –
backend/ |- src/... |- dist/ |- server.min.js frontend/ |- src/... |- dist/ |- public/ |- main.min.js |- vendor.min.js |- index.html docker/ |- data/ |- local-db.json |- server.min.js |- package.json |- public/ |- main.min.js |- vendor.min.js |- index.html |- Dockerfile |- .dockerignore
Оба интерфейса и бэкэнда сводится к минимуму, чтобы уменьшить пространство. Содержимое минимизированного кода копируется в папку Docker так, чтобы мне было легче упаковать его в документ докера.
Express Server обслуживает общедоступную папку (угловое приложение) под корневым маршрутом. В то время как остальная часть API начинается с /API/
приставка. Это также означает, что угловой может использовать /API
При звонке http, поэтому он всегда будет вызывать что-то в том же домене.
this.http.post('/api'+ reportUrl);
Package.json от бэкэнда также включен, потому что мне нужно установить Node_Modules, необходимые для приложения ExpressJS. Вероятно, возможно как-то объединить зависимости, используя WebPack, но я был на вовремя и не расследовал дальше, как это сделать.
import * as FileAsync from 'lowdb/adapters/FileAsync'; const low = require('lowdb'); low(new FileAsync(path)).then(db => { db.defaults({ maxEntries: MAXENTRIES, configs: [] }) .write(); });
Это напишет конфигурацию JSON по умолчанию для данных/local-db.json.
Dockerfile
2. Это должно быть маленьким, нет большого пространства
Обычная практика во время разработки – это бросить все исходные файлы в контейнер Docker и запустите полный сервер Node.js для обслуживания вашего приложения. Это легкий, быстрый, безболезненный.
Но полный Node.js на сервере Debian довольно большой – почти 650 МБ с самого начала. После установки нашего приложения Expressjs и Angular пошли до 1,3 ГБ.
Так что мы решили пойти с новой Barebone OS на основе Альпийский Linux, который является огромным 50 МБ. Со всем установленным, он пришел до примерно 300 МБ. Все еще намного меньше, чем полное изображение сервера.
Полный список доступных базовых изображений узла – здесь Отказ
Barebone OS означает, что нам нужны дополнительные файлы, чтобы установить модули узлов.
FROM node:10.15.3-alpine ENV JWT_SECRET 512FF7B2EMCKAHG24C ENV BCRYPT_SALT 12 ENV PORT 8080 ENV TOKEN_EXPIRES_IN 24h WORKDIR /usr/src/app COPY . . RUN apk --no-cache add --virtual native-deps \ bash g++ gcc libgcc libstdc++ linux-headers make python && \ npm install --quiet node-gyp forever -g &&\ npm install --production --quiet EXPOSE 8080 CMD forever server.min.js 8080
Есть очень подробные Документация О том, как написать DockerFile, но по существу, Docker File аналогичен сценарию Bash, который выполняет команды в последовательности и, наконец, обслуживает приложение.
Из узла: 10.15.3-альпий
Как я выбираю изображение в качестве основы для контейнера.
Я устанавливаю переменные среды с Env
команда. Что затем можно прочитать в приложении Expressjs через Process.env
Отказ
Workdir
Выбирает текущую папку, которую я хочу использовать в контейнере. Если каталог не существует, Docker создает их.
Я включаю несколько устанавливаемых (GCC, Python и т. Д.), Требуется построен для создания узла.
А затем наконец-то служить server.min.js
с Навсегда Отказ
Навсегда – это инструмент CLI, который будет запустить сервер узла в качестве демона и не может быть случайно убит.
Docker Run.
3. Это должно быть в состоянии подключиться к базе данных MariaDB в сети localhost
Теперь приходит веселая часть – запущенная приложение. Сначала мы должны построить это.
$ docker build --tag node-app:alpine .
Docker Build читает команду из DockerFile и создает изображение.
--tag
Позволяет мне назвать Docker Image, так что легче найти его позже.
После строительства Docker Images
показывает, что я действительно построил изображение
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE node-app alpine f4ca2e0425a0 3 days ago 354MB
Теперь, чтобы запустить изображение докера
$ docker run \ --name node-app \ --network host \ --restart 'unless-stopped' \ --detach \ node-app:alpine
--name
Позвольте мне установить пользовательское имя. Если это не предусмотрено, Docker создаст имя для вас, как драгоценные гаусы или аналогичные.
--restart
сделает бегущий контейнер навсегда, если специально не остановится.
--detach
сделает его работать на заднем плане, освобождая мой терминал для других вещей. Если вы не используете это, вам понадобится 2-й терминал, чтобы остановить ваш контейнер Docker.
--network
это Ключевой вариант здесь. Одним из требований является то, что контейнер Docker должен иметь возможность подключаться к базе данных на localhost. И используя опцию хозяин
мы можем сделать это. Существуют и другие методы создания докеровских сетей и соединительных контейнеров вместе. Вы можете прочитать больше здесь Отказ
С этой командой я могу видеть, как приложение работает на localhost: 8080
Отказ И мое приложение может успешно подключаться к базе данных. 🎉.
Объем докера
4. Определенные поля настраиваются от базы данных JSON, которая выставляется за пределами контейнера.
Контейнер Docker теперь должен бежать гладко, пока не обнаружил, что локальная DB JSON на самом деле не обновляется. И я не могу контролировать конфигурацию снаружи контейнера.
Это потому, что я оставил --volume
Опция при запуске Docker, который позволяет мне установить папку докера, которая затем может быть передана между хостом и контейнером Docker. Вы можете узнать больше о постоянство данных в Docker здесь Отказ
$ docker run \ --name node-app \ --volume $(pwd)/data:/usr/src/app/data \ --network host \ --restart 'unless-stopped' \ --detach \ node-app:alpine
$ (PWD)
вставит текущий рабочий каталог в команду. Если бы я позвонил Docker из другой папки, PWD будет другим.
Здесь команда громкости устанавливает папку данных в папку данных, которая существует внутри контейнера Docker /usr/src/app/
папка. Если целевая папка не существует, --volume
создадим это для меня.
Запустите это, и теперь я могу управлять конфигами извне.
Сохранение и загрузка изображений
Теперь, когда у меня есть изображение вверх и бега. Мне нужно экспортировать изображение в формат, который я могу импортировать в разные устройства и запускать тот же экземпляр.
$ docker save -o ./node-app-image.tar node-app:alpine
Сохранить
Команда экспортирует текущее состояние изображения в тарлбол. Я убедитесь, что я не добавил какую-либо пользовательскую конфигурацию, потому что я не хочу, чтобы они были сохранены в образе.
$ docker load -i ./node-app-image.tar
Я тогда бегаю нагрузка
Команда после того, как я скачал блокнот в машину. Загрузка изображения будет включать изображение в Docker Images
Отказ А потом я делаю Беги
Команда как раньше, и она должна найти то же самое Узел-приложение: Alpine
Изображение я спас.
Мысли
Докер действительно довольно мощный. Он позволил разработчикам масштабировать приложения мгновенно и уверенно, потому что окружающая среда всегда будет точно такой же.
Тем не менее, я думаю, что документация Docker может быть немного легче иметь дело с. Существует просто такое огромное количество конфигурации для изучения, это не удивительно установка Docker – это карьера самостоятельно.
Несмотря на это, обучение Docker захватывает. Дайте мне знать, если есть лучший путь!
Ресурсы
[1] https://github.com/nodejs/Docker-node [2] https://github.com/nodejs/Docker-node/issues/282 [3] https://stackoverflow.com/questions/43316376/what-does-net-host-option-in-docker-command-really-Do [4] https://stackoverflow.com/questions/12701259/how-to-make-a-node-js-application-run.