Docker для фронтенд-разработчиков

Это краткое и простое руководство по докеру, полезное для frontend разработчиков.

Почему вам следует использовать докер?

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

Введите виртуальные машины или виртуальную машину, это позволило нам запускать несколько приложений на одних и тех же серверах. но есть недостаток. Для работы каждой виртуальной машины требовалась целая ОС. Для работы каждой ОС необходим процессор, оперативная память и т. д., а также исправления и лицензирование, что, в свою очередь, увеличивает стоимость и отказоустойчивость.

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

Но как это поможет нам, разработчикам?

Это гарантирует, что рабочая среда одинакова для всех разработчиков и всех серверов, т. е. производство, промежуточное размещение и тестирование.

Любой может настроить проект за считанные секунды, не нужно возиться с конфигурацией, устанавливать библиотеки, настраивать зависимости и т. д.

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

Давайте сделаем шаг назад, как выглядит контейнерная система физически и чем она отличается от VM.

1.1 Разница между виртуальной машиной и докером

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

Разобравшись с этим, давайте начнем.

Как использовать докер?

Для этого нам необходимо ознакомиться с определенной терминологией.

1.2 Визуализация докер-образов и докер-контейнера

Образ Docker : это исполняемый файл, который содержит урезанную версию операционной системы, а также все библиотеки и конфигурации, необходимые для запуска приложения. Он состоит из нескольких слоев, наложенных друг на друга и представленных как один объект. Образ Docker создается с использованием файла Docker , мы доберемся до этого немного позже.

Docker-контейнер: это работающий экземпляр образа docker. может быть много контейнеров, работающих из одного и того же образа докера.

Контейнеризация простого приложения Node.js

Мы попытаемся контейнеризировать очень простое приложение Node.js и создать образ:

Ваше приложение Node.js

Начнем с создания папки my-node-app ,

mkdir my-node-app  
cd my-node-app

давайте создадим простой сервер узлов index.jsи добавим туда следующий код:

//Load express module with `require` directive

var express = require('express')

var app = express()

//Define request response in root URL (/)  
app.get('/', function (req, res) {  
 res.send('Hello World!')  
})

//Launch listening server on port 8081  
app.listen(8081, function () {  
  console.log('app listening on port 8081!')  
})

и сохраните этот файл в своей my-node-appпапке.

Теперь создаем package.jsonфайл и добавляем туда следующий код:

 {

    "name": "helloworld",  
    "version": "1.0.0",  
    "description": "Dockerized node.js app",  
    "main": "index.js",  
    "author": "",  
    "license": "ISC",  
    "dependencies": {  
      "express": "^4.16.4"  
    }

 }

На этом этапе вам не нужно устанавливать Express или npm на ваш хост, потому что помните, что дескрипторы dockerfile настраивают все зависимости, библиотеки и конфигурации.

DockerFile

Давайте создадим файл docker и сохраним его внутри нашего my-node-app folder. Этот файл не имеет расширения и называется Dockerfile . Давайте продолжим и добавим следующий код в наш файл docker.

    # Dockerfile  
    FROM node:8  
    WORKDIR /app  
    COPY package.json /app  
    RUN npm install  
    COPY . /app  
    EXPOSE 8081  
    CMD node index.js

Теперь, что мы здесь делаем:

FROM node:8 — извлекает образ докера node.js из хаба докеров,WORKDIR /app-это устанавливает рабочий каталог для нашего кода в изображении, он используется всеми последующими командами, такими COPY как RUNиCMD COPY package.json /app- это копирует наш package.json из my-node-appпапки хоста в наше изображение в /appпапке.

RUN npm install — мы запускаем эту команду внутри нашего образа, чтобы установить зависимости (node_modules) для нашего приложения.

COPY . /app — мы говорим докеру скопировать наши файлы из папки my-node-app и вставить их в /appобраз докера.

EXPOSE 8081 — с помощью этой команды мы раскрываем порт контейнера. Почему этот порт? потому что наш сервер в index.js прослушивает 8081. По умолчанию контейнеры, созданные из этого образа, будут игнорировать все запросы, сделанные к нему.

Сборка образа Docker

Время для шоу. Откройте терминал, перейдите в свою папку my-node-app и введите следующую команду:

# Build a image docker build -t <image-name> <relative-path-to-your-dockerfile>

docker build -t hello-world .

Эта команда создает hello-world образ на нашем хосте.

-tиспользуется для присвоения имени нашему изображению, которое здесь — hello-world .

.— это относительный путь к файлу Docker, поскольку мы находимся в папке, которую my-node-app мы использовали точкой для обозначения пути к файлу Docker.

Вы увидите вывод в командной строке примерно такой:

    Sending build context to Docker daemon  4.096kB  
    Step 1/7 : FROM node:8  
     ---> 4f01e5319662  
    Step 2/7 : WORKDIR /app  
     ---> Using cache  
     ---> 5c173b2c7b76  
    Step 3/7 : COPY package.json /app  
     ---> Using cache  
     ---> ceb27a57f18e  
    Step 4/7 : RUN npm install  
     ---> Using cache  
     ---> c1baaf16812a  
    Step 5/7 : COPY . /app  
     ---> 4a770927e8e8  
    Step 6/7 : EXPOSE 8081  
     ---> Running in 2b3f11daff5e  
    Removing intermediate container 2b3f11daff5e  
     ---> 81a7ce14340a  
    Step 7/7 : CMD node index.js  
     ---> Running in 3791dd7f5149  
    Removing intermediate container 3791dd7f5149  
     ---> c80301fa07b2  
    Successfully built c80301fa07b2  
    Successfully tagged hello-world:latest

Как вы можете видеть, он выполнил шаги из нашего файла докера и вывел образ докера. Когда вы попробуете это в первый раз, это займет несколько минут, но в следующий раз он начнет использовать кеш и строить намного быстрее, а результат будет таким, как показано выше. Теперь попробуйте выполнить следующую команду в своем терминале, чтобы увидеть, есть ли ваше изображение или нет:

    # Get a list of images on your host 
    docker images

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

    REPOSITORY    TAG      IMAGE ID      CREATED         SIZE  
    hello-world   latest   c80301fa07b2  22 minutes ago  896MB

Запустить Docker-контейнер

Создав образы, мы можем развернуть контейнер из этого образа.

    # Default command for this is docker container run <image-name>  
    docker container run -p 4000:8081  hello-world

Эта команда используется для создания и запуска Docker-контейнера.

-p 4000:8081— это флаг публикации, он сопоставляет порт хоста 4000 с портом контейнера 8081, который мы открыли с помощью команды Exposure в файле Docker. Теперь все запросы к порту хоста 4000 будут обрабатываться портом контейнера 8081.

hello-world — это имя, которое мы дали нашему образу ранее, когда запускали команду docker-build.

Вы получите такой вывод:

    app listening on port 8081!

Если вы хотите войти в свой контейнер и подключить к нему терминал bash, вы можете запустить

    # Enter the container
    docker exec -ti <container id> /bin/bash

Чтобы проверить, запущен контейнер или нет, откройте другой терминал и введите

    docker ps

Вы должны увидеть свой работающий контейнер следующим образом

     CONTAINER ID    IMAGE        COMMAND                  CREATED    
    `<container id>`  hello-world  "/bin/sh -c 'node in…"   11 seconds ago

    STATUS              PORTS                    NAMES  
    Up 11 seconds       0.0.0.0:4000->8081/tcp   some-random-name

Это означает, что наш контейнер с идентификатором <container id>, созданным из образа hello-world, запущен, работает и прослушивает порт 8081.

Теперь наше небольшое приложение Node.js полностью контейнеризировано. Вы можете запустить http://localhost:4000/ в своем браузере и вы должны увидеть что-то вроде этого:

1.3 Контейнерное приложение Node.js

Вуаля, вы контейнеризировали свое первое приложение.