Рубрики
Без рубрики

Docker Alpine + Expressjs + угловой

Докер уже существует в течение значительного времени, выпущенного на 2013 году, он направлен на решение проблемы «Но она работает на моем компьютере».

Автор оригинала: Jellene Khoh.

Это было для проекта, который я недавно провел, что потребовало приложение для приспособления отчетности, которое будет подаваться из образа докера, и будет жить внутри небольших устройств Linux Linux.

Приложение должно было выполнить эти критерии:

  1. Это должно быть быстро воспроизведено для многих устройств
  2. Это должно быть маленьким, нет большого пространства
  3. Он должен быть в состоянии подключиться к базе данных Mariadb в сети localhost
  4. Определенные поля настраиваются от базы данных JSON, которая выставляется за пределами контейнера.

Контейнер Docker, содержащий приложение Expressjs, которое служит угловым приложением

Img_20190408_153056.jpg.

Докер

1. Это должно быть быстро воспроизведено для многих устройств

Докер уже в течение значительного времени, выпущено на 2013 Он стремится решить проблему «Но она работает на моем компьютере».

Популярное использование Docker состоит в том, чтобы сопрянуть его с Kubernetes, чтобы раскрутить несколько микросервисов, чтобы обрабатывать большие шипы одновременных пользователей, а затем удалить их после накопления, чтобы сохранить ресурсы. Каждое микросервис – это крошечный сервер самостоятельно.

Поскольку Docker Images по сути, по существу, как резервная копия крошечного сервера, он всегда будет работать без особой конфигурации. Которые позволяет легко скопировать изображение на любое новое устройство, и включите новый контейнер Docker, запущенный приложение.

Архитектурное решение

  1. Используйте Docker для контейнерации приложения
  2. Expressjs служит веб-сервером для приложения Frontend углового приложения.
  3. Expressjs использует lowdb Для чтения/записи конфигураций к файлу JSON в папке под названием Data/.
  4. 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 Отказ И мое приложение может успешно подключаться к базе данных. 🎉.

giphy.gif.gif.

Объем докера

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 захватывает. Дайте мне знать, если есть лучший путь!

giphy.gif.gif.

Ресурсы

[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.