Прежде всего, вам нужно получить 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 и ресурсы.
- Превосходный докер: https://github.com/veggiemonk/awesome-docker
- Мастерская Hello Docker: http://docker.atbaker.me
- Почему Docker: https://blog.codeship.com/why-docker
- Docker Weekly и архивы: https://blog.docker.com/docker-weekly-archives
- Блог Codeship: https://blog.codeship.com
PS: Часть AWS, упомянутая в избранном изображении, будет рассмотрена в новом посте.
- Азат Мардан
Https://www.linkedin.com/in/azatm
Чтобы связаться с Азатом, основным автором этого блога, заполните контактную форму.
Кроме того, не забудьте получить 3 замечательных ресурса БЕСПЛАТНО при подписке на информационный бюллетень.
Простой. Легкий.
Без комментариев.