Прежде всего, вам нужно получить Docker deamon. Если вы, как и я, пользователь macOS, то проще всего просто зайти на официальный сайт Docker https://docs.docker.com/docker-for-mac.

Если вы не являетесь пользователем macOS, вы можете выбрать один из вариантов на этой странице: https://docs.docker.com/engine/installation.

После завершения установки проверьте установку Docker, запустив:

$ docker run hello-world

Если вы видите такое сообщение, скорее всего, вы не запускали Docker:

Cannot connect to the Docker daemon. Is the docker daemon running on this host?

Запустите Docker. Если вы использовали macOS, вы можете использовать приложение с графическим интерфейсом. В противном случае CLI.

Вот как запуск Docker deamon выглядит на моей macOS:

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

Напротив, если вы видите сообщение, подобное приведенному ниже, значит, deamon запущен, и вы готовы к работе с Docker!

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
 
c04b14da8d14: Pull complete
Digest: sha256:0256e8a36e2070f7bf2d0b0763dbabdd67798512411de4cdcf9431a1feb60fd9
Status: Downloaded newer image for hello-world:latest
 
Hello from Docker!
This message shows that your installation appears to be working correctly.
 
...

Далее мы загрузим облегченную версию Linux в виде образа. Он называется альпийский. Мы получим этот образ Alpine из Docker Hub.

$ docker pull alpine

Подождите, пока изображение загрузится. Надеюсь, у вас быстрый интернет. Хорошо то, что вам нужно загрузить изображение только один раз. Он будет сохранен на вашем компьютере для использования в будущем. Давайте на самом деле проверим наличие изображения, выполнив:

$ docker images

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

Основы Docker

Во-первых, чтобы установить образ (вытащить) из Docker Hub, есть команда docker pull {name}. Вы уже использовали его для Alpine:

$ docker pull alpine

Некоторые другие изображения по именам из Docker Hub:

  • бор: Node.js v6 на основе Debian Jessie
  • argon: Node.js v4 на основе Debian Jessie
  • убунту: Ubuntu
  • redis: Redis на основе Debian Jessie
  • mongodb: MongoDB на основе Debian Wheezy

После загрузки изображения вы можете запустить его с помощью docker run {name}, например,

$ docker run alpine

Но потом ничего не произошло! Это потому, что когда вы вызываете $ docker run {name}, клиент Docker (CLI):

  • Находит изображение (в данном случае alpine)
  • Загружает контейнер
  • Выполняет команды (если есть) в контейнере

Когда мы запускали $ docker run alpine, мы не предоставляли никаких команд, поэтому контейнер загрузился, выполнил пустую команду и затем завершил работу.

Давайте попробуем лучшую команду, которая будет печатать hello world из alpine:

$ docker run alpine echo "hello from alpine"

В результате Docker запускает команду echo в нашем контейнере alpine и затем закрывается.

Представьте, сколько времени могло потребоваться, чтобы загрузить виртуальную машину, запустить на ней команду и затем убить ее! Намного длиннее контейнера. В этом преимущество контейнеров.

Если бы контейнеры могли запустить только одну команду echo и выйти, они были бы очень бесполезны. К счастью, контейнеры могут выполнять длительные процессы, то есть работать без выхода. Чтобы увидеть все запущенные контейнеры, используйте эту команду:

$ docker ps

Ps покажет вам список всех контейнеров, которые мы запускали на этом компьютере (называемом хостом):

$ docker ps -a

Чтобы остановить отсоединенный контейнер, запустите $ docker stop {ID}, указав идентификатор контейнера.

Вот некоторые полезные параметры команды doker run:

  • -d отключит наш терминал (bg / daemon).
  • -rm удалит контейнер после запуска.
  • -Он подключает интерактивный терминал к контейнеру.
  • -p будет публиковать / открывать порты для нашего контейнера.
  • - назовите имя для нашего контейнера.
  • -v монтирует том для совместного использования между хостом и контейнером.
  • -e предоставляет контейнеру переменные среды.
  • docker run - справка по всем флагам

Создание образов Docker

Если вы помните из определения, есть такая вещь, как Dockerfile. Вот как мы можем создавать новые изображения. Фактически, у каждого образа в Docker Hub есть Dockerfile. Dockerfile - это просто текстовый файл, содержащий список команд, которые клиент Docker вызывает при создании образа.

Вы можете включить в Dockerfile следующие инструкции:

  • FROM: (требуется как первая инструкция в файле) указывает базовый образ, на основе которого создается контейнер Docker и для которого запускаются последующие инструкции Dockerfile. Образ может быть размещен в общедоступном репозитории, частном репозитории, размещенном в стороннем реестре, или репозитории, который вы запускаете на EC2.
  • EXPOSE: перечисляет порты, которые нужно открыть на контейнере.
  • ДОБАВИТЬ: добавляет указанные файлы в место в контейнере.
  • WORKDIR: устанавливает текущий рабочий каталог для выполнения команд в контейнере.
  • VOLUME: отмечает точку монтирования как доступную извне для хоста (или других контейнеров).
  • CMD: указывает исполняемый файл и параметры по умолчанию, которые объединяются в команду, которую контейнер запускает при запуске. Используйте следующий формат:
  • CMD [«исполняемый файл», «параметр1,» параметр2]

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

ENTRYPOINT: использует тот же формат JSON, что и CMD, и, как и CMD, указывает команду, запускаемую при запуске контейнера. Также позволяет запускать контейнер как исполняемый файл с помощью docker run.

Если вы определяете ENTRYPOINT, вы также можете использовать CMD, чтобы указать параметры по умолчанию, которые можно переопределить с помощью опции -d docker run. Команда, определенная с помощью ENTRYPOINT (включая любые параметры), сочетается с параметрами из ** CMD ** или docker run при запуске контейнера.

RUN: указывает одну или несколько команд, которые устанавливают пакеты и настраивают ваше веб-приложение внутри образа.

ENV - устанавливает для переменной среды {key} значение {value} с помощью {key} = {value}. Пример синтаксиса:

ENV myName="John Doe" myDog=Rex The Dog myCat=fluffy

Для получения дополнительной информации об инструкциях, которые вы можете включить в Dockerfile, перейдите по ссылке Dockerfile Reference: http://docs.docker.io/reference/builder. Советы и рекомендации по использованию Dockerfile: https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices

Тома могут совместно использовать код между хостом (вашим компьютером) и контейнером. Другими словами, том Docker - это червоточина между эфемерным контейнером Docker и хостом. Он отлично подходит для разработки или хранения постоянных данных. Следующая команда смонтирует том из текущего рабочего каталога (pwd) на хосте. Файлы будут доступны в / www / в контейнере. Параметры запоминать слева направо, то есть host: contaner.

$ docker run -v $(pwd)/:/www/ -it ubuntu

Как только команда будет запущена, вы окажетесь внутри контейнера благодаря параметру -it. Там вы можете перейти к / www с помощью cd / www. Что вы видите (используйте ls)? Ваши файлы! А теперь волшебство. Если вы измените, удалите добавленные файлы в папку вашего хоста, эти изменения будут автоматически в контейнере!

Более того, даже если контейнер остановлен, постоянные данные все еще существуют на хосте Docker и будут доступны.

Создание образов узлов Docker

Теперь, когда дело доходит до Node, у вас есть возможность получить один из официальных образов Node из Docker Hub. Текущие версии - Boron и Argon, но есть также версия 7 и ночные выпуски.

Другой вариант - создать образ узла из базы Debian или Ubuntu. Вам даже не нужно составлять Dockerfile самостоятельно. Вы можете позаимствовать несколько строк из официальных изображений и при необходимости добавить / удалить.

Мы продолжим работу с первым вариантом, так как это самый простой способ. Итак, мы создаем Dockerfile в нашей папке проекта Node.js прямо там, где у вас есть package.json и node_modules, то есть в корне проекта. Каждый проект обычно представляет собой папку или даже отдельный репозиторий Git. Затем напишите в инструкции Dockerfile:

FROM node:argon
 
# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
 
# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install
 
# Bundle app source
COPY . /usr/src/app
 
EXPOSE 3000
CMD [ "npm", "start" ]

Мы начинаем с образа Argon, создавая папку для кода вашего приложения. Затем мы копируем файлы исходного кода из текущей папки (корень проекта). Наконец, мы открываем порт приложения (по какой-то странной причине его почти всегда 3000) и загружаем сервер с помощью npm start, предполагая, что этот сценарий npm определен в вашем package.json. Если вы не являетесь поклонником сценариев npm, таких как npm start, просто используйте node app.js или node server.js в зависимости от имени вашего файла.

Чтобы создать образ приложения Node.js, запустите $ docker build. Первый запуск может занять больше времени, если у вас еще нет агрона. В следующий раз будет быстрее. После завершения сборки вы можете запустить контейнер приложения, как и любые другие изображения:

$ docker run {name}

Вот загвоздка. Вы могли заметить, что у вашего нового образа нет имени, если вы просто использовали docker build. И, скорее всего, у вас уже есть или будет несколько изображений. Поэтому лучше давать изображениям имена и теги при их создании. Используйте флаг -t и формат nam: tag. Например,

$ docker build -t {your-name}/{your-app-name}:{tag} .

Контейнеры работают быстро, но создавать новые образы каждый раз, когда вы вносите изменения в исходный код, не очень хорошо. Итак, для разработки мы можем смонтировать исходный код как том и использовать что-то вроде forever, nodemon или node-dev для прослушивания изменений файлов и перезапуска сервера в любое время, когда мы нажимаем кнопку save. В случае тома нет необходимости копировать исходный код, поскольку он будет смонтирован с тома.

FROM node:argon
 
WORKDIR /usr/src/app 
RUN npm install

EXPOSE 3000
CMD [ "nodemon", "app.js" ]

Команда для запуска этого образа будет немного более продвинутой, так как теперь нам нужно смонтировать том:

$ docker run -v ./:/usr/src/app -it {name}

Теперь внесенные вами изменения будут переданы в контейнер, сервер перезапустится, и вы сможете разрабатывать в своей среде хоста, выполняя код в контейнере. Лучшее из обоих миров! (Это здорово, потому что среда контейнера будет в точности такой же, как и та, что у вас есть сейчас.) Но приложения не работают сами по себе. Вам нужна настойчивость и другие услуги.

Работа с несколькими контейнерами: Node и MongoDB

version: '2'
services:
 
  mongo:
    image: mongo
    command: mongod --smallfiles
    networks:
      - all
 
  web:
    image: node:argon
    volumes:
      - ./:/usr/src/app
    working_dir: /usr/src/app
    command: sh -c 'npm install; npm run seed; npm start'
    ports:
      - "3000:8080"
    depends_on:
      - mongo
    networks:
      - all
    environment:
      MONGODB_URI: "mongodb://mongo:27017/accounts"
 
networks:
  all:

Давайте посмотрим на этот ymp-файл построчно. Начнем со списка услуг. Имя службы, то есть mongodb, будет доступно в других контейнерах, поэтому мы можем подключиться к MongoDB с помощью mongodb: // mongo: 27017 / accounts. Вам не нужно передавать эту строку подключения в переменной среды. Я просто сделал это, чтобы показать, что вы можете это сделать.

Изображение, тома, порты и другие поля имитируют инструкции Dockerfile. Ключевое различие в том, что мы используем depends_on. Это укажет веб-службе использовать службу mongo.

Чтобы запустить Docker compose, просто выполните эту команду терминала (при условии, что deamon запущен):

$ docker-compose up

Вы можете посмотреть полный рабочий пример приложения MERN (MongoDB, Express, React and Node) по адресу https://github.com/azat-co/mern/blob/master/code. Docker compose - отличный и простой способ запустить многоконтейнерную среду.

Заворачивать

Контейнеры отлично подходят для безопасного размещения вашего кода в нескольких средах с очень небольшими накладными расходами. Это позволяет свести к минимуму любые неточности. Основная идея заключается в том, что, разрабатывая среду, идентичную производственной, вы устраняете любые потенциальные проблемы, связанные с различиями между dev и prod. Более того, сделав инкапсуляцию дешевле, чем с виртуальными машинами, мы можем разделить наши приложения на более детализированные службы. Их можно разделить не только на приложение, базу данных, кеш, веб-сервер, но и многое другое. Мы можем разделить веб-приложения на контейнеры по ресурсам, например, конечные точки для / account в одном контейнере, конечные точки для / users в другом и т. Д. но это тема для другого поста.

Дополнительная литература и ресурсы Docker

Обучение никогда не прекращается! Вот некоторые материалы по Docker и ресурсы.

PS: Часть AWS, упомянутая в избранном изображении, будет рассмотрена в новом посте.

- Азат Мардан

Https://www.linkedin.com/in/azatm
Чтобы связаться с Азатом, основным автором этого блога, заполните контактную форму.

Кроме того, не забудьте получить 3 замечательных ресурса БЕСПЛАТНО при подписке на информационный бюллетень.

Простой. Легкий.

Без комментариев.