Dockerize your JS app
$ whoami
Інна Іващук
Senior Software Engineer
JS developer, music fan, movie-dependent and Star Wars fan 🤓
May the Force be with you!
-
Хмарні провайдери і контейнери
-
Що таке Docker? Базове використання
-
Мережа Docker
-
Запуск JS додатку у Docker контейнері
-
docker-compose
-
Kahoot time
-
Q&A
Agenda
Вже доводилось стикались із Docker?
Docker vs NodeJS в Google Trends
Web Development
Docker
+
Можлива ситуація на проекті
Requested changes
Use new API for authentication
Login
Що необхідно зробити?
- локально налаштовуємо і установлюємо все необхідне (Java, Gradle, Maven, Mongo, PostgreSQL and etc)
- вносимо зміни в JavaScript файлику
- перевіряємо наші зміни, використовуючи локально розвернуту API
- і нарешті - commit & push
Можлива ситуація
- Зміни розгорнуто/опубліковано (deployed/published)
- QAs починають валідацію, але виявляється, що наші зміни працюють не так, як очукувалось
Як це можна зробити
- Встановити Docker
- Викачати останню версію бекенд сервіса з Docker реєстру
- Запустити все локально
- Внести зміни і перевірити все локально
- Profit 🤩
Так і з'явився Docker
Хмари та контейнери
Що таке хмарні технології?
Хмарна система або технологія хмарних обчислень відноситься до обчислювальних компонентів (апаратне забезпечення, програмне забезпечення та інфраструктура), які забезпечують надання послуг хмарних обчислень, таких як SaaS (програмне забезпечення як послуга), PaaS (платформа як послуга) та IaaS (інфраструктура) як послуга) через мережу (тобто Інтернет).
Які хмарні технології або сервіси використовуєте?
Магія хмарних технологій
Microsoft змогла опублікувати супутникові фотознімки Bing Maps на 2,5 петабайта за допомогою машинного навчання Azure для побудови віртуального світу Flight Simulator. Можна сказати, це справді хмара, яка оживляє гру. Azure також допомагає моделювати погоду в режимі реального часу.
Хмарні провайдери
Сучасна SDLC з CI/CD, контейнерами, оркестраторами та хмарами
Хмарні провайдери і контейнери
Deploy
Deploy
Deploy
Deploy
Що таке Docker?
Docker
Docker - це відкрита платформа для розробки, доставки та запуску додатків.
- дозволяє відокремити ваші програми від інфраструктури, щоб мати змогу швидко доставити програмне забезпечення
- дозволяє керувати своєю інфраструктурою так само, як і своїми додатками
- дозволяє швидко доставити, протестувати та розгорнути код
- дозволяє значно зменшити затримку між написанням коду та запуском його у виробництво
Контейнери та віртуальні машини (VM)
Контейнер запускається в Linux і спільно використовує ядро хост-машини з іншими контейнерами. Він запускає дискретний процес, не займаючи більше пам'яті, ніж будь-який інший виконуваний файл, роблячи його легким.
На відміну від цього, віртуальна машина (VM) запускає повноцінну “гостьову” операційну систему з віртуальним доступом до ресурсів хосту через гіпервізор. Взагалі, віртуальні машини несуть багато накладних витрат, окрім того, що витрачається логікою вашого додатка.
Docker та підтримка ОС
Docker Engine доступний на різних платформах Linux, macOS та Windows 10 через Docker Desktop та у вигляді статичної двійкової інсталяції. Знайдіть бажану операційну систему нижче.
Docker Engine
Docker Engine - це клієнт-серверна програма з 3 основними компонентами:
-
server - це тип довготривалої програми, що називається daemon процесом (команда dockerd)
-
REST API - визначає інтерфейси, які програми можуть використовувати для комунікації з daemon та вказівок щодо того, що робити
-
command-line interface (CLI) - клієнт (docker команди)
Архітектура Docker 🐳
Docker використовує архітектуру клієнт-сервер.
- Docker daemon (dockerd) слідкує за Docker API запитами та керує Docker , такими як зображення, контейнери, мережі та томи. Daemon також може спілкуватися з іншими daemon для управління послугами Docker
- Docker client (docker) - основний спосіб взаємодії багатьох користувачів Docker з Docker. Команда docker використовує Docker API
- Docker registry - зберігає образи (image) Docker. Може бути загальнодоступною або приватною
Docker об'єкт - IMAGE (образ)
IMAGE (образ) - це шаблон лише для читання з інструкціями щодо створення контейнера Docker. Часто образ базується на іншомих, з деякими додатковими налаштуваннями.
Щоб створити власний образ потрібно створити Dockerfile з для визначення кроків, необхідних для створення образу та його запуску. Кожна інструкція в Dockerfile створює шар у зображенні. Коли ви змінюєте файл Docker і перебудовуєте образ, перебудовуються лише ті шари, які змінилися.
Docker об'єкти - CONTAINERS (контейнери)
Container - це запущений екземпляр образу (image). Ми можемо створювати, запускати, зупиняти, переміщувати або видаляти контейнер за допомогою Docker API або CLI. Можна підключити контейнер до однієї або декількох мереж, приєднати до нього сховище або навіть створити новий образ на основі його поточного стану.
Контейнер визначається його образами (images), а також будь-якими параметрами конфігурації, які надаються йому під час створення або запуску.
Docker об'єкти - CONTAINERS (контейнери)
File system
environment config
application image
Container
Docker архітектура: Docker об'єкти
Services дозволяють масштабувати контейнери за допомогою декількох Docker deamons, які працюють разом у "swarm" з кількома менеджерами та працівниками. Кожен член "swarm" є демоном Docker, і всі демони спілкуються за допомогою API Docker. Послуга дозволяє визначити бажаний стан, наприклад кількість копій служби, яка повинна бути доступна в будь-який момент часу.
Docker Swarm vs. Kubernetes
Docker Swarm переваги:
- накладання мереж
- балансування навантаження
- висока доступність та кілька функцій для масштабовання
Docker Swarm недоліки:
- власні засоби моніторингу
- API Docker обмежує функціональність
- для зручного управління інтерфейсом потрібен сторонній інструмент, такий як Portainer.io
Docker Volumes
- легше створити резервну копію або перенести, ніж прив'язувати монтування
- можна керувати за допомогою команд Docker CLI або Docker API
- працює як на контейнерах Linux, так і на Windows
- можна безпечніше розподілити між кількома контейнерами
- дозволяють зберігати томи на віддалених хостах або хмарних постачальниках, шифрувати вміст томів або додавати інші функції
вміст нових томів може бути попередньо заповнений контейнером - Docker Desktop має набагато вищу продуктивність, ніж монтування прив'язки з хостів Mac і Windows
Список основних Docker команд
$ docker run – запускає команду в новому контейнері
$ docker start – запускає або декілька зупинених контейнерів
$ docker stop – зупиняє один або декілька запущених контейнерів
$ docker build – будує образ (image), використовуючи Dockerfile
$ docker pull – витягує образ (image) з Docker реєстру
$ docker push – публікація образу (image) в Docker реєстру
$ docker ps - список контейнерів
$ docker images - список образів (images)
$ docker exec – виконати команду в run-time контейнера
$ docker search – пошук образу в Docker Hub
$ docker stats – відображати в реальному часі статистику використання ресурсів контейнерами
Повний список доступних команд можна знайти тут - Docker документація
$ docker stop $(docker ps -a -q) – зупинити всі контейнери
$ docker rm $(docker ps -a -q) – видалити всі зупинені контейнери
$ docker rm container-id – видалити контери по ID
$ docker rmi $(docker images -q) – видалити всі образи (images)
$ docker rmi image-id – видалити образ (image) по ID
Корисні Docker команди
Мережа Docker
Огляд мереж
Однією з причин, чому контейнери та служби Docker настільки потужні, є те, що існує можливість з'єднати їх разом або підключити до робочих навантажень, що не належать Docker. Контейнери та служби Docker навіть не повинні знати, що вони розгорнуті на Docker, чи їх "peers" також є робочим навантаженням Docker чи ні.
Незалежно від того, чи працюють ваші хости Docker під управлінням Linux, Windows або їх поєднання, ви можете використовувати Docker для управління ними за допомогою платформного агностику.
Мережеві драйвери
Мережеву підсистему Docker можна підключити за допомогою драйверів. Кілька драйверів існують за замовчуванням і забезпечують базову функціональність мережі:
bridge
host
overlay
macvlan
none
Мережевий драйвер: Bridge
172.18.0.1
172.18.0.2
172.18.0.3
Мережевий драйвер: Host
Docker host
port:8080
Мережевий драйвер: Overlay
Docker host 1
Docker host 2
Мережевий драйвер: macvlan
Docker host
LAN
Підсумок
- bridge мережі найкраще підходять, коли для спілкування на одному хості між декількома контейнерами
- host мережі найкраще підходять, коли мережевий стек не повинен бути ізольований від хоста Docker, але ви хочете, щоб інші аспекти контейнера були ізольованими
- overlay мережі найкращі, коли вам потрібні контейнери, що працюють на різних хостах Docker для спілкування, або коли декілька програм працюють разом, використовуючи служби swarm
- macvlan мережі найкраще підходять, коли потрібна установка VM або потрібно, щоб контейнери виглядати як фізичні хости у вашій мережі, кожен з яких має унікальну MAC-адресу
- і ще одне - third-party мережеві плагіни дозволяють виконати інтеграцію Docker із специфічним мережевим стеком
Деталі мережі
- NETWORK ID — ідентифікатор мережі, який присвоюється під час створення
- NAME — ім'я мережі, можна налаштувати
- DRIVER — драйвер використаний при створенні
- SCOPE — місце, де використовується
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
6df045e07b11 bridge bridge local
9d45c14e604a host host local
b285e48f2c94 none null local
Щоб перевірити детальну інформацію по мережі:
Створення мережі
$ docker network create bridge-network
Існує декілька варіантів:
- найпростіший спосіб
$ docker network create --driver=bridge bridge-network
- приклад з використанням overlay драйвера
$ docker network create -d overlay my-multihost-network
$ docker network create --driver overlay overlay_network
$ docker network create -d macvlan \
> --subnet=172.16.86.0/24 \
> --gateway=172.16.86.1 \
> -o parent=eth0 \
> my-macvlan-net
- macvlan створення
Час запустити наш додаток, використовуючи Docker
Dockerfile
Необхідно створити Dockerfile в директорії нашого додатку
FROM mhart/alpine-node:14
# Create app directory
WORKDIR /usr/src/app
# A wildcard is used to ensure both package.json
# AND package-lock.json are copied
COPY package*.json ./
# Install app dependencies
RUN yarn
# Bundle app source
COPY . .
# Build the app
RUN yarn build
EXPOSE 8080
# run CMD command "yarn start:prod"
CMD [ "node", "dist/main.js" ]
.dockerignore
Додати .dockerignore файл в тій же директорії
node_modules
npm-debug.log
Тепер можна створити образ (image)
Потрібно перейти до каталогу, в якому є знаходиться Dockerfile, і виконати наступну команду для створення образу (image) Docker. Прапорець -t дозволяє позначити образ, щоб його було легше знайти пізніше за допомогою команди docker images:
docker build -t myapp/nest-user-service .
Тепер образ (image) буде достпний для Docker:
$ docker images
# Example
REPOSITORY TAG ID CREATED
node 12 1934b0b038d1 5 days ago
myapp/user-service latest d64d3505b0d2 1 minute ago
Запуск образу (image)
Запуск обазу за допомогою -d, запускає контейнер у від'єднаному режимі, залишаючи контейнер працюючим у фоновому режимі. Прапорець -p переспрямовує загальнодоступний порт до приватного порту всередині контейнера. Можна запустити раніше створений образ:
docker run -p 3030:8080 -d myapp/nest-user-service
Виведемо деталі нашого додатка:
# Get container ID
$ docker ps
# Print app output
$ docker logs <container id>
# Example
Running on http://localhost:8080
Перевірка контейнерів
Щоб протестувати свою програму, потрібно отримати порт нашого додатку, який Docker надав:
$ docker ps
# Example
ID IMAGE COMMAND ... PORTS
ecce33b30ebf myapp/nest-user-service:latest npm start ... 3030->8080
У наведеному вище прикладі Docker виконав меппінг порту 8080 всередині контейнера на порт 3030 на даній машині.
А як нарахунок інших сервісів або MondoDB?
docker-compose допоможе нам з цією задачею
docker-compose
Що таке docker-compose?
Compose - це інструмент для визначення та запуску багатоконтейнерних програм Docker.
Використовуючи docker-compose, з допомогою YAML файлів можна виконати налаштування додатку. Потім за допомогою однієї команди створити та запустити всі сервіси з використанням конфігурації.
Працює у будь-якому середовищі: production, staging, development, testing, а також робочі процеси CI.
Використання docker-compose це буквально три кроки:
-
Визначте середовище додатку за допомогою Dockerfile, щоб його можна було відтворювати де завгодно
-
Визначте сервіси, з яких складається додаток, у docker-compose.yml, щоб їх можна було запускати разом в ізольованому середовищі
-
Виконати docker-compose up, щоб запустити всі сервіси додатоку
Крок 1: Створити Dockerfile
На цьому кроці конфігуруємо Dockerfile, який створює образ Docker. Образ буде містити всі залежності, яких необхідні для JS додатку, включаючи NodeJS.
FROM node:14
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
# A wildcard is used to ensure both package.json
# AND package-lock.json are copied
COPY package*.json ./
RUN yarn
# Bundle app source
COPY . .
RUN yarn build
EXPOSE 8080
CMD [ "yarn", "start:prod" ]
Крок 2: Налаштувати сервіси у docker-compose.yml файлі
Створити файл docker-compose.yml в директорії проекту:
version: '3.3'
services:
user-api:
container_name: nest-user-service
restart: always
build: .
ports:
- '8080:3000'
links:
- mongo
mongo:
container_name: mongo
image: mongo
ports:
- '27017:27017'
Даний файл конфігурує два сервіса: user-api і mongo:
- user-api сервіс використовує образ, створений з використанням Dockerfile в даній директорії. Потім він прив’язує контейнер і хост машину до відкритого порту - 8080
- mongo сервіс використовує публічний Mongo образ (image), викачаний з реєстру Docker Hub
Крок 3: Створити і запустити додаток
З директорії проекту запустити програму, з допомогою команди:
Тепер можна перейти на http://localhost:8080/ в браузері, для того щоб перевірити чи додаток працює.
І для того, щоб перевірити доступні образи(image):
$ docker-compose up
docker image ls
Крок 5: Відредагувати compose файл та додати змінні середовища (env. vars.)
version: '3.3'
services:
user-api:
container_name: nest-user-service
restart: always
build: .
ports:
- '8080:3000'
links:
- mongo
environment:
- PORT=3000
- DATABASE_URL=mongodb://mongo:27017/users
mongo:
container_name: mongo
image: mongo
ports:
- '27017:27017'
Just do it
Популярне питання - "Як перебудувати тільки один сервіс?"
$ docker-compose up -d --force-recreate --no-deps --build user-api
Kahoot time
Q & A
Налаштований CI/CD - GitHub Actions
Dockerize your JS app
By Inna Ivashchuk
Dockerize your JS app
Docker & docker-compose
- 632