Docker для windows как работает

imageДанная публикация является разбором особенностей контейнерной виртуализации Docker под системой Windows.

Она не претендует на роль исчерпывающей и по мере необходимости будет обновляться и дополняться.

За практическим руководством с нуля советую обратиться к этой публикации.

Содержание

  • Предварительные настройки
  • Выбор между Docker Toolbox on Windows или Docker for Windows
  • Windows контейнеры и Linux контейнеры
  • Особенности монтирования папок
  • Монтирование с хост-машины или volume
  • Особенности разметки диска GPT и MBR
  • Docker Toobox to Windows
  • Docker Swarm
  • Проблемы с кодировкой
  • Полезные ссылки
  • Заключение

Предварительные настройки

Контейнерная виртуализация или виртуализация на уровне операционной системы Docker нативно работает только на дистрибутивах Linux и FreeBSD (экспериментально).
На Windows вам понадобится гостевая Linux система либо специальная минималистичная виртуальная машина с ядром Linux от разработчиков Docker, которая и ставится из коробки.
Само собой разумеется, что вы включили виртуализацию у себя в BIOS/UEFI
Пункт настройки может называться по-разному: VT-x, VT-d, Intel VT, AMD-V, Virtualization Technology.

Еще одним минимальным системным требованием будет разрядность системы x64 и версия не ниже Windows 7 Pro.

Выбор между Docker Toolbox on Windows или Docker for Windows

Появление Docker Toolbox on Windows и Docker Toolbox on Mac было большим событием.

Сборка включается в себя сам docker, утилиту docker-compose, утилиту для работы с виртуальной машиной docker-machine и клиент Kitematic.

Используется виртуальная машина (по умолчанию на VirtualBox) с минималистичным Linux окружением.

Позже для новых операционных систем выпустили Docker for Windows и Docker for Mac, которая на текущий момент является актуальной версией и продолжает развиваться.

Выбор между версиями не сложный:
— Если у вас Windows 10 x64 Pro, Enterprise или Education то включаем службу Hyper-V и ставим Docker for Windows.

Заметьте, что после включения службы Hyper-V пропадет возможность запускать и создавать x64 виртуальные машины на VirtualBox.

— Если же у вас другая версия Windows(7 Pro, 8, 8.1, 10 Home) то ставим VirtualBox и Docker Toolbox on Windows.

Несмотря на то, что Docker Toolbox разработчиками признан устаревшим работа с ним слабо отличается от Docker for Windows.

Вместе с установкой Docker Toolbox будет создана виртуальная машина.
В самом VirtualBox можно будет добавить оперативной памяти и ядер процессора на ваше усмотрение.

Windows контейнеры и Linux контейнеры

Docker for Windows предоставляет возможность переключать контейнеризацию между Linux и Windows версией.

В режиме Windows контейнеризации вы можете запускать только Windows приложения.
Замечу, что на май 2018 года в официальном Docker Hub существует всего 13 образов для Windows.

После включения Windows контейнеризации не забудьте добавить внешнюю сеть.

В конфигурационном файле docker-compose.yml это выглядит так:

networks:
  default:
    external:
      name: nat

Особенности монтирования папок

На примонтированных volume-ах не кидаются события файловой системы, поэтому inotify-tools не работает.
Спасибо пользователю eee

Если вы разрабатываете свой проект и пользуетесь docker-compose вне домашней папки то вам нужно будет проделать некоторые манипуляции.

Используя Docker for Windows для монтирования нового диска у вашего локального пользователя обязательно должен стоять пароль, который будет использоваться для доступа к shared папки.

Особенность заключается в том, что монтируемые внутрь контейнера диск будет монтироваться как от удаленной машины //10.0.75.1/DISK_DRIVE по протоколу SMB.

Для Docker Toolbox диски монтируются в самом VirtualBox на вкладке «Общие папки»
Пример для диска «D»:

Права доступа к монтируемым файлам и папкам

Как бы вам не хотелось, но для всех примонтированных из хост-машины файлов и папок будут стоять права 755 (rwx r-x r-x) и поменять их вы не сможете.

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

В данном случае либо генерируют ключ при создании образа, либо прокидывают сокет ssh-agent с хост-машины.

Монтирование с хост-машины или volume

Монтирование внутрь контейнера происходит с использованием сети и протокола SMB, следовательно, внутри контейнера диск «D:\» будет примонтирован из источника //10.0.75.1/D
Использование volume внутри контейнера отображается как монтирование локального диска /dev/sda1, что влияет на скорость работы.

Простым тестом копирование файла на обычном HDD скорость работы получилась следующая:

Такая разница в скорости скорее всего связана с тем, что в volume данные сбрасываются на диск постепенно, задействуя кеш в ОЗУ.

Особенности разметки диска GPT и MBR

Данный пункт не является истинной так как опровергающей или подтверждающей информации в интернете найти не смог.

Если на хост-машине таблица разделов MBR, то контейнер с MySQL/MariaDB может упасть с ошибкой:

InnoDB: File ./ib_logfile101: ‘aio write’ returned OS error 122. Cannot continue operation

По умолчанию в базе данных включеён параметр innodb_use_native_aio, отвечающий за асинхронный ввод/вывод и его надо будет выключить.

Данная проблема также встречается на некоторых версиях MacOS.

Docker Toobox to Windows

Главное правило: начинать работу с запуска ярлыка на рабочем столе «Docker Quickstart Terminal», это решает 80% проблем.

— Бывает возникают проблемы с отсутствия переменных окружения, решается командой:

eval $(docker-machine env default)

— Если все же возникают проблемы из разряда «docker: error during connect», необходимо выполнить:

docker-machine env --shell cmd default 
@FOR /f "tokens=*" %i IN ('docker-machine env --shell cmd default') DO @%i

Название Docker Machine по умолчанию default.

Docker Swarm

Ни в Docker for Mac, ни в Docker for Windows — нет возможности использовать запущенные демоны в качестве клиентов кластера (swarm members).
Спасибо пользователю stychos

Проблемы с кодировкой

Используя Docker Toolbox(на Docker for Windows не удалось воспроизвести) нашлась проблема с тем, что русские комментарии в docker-compose.yml файле приводили к ошибке:

Traceback (most recent call last):
  File "docker-compose", line 6, in <module>
  File "compose\cli\main.py", line 71, in main
  File "compose\cli\main.py", line 124, in perform_command
  File "compose\cli\command.py", line 41, in project_from_options
  File "compose\cli\command.py", line 109, in get_project
  File "compose\config\config.py", line 283, in find
  File "compose\config\config.py", line 283, in <listcomp>
  File "compose\config\config.py", line 183, in from_filename
  File "compose\config\config.py", line 1434, in load_yaml
  File "site-packages\yaml\__init__.py", line 94, in safe_load
  File "site-packages\yaml\__init__.py", line 70, in load
  File "site-packages\yaml\loader.py", line 24, in __init__
  File "site-packages\yaml\reader.py", line 85, in __init__
  File "site-packages\yaml\reader.py", line 124, in determine_encoding
  File "site-packages\yaml\reader.py", line 178, in update_raw
  File "c:\projects\compose\venv\lib\encodings\cp1251.py", line 23, in decode
UnicodeDecodeError: 'charmap' codec can't decode byte 0x98 in position 1702: character maps to <undefined>
[4176] Failed to execute script docker-compose

Полезные ссылки

Docker Toolbox on Windows
Docker for Windows
Практическое руководство по Docker

Заключение

Особенности работы с Docker контейнеризацией на системе Windows не отличается от работы на Linux за исключение разобранных выше.

В статье я умышленно не упомянул заметно низкую скорость работы контейнеров и overhead используя систему Windows как само собой разумеющееся.

Буду рад услышать ваши отзывы. Не стесняйтесь предлагать улучшения или указывать на мои ошибки.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Какой версией Docker вы пользуетесь?


32.47%
Docker Toolbox on Windows
88


67.53%
Docker for Windows
183

Проголосовал 271 пользователь.

Воздержался 191 пользователь.

Эта статья даст вам полное представление о Docker Desktop для пользователей Windows и MAC. Мы изучим установку Docker Desktop на компьютерах с Windows и Mac. После установки мы также попытаемся выполнить некоторые операции Docker.

Docker Desktop — это собственное настольное приложение, разработанное Docker для пользователей Windows и MAC. Это самый простой способ запуска, сборки, отладки и тестирования приложений Dockerized.

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

Docker Desktop состоит из инструментов для разработчика, приложения Docker, Kubernetes и синхронизации версий. Он позволяет вам создавать сертифицированные образы и шаблоны языков и инструментов.

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

Прежде чем перейти к процессу установки, давайте разберемся с его версиями.

Версии Docker

Docker в основном поставляется в двух версиях, в Community и ENterprise.

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

Мы начнем наше обучение с Community Edition. Контейнеры Docker, работающие в конкретной операционной системе, совместно используют ядро ​​ОС. Это означает, что мы не можем использовать ядро ​​Windows (хост) для запуска контейнеров Linux или наоборот. Чтобы проделать это, у нас есть Docker Desktop для Windows и MAC.

Выпуски Docker Desktop

Docker Desktop выпускается в двух вариантах.

  • Stable: как видно из названия, стабильный выпуск тщательно протестирован и может быть использован при разработке более надежных приложений. Его версии полностью синхронизированы с версиями Docker Engine.
  • Edge: эти версии состоят из всех новых и экспериментальных функций Docker Engine. Есть больше шансов ошибок, сбоев и проблем, которые могут возникнуть. Тем не менее, пользователи получат возможность ознакомиться с предстоящими функциями.

Docker на Windows

Есть два варианта Docker на Windows.

1. Использование Docker Toolbox

Docker Toolbox предоставляет набор легких инструментов.

  • Oracle virtual box
  • Docker Engine
  • Docker Machine
  • Docker compose
  • Kitematic GUI

Вышеуказанные инструменты устраняют необходимость развертывания отдельной виртуальной машины для запуска Docker. Просто установите исполняемый файл панели инструментов Docker непосредственно в Windows и начните разработку приложений. Требуется 64-битная ОС и Windows 7 или выше с включенным режимом виртуализации.

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

2. Использование Docker Desktop

Docker Desktop — это новейшая технология, используемая для Docker в Windows. Он заменяет виртуальную машину Oracle собственной технологией виртуализации, доступной в Windows, то есть Microsoft Hyper-V.

Он по-прежнему будет запускать Docker на Linux-машине, созданной под ним. Но на этот раз вместо виртуальной машины Oracle мы использовали нативный Microsoft Hyper-V.

Установка Docker на Windows

Вы можете скачать репозиторий Docker Desktop из Docker Hub.

Установка Docker на Windows

истемные требования:

  • Windows 10 или Windows Server 2016 Professional или Enterprise Edition
  • Поддержка Hyper-V.

Чтобы запустить Hyper-V, оборудование должно соответствовать следующим требованиям:

  • 64-битный процессор
  • > = 4 ГБ ОЗУ
  • Поддержка виртуализации оборудования на уровне BIOS

Следовательно, программная и аппаратная зависимость заключается в запуске Docker Desktop на Windows.

Установка Docker на macOS

Вы можете скачать репозиторий Docker Desktop из Docker Hub.  

Установка Docker на macOS

Системные требования:

  • MAC Hardware 2010 или новее с аппаратной поддержкой управления памятью и неограниченным режимом. Выполните команду kern.hv_support, чтобы проверить, поддерживает ли оборудование MAC инфраструктуру гипервизора.
  • MAC OS версии 10.13 или новее.
  • > = 4 ГБ ОЗУ
  • Virtual-Box до версии 4.3.30

Работа с образами

После установки проверьте версию установленного Docker Engine.

docker --version

Docker работает с доставкой и запуском контейнерных приложений. Вам либо нужно создать свое собственное контейнерное приложение, либо Docker поддерживает контейнерные образы в Docker Hub, и его можно легко загрузить с помощью простой команды docker run.

Здесь мы будем тянуть образ Redis.

docker pull redis

docker образ redis

С помощью простой команды run образы можно скачивать и загружать на GitHub или Docker Hub, и любой пользователь во всем мире может получить к нему доступ и начать работать с ним.

Docker Container запускает образ Docker. Следующим шагом является запуск контейнера.

docker run -p 6379 Redis

docker запуск redis

Будет создан зашифрованный идентификатор контейнера. Вы можете быстро проверить состояние работающего экземпляра в Docker, нажав на Dashboard option.

Docker Desktop

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

Docker Desktop

Возможности Docker Desktop

Существует множество преимуществ:

  • Поддерживает широкий спектр инструментов разработки.
  • Обеспечьте быстрый и оптимизированный способ создания и публикации контейнерного образа на любой облачной платформе.
  • Простота установки и настройки полной среды Docker
  • Повышение производительности благодаря встроенной виртуализации Hyper-V для Windows и HyperKit для MAC.
  • Возможность работать в Linux через WSL 2 на компьютерах с Windows.
  • Легкий доступ к работающим контейнерам в локальной сети.
  • Возможность поделиться любым приложением на облачной платформе, на разных языках и в разных средах.
  • Для обеспечения безопасности и актуальности выполняются автоматические обновления.
  • Включены последние версии Kubernetes.
  • Возможность переключения между Linux и Windows сервером на Windows.

Docker Desktop — это нативное приложение, разработанное на Windows и MAC OS для запуска, сборки и доставки контейнерных приложений или сервисов.

Однако

Docker Desktop предназначен не для производственной среды, а для рабочего стола и среды разработки.

Также рекомендуем прочитать:

  1. Docker для начинающих — технология контейнеров
  2. В чем разница между Docker и Kubernetes?
  3. Введение в Docker Hub и все, что вы должны знать о нем
  4. Как установить Docker на Ubuntu, Windows, Debian и CentOS?
  5. Kubernetes — Введение для начинающих
  6. Docker посмотреть запущенные контейнеры, запустить или остановить контейнеры

If you’re new to containers and Docker and work primarily on Windows, you’re in for a treat. In this article, you’re going to learn how to set up Docker on Windows 10 using Docker Desktop for Windows or simply referred to as Docker Desktop in this article.

Not a reader? Watch this related video tutorial!

Not seeing the video? Make sure your ad blocker is disabled.

Docker Desktop is the Docker Engine and a management client packaged together for easy use in Windows 10. In this article, you will install Docker Desktop, deploy your first container, and share data between your host and your containers.

Prerequisites for Docker on Windows

This is a walkthrough article demonstrating various steps in Docker Desktop for Docker on Windows. To follow along, be sure you have a few specific requirements in place first.

  • An Internet connection to download 800MB+ of data
  • Windows 10 64-bit running Pro, Enterprise, or Education edition with release 1703 or newer. This is necessary to run Hyper-V on Windows 10.
  • A CPU with SLAT (nested paging) compatibility. All AMD/Intel processors since approximately 2008 are SLAT compatible
  • At least 4GB of RAM
  • BIOS hardware virtualization sometimes labeled as Virtualization Technology or VTx. This must be enabled and show as Enabled in the performance tab of Task Manager as shown below.
Enabled BIOS virtualization shown in Windows Task Manager
Enabled BIOS virtualization shown in Windows Task Manager

Downloading and Installing Docker Desktop

Up first, you need to download and install Docker Desktop to get Docker on Windows going. Docker Desktop comes available in two releases; a stable release and a testing release.

The stable release is released quarterly and ensures a fully-tested application. In this article, you will be using the stable release.

Warning: Upon installation, Docker Desktop will prompt you to install the Hyper-V hypervisor if not already installed. By doing so, the Hyper-V hypervisor prevents any user-mode hypervisors such as VirtualBox, VMWare, etc. from running guest VMs. Hyper-V support for VirtualBox and VMWare is limited but coming.

You also have the option of a download source through manually downloading Docker Desktop directly from Docker.com or via the Windows package manager, Chocolatey. Let’s briefly cover each method.

From Docker.com

To download Docker Desktop directly from docker.com, you can go to the product page, register for an account and download it from there. This is preferred if you intend to use Docker in production by registering an account.

However, if you’re just testing Docker out for the first time, you can also download it directly which is much easier.

Once the EXE is downloaded, run the executable and click through the prompts accepting all of the defaults.

When asked whether you plan to Use Windows containers instead of Linux containers, as shown below, do not enable the checkbox. You will be using Linux containers in this article.

Installing Docker Desktop
Installing Docker Desktop

Once installation is complete, reboot your computer.

Selecting the option to use Windows containers or Linux containers tells Docker to attach images to a Windows kernel or Linux kernel. You can change this setting at any time after installation by right-clicking the Docker icon in the System Tray and selecting Switch to Windows containers as shown below.

Switching to Windows containers
Switching to Windows containers

Using Chocolatey

The other option to get Docker Desktop downloaded and installed is with Chocolatey. Chocolatey automates many of the download/install tasks for you. To do so, open up a command-line console (either cmd or PowerShell) as an administrator to download and install the program in one shot by running the command below.

choco install docker-desktop

Once complete, reboot Windows 10.

If you’d like to try out the testing release at some point, you can download and install this by running choco install docker-desktop --pre.

Validating the Docker Desktop Installation

Once installed, Docker Desktop automatically runs as a service providing Docker on Windows. It’s shown in the system tray when you log in to Windows after you reboot. But how do you actually know it’s working?

To validate Docker Desktop is working correctly, open a command-line console and run the docker command. If the installation went well, you will see a Docker command reference.

Finally, have Docker download and run an example container image called hello-world by running the command docker run hello-world. If all is well, you will see output like below.

A successful test image run via Docker Desktop
A successful test image run via Docker Desktop

Running Commands in Docker Containers

Docker Desktop is installed and you’ve verified all is well? Now what? To get started with Docker on Windows, one common task to perform in a Docker container is running commands. Through the docker run command, you can send commands through the host (your Windows 10 PC) directly into a running container.

To run commands in a container with docker run, you’ll first specify an image name followed by the command. To get started, tell Docker to run the command hostname inside of a container called alpine as seen below.

> docker run alpine hostname
b74ff46601af

Since you don’t have the alpine Docker image on your computer now, Docker on Windows will download the tiny image from the Docker Hub, bring up a container from that image, and send the command directly into the container and shut it down all in one swoop.

If you’d like to keep the container running, you can also use the -it parameter. This parameter tells Docker to keep the container in “interactive mode” leaving it running in the foreground after executing the command. You’ll see that you are then presented with a terminal prompt ready to go.

> docker run -it alpine sh
/ #

When you’re done in the terminal, type exit to return to Windows 10.

Accessing Files from the Docker Host in Containers

Another common task is accessing host files from containers. To access host files in containers, Docker on Windows allows you to link a folder path from your desktop to share that folder to your container. This process is called binding.

To create a binding, make a folder on a local drive. For this example, I’ll use E:\ and call it input. It’ll then create a new text document named file.txt in the folder. Feel free to use whatever path and file you wish.

Once you have the folder you’d like to share between the host and container, Docker needs to mount the folder using the --mount parameter. The --mount parameter requires three arguments; a mount type, a source host directory path and a target directory path. The target path will be a symbolic link within the container.

Below you will see an example of mounting the entire E:\ within the Windows 10 host to show up as the /home/TEST directory inside of the Linux container.

> docker run --mount type=bind,source="E:/",target=/home/TEST -it alpine

When you attempt to mount a host folder, Docker Desktop will ask for your permission to share this drive with the Docker containers as seen below.

Sharing a Docker drive
Sharing a Docker drive

If you created the file.txt file in the Windows 10 folder as described earlier, run cat /home/TEST/input/file.txt. You will see that contents are displayed.

Now, delete the input folder that you just created and run the cat ... command again. Observe that the shell now reports that the file does not exist anymore.

Working with files in Docker containers
Working with files in Docker containers

Mapping Network Ports

Another important concept to know is how Docker on Windows handles networking. For a brief introduction, let’s see what it takes to access a web service running in a container from the local host.

First, spin up a demo image that will run an example webpage. Download and run the Docker image called dockersamples/static-site. You’ll use docker container run to do so.

The following command does four actions at once:

  • Downloads a Docker image from Docker Hub called static-site in the docker-samples “directory”
  • Starts a container instance up from the static-site image
  • Immediately detaches the container from the terminal foreground (—detach)
  • Makes the running container’s network ports accessible to the Windows 10 host (—publish-all)
docker container run --detach --publish-all dockersamples/static-site
## Alternate/shorthand syntax that does the same thing:
## docker container run -d -P dockersamples/static-site
## docker run -d -P dockersamples/static-site

Once run, Docker will return the container ID that was brought up as shown below.

Docker container ID returned from running a container
Docker container ID returned from running a container

Publishing Network Ports

Since using the --publish-all parameter, local host ports are now mapped to the container’s network stack. You can use the docker ps subcommand to list all running containers including what ports are assigned to all of the running containers. In the instance below, one container is running mapping host port 32777 to container port 80 and host port 32776 to container port 443.

Showing port mapping of Docker container
Showing port mapping of Docker container

Docker on Windows assigns containers random ports when using the --publish-all parameter unless explicitly define them.

Now open up a web browser and navigate to http://localhost:32777 or the port that Docker assigned to map to port 80 as output by docker ps. If all goes well, you should see the below webpage show up.

Resulting webpage running in the Docker container
Resulting webpage running in the Docker container

Changing the Published Ports

You now have a Docker container running in Docker on Windows serving up a simple web page. Congratulations! But now you need to specify a specific port binding not relying on the random port selection with --publish-all. No problem. Use the -p parameter.

First, stop the running container by specifying a unique string of it’s container ID. You can find this container ID by running docker ps. Once you know the container ID, stop the container and start a new one while designating Docker to assign a specific port to publish.

The syntax for specifying a port is <external port>:<container port>. For each port that you want to publish, use the --publish or -p switch with the external and container port numbers as shown below.

> docker stop f766
> docker run --detach -p 1337:80 dockersamples/static-site

When you are specifying a container ID, you only have to type enough of the ID to be unique. If you are only running a single container and its ID is f766f4ac8d66bf7, you can identify the container using any number of characters including just f. The requirement is that whatever you type allows it to uniquely identify a single container.

Now go to your web browser and navigate to localhost:1337. Remember, you are not changing the image and it always listens on port 80; you are changing the port translation rule in the Docker configuration that lets you connect to the container.

Webpage being served up on port 1337
Webpage being served up on port 1337

Stopping all Containers

Using docker stop, you can stop a container but how do you stop multiple containers at once? One way to do so is by providing multiple, space-delimited container IDs. You can see below an example of how to stop three containers with IDs of fd50b0a446e7, 36ee57c3b7da, and 7c45664906ff.

> docker stop fd50 36ee 7c45

If you’re managing Docker containers in PowerShell, you can also use a shortcut to stop all containers. Feed a list of container IDs via docker ps -q to the stop parameter through PowerShell’s command expansion docker stop (docker ps -q).

Confirm all containers are stopped by seeing no containers listed when you type docker ps.

Cleaning Up

You’ve downloaded a few container images and run some containers that are now stopped. Even though they’re stopped, their allocated storage isn’t gone off of the local host disk. You must delete the containers free up that space and avoid cluttering up your workspace.

To delete a single container, use the container remove rm parameter like below.

> docker container rm <container ID>

Or, to delete all stopped containers, use the prune parameter as below.

If you’re looking for simple and painless software deployment, Docker is the right tool for you. It is the best containerization platform and in this blog on Docker for Windows we’ll specifically focus on how Docker works on Windows.

To get in-depth knowledge on Docker, you can enroll for live DevOps Certification Training by Edureka with 24/7 support and lifetime access.

I’ll be covering the following topics in this blog:

  1. Why use Docker For Windows?
  2. Docker for Windows prerequisites 
  3. Components installed with Docker 
  4. What is Docker?
  5. Docker Terminologies
  6. Hands-On

Why use Docker for Windows?

Why use Docker for Windows - Docker for Windows - Edureka

Why use Docker for Windows – Docker for Windows

  • Avoids the work on my machine but doesn’t work on production problem: This problem occurs due to the inconsistent environment throughout the software development workflow. With Docker you can run an application within a container which contains all the dependencies of the application and the container can be run throughout the software development cycle. This practice provides a consistent environment throughout the software development life cycle
  • Improves productivity: By installing Docker on windows we’re running Docker natively. If you’ve been following Docker for a while, you know that Docker containers originally supported only Linux operating systems. But thanks to the recent release, Docker can now natively run on windows, which means that Linux support is not needed, instead the  Docker container will run on the windows kernel itself
  • Supports native networking: Not only the Docker container, the entire Docker tool set is now compatible with windows. This includes the Docker CLI (client), Docker compose, data volumes and all the other building blocks for Dockerizied infrastructure are now compatible with windows. But how is this advantageous? Since all the Docker components are locally compatible with windows, they can now run with minimal computational overhead.

    You can get a better understanding with this Online Docker Training Course.

Docker For Windows Prerequisites

Docker for Windows - Prerequisites - Edureka

Docker for Windows – Prerequisites

The following requirements need to be met before installing Docker on windows:

  1. Check if you’re using Windows 10, either pro edition or enterprise edition, 64-bit system. Docker will not run on any other windows version. So if you’re running on an older windows version, you can install the Docker toolbox instead. 
  2. Docker for windows requires a Type-1 hypervisor and in the case of windows, it’s called the Hyper-V. Hyper-V is basically a lightweight virtualization solution build on top of the hypervisor framework. So you don’t need a virtual box, you just have to enable the hypervisor.
  3. And also you need to enable the virtualization in BIOS. Now when you install Docker for windows, by default of this is enabled. But in case you’re facing any issue during installation, please check if your Hyper-V and virtualization is enabled.

Components Installed With Docker

Components installed with Docker - Docker for Windows - Edureka

Components installed with Docker – Docker for Windows

  1. Docker Engine: When we say Docker, we actually mean Docker engine. The Docker engine contains the Docker daemon, REST API for interacting with the Docker daemon and a command line interface client that communicates with the daemon. Docker daemon accepts Docker commands such as Docker run, Docker build, etc, from the Docker client.
  2. Docker Compose: Docker compose is used to run multiple Docker containers at once by using a single command, which is docker-compose up.
  3. Docker Machine: Docker machine is used to install Docker engine. It is basically what you install on your local system. The Docker machine has it’s own CLI client known as the Docker machine and a Docker engine client called Docker.
  4. Kitematic: Kitematic is an open source project built to simplify the use of Docker on Windows. It helps to automate the installation of Docker and it provides a very interactive user interface for running Docker containers.

If you want to learn more about Docker for Windows, check out this video by our DevOps experts.

Docker For Windows | Setting Up Docker On Windows | Docker Tutorial For Beginners | Edureka

This Edureka video on Docker For Windows we’ll discuss Docker which is one of the best containerization platforms out there.

What Is Docker?

Docker is a containerization platform that runs applications within containers called Docker containers. Docker containers are light weighted when compared to virtual machines. When you install a Virtual machine on your system, it uses the guest operating system on top of your host operating system.  This obviously takes up a lot of resources like disk space, RAM, etc. On the other hand, Docker containers make use of the host operating system itself.

What is Docker - Docker for Windows - Edureka

What is Docker – Docker for Windows

In the above image, you can see that, there’s a host operating system on top of which the Docker engine is mounted. The Docker engine runs container #1 and container #2. Both of these containers have different applications and each application has its own libraries and packages installed within the container.

I hope you have a good idea about what Docker is if you still have doubts check out this blog to learn more!

Let’s discuss some Docker terminologies now:

  • Docker Images

Docker images are read-only templates to build Docker images. Docker images are created from a file called Dockerfile. Within the Dockerfile, you define all the dependencies and packages that are needed by your application.

  • Docker Containers

Every time you run a Docker image, it runs as a Docker container. Therefore, a Docker container is the run time instance of a Docker image.

  • Docker’s Registry

Docker’s registry, known as DockerHub is used to store Docker images. These images can be pulled from the remote server and can be run locally. DockerHub allows you to have Public/Private repositories.

  • Docker Swarm

Docker swarm is a technique to create and maintain a cluster of Docker engines. A cluster of Docker engines comprises of multiple Docker engines connected to each other, forming a network. This network of Docker engines is called a Docker swarm. A Docker manager initiates the whole swarm and the other Docker nodes have services running on them. The main goal of the Docker manager is to make sure that the applications or services are running effectively on these Docker nodes.

  • Docker Compose

Docker compose is used to run multiple containers at once. Let’s say that you have 3 applications in 3 different containers and you want to execute them at once. This is where Docker compose comes in, you can run multiple applications in different containers at once, with a single command, which is docker-compose up.

Hands-On

We’ll begin our demo by installing Docker for windows. But before we do that, check if you’ve met the prerequisites.

One more thing to note is since Docker for Windows requires Microsoft’s Hyper-V and once it’s enabled, VirtualBox will no longer be able to run virtual machines. So you can’t run Docker for Windows and a VirtualBox on the same system, side by side.

Install Docker On Windows:

  1. Download Docker for Windows installer from the official website
  2. Double-click on the installer to run it
  3. Go through the Install Wizard, accept the license and proceed with the install
  4. After installation, open the Docker for Windows app and wait till the whale icon on the status bar becomes stable
  5. Open up any terminal like Windows PowerShell and start running Docker

Installation - Docker for Windows - EdurekaInstallation – Docker for Windows

Enough of theory, let’s get our hands dirty and create a simple Python web application by using Docker Compose. This application uses the Flask framework and maintains a hit counter on Redis.

Flask is a web development framework, written in Python and Redis is an in-memory storage component, used as a database. You don’t have to install Python or Redis, we’re simply going to use Docker images for Python and Redis.

In this demo we’re going to use Docker compose to run two services, namely:

  1. Web service
  2. Redis service.

What does the application do? It maintains a hit counter every time you access a web page. So each time you access the website the hit counter gets incremented. It’s simple logic, just increment the value of the hit counter when the web page is accessed.

For this demo, you’ll need to create four files:

  1. Python file
  2. Requirements.txt
  3. Dockerfile
  4. Docker compose file

Below is the Python file (webapp.py) that creates an application by using the Flask framework and it maintains a hit counter on Redis. 

import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I have been seen {} times.
'.format(count)
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)

The requirements.txt file has the name of the two dependencies, i.e. Flask and Redis that we’ll be installing in the Dockerfile.

flask
redis

The Dockerfile is used to create Docker images. Here, I’m installing python and the requirements mentioned in the requirements.txt file.

 
FROM python:3.4-alpine 
ADD . /code 
WORKDIR /code 
RUN pip install -r requirements.txt 
CMD ["python", "webapp.py"] 

The Docker compose file or the YAML file contains two services:

  1. Web service: Builds the Dockerfile in the current directory
  2. Redis service: Pulls a Redis image from DockerHub
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"

You can now run these two services or containers by using the following command:

docker-compose up

To view the output you can use Kitematic. To open Kitematic, right click on the whale icon on the status bar.

Kitematic -Docker For Windows - Edureka

Kitematic – Docker for Windows

On the top left-hand corner, you can see the two services running. 

Kitematic -Docker For Windows - Edureka

Kitematic – Docker for Windows

This is what the output looks like. When you refresh the page, the hit count gets incremented.  

Output -Docker For Windows - EdurekaOutput – Docker for Windows

With this, we come to the end of this blog. I hope you have a better understanding of how Docker works on Windows. Stay tuned for more blogs on the most trending technologies.

If you found this Docker for Windows blog relevant, check out the DevOps training by Edureka, a trusted online learning company with a network of more than 450,000 satisfied learners spread across the globe. The Edureka DevOps Certification Training course helps learners gain expertise in various DevOps processes and tools such as Puppet, Jenkins, Docker, Nagios, Ansible, and GIT for automating multiple steps in SDLC.

Добро пожаловать в гайд по изучению Docker, в котором я проиллюстрирую вам совершенно иной подход при разработке ваших приложений с его помощью. Эту статью вы можете считать как быстрый старт, введение в Docker.
Когда вы полностью прочитаете эту статью, уверен, вы поймёте, что такое Docker, для чего нужен, и где используется.

Но основным ключом к его освоению — это полное повторение процесса написания кода, как демонстрируется в этой статье. Это гайд по работе с Docker для новичков, потому, повторение процесса у себя на компьютере — обязательное условие к его пониманию. Одного чтения недостаточно, важно — повторение процесса и много практики. Так же чтобы наконец-то научиться работать с ним, даже при условии плохого понимая Docker-а, начните его уже применять в своей разработке. Начните, и увидите, как стали продвинутым его пользователем.

Когда я наконец-то понял все тонкости работы с Docker (на полное изучение которого ушло несколько месяцев), и начал правильно применять его при разработке (а он как раз и нужен для разработки, в большей степени), то почувствовал, как будто обрёл какую-то сверхспособоность. Смотря на свой опыт изучения Докера, я понял, что мне есть что рассказать, и чем поделиться. В этой статье я постарался создать максимально понятную для новичков инструкцию, благодаря которой вы сможете полностью изучить Docker за 30 минут. Я долго думал о том, чтобы написать туториал, и наконец-то осилил эту задачу, и, как мне кажется, получилось неплохо :)

Эта инструкция так же подходит для тех, кто не имеет никаких знаний, или опыта работы с докером, или аналогичным программным обеспечением. Вы получите все важные знания, необходимые для работы. Статья построена по принципу от простого к сложному. В итоге статьи вы будете чётко понимать, что такое Docker, зачем нужен, как с ним работать, и применять его для разработки: создавать окружение, необходимое для создания вашего приложения.

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

В этом туториале я показываю всё на примере ОС Windows 10, делая все команды из консоли винды, и демонстрируя процесс установки Docker на Windows 10. Но, все команды будут работать аналогично и на Linux и Mac. Эта статья — это продолжение ряда статей, посвященных настройке рабочего окружения. В прошлой статье мы рассматривали работу с Vagrant, что не менее интересно, чем Docker. И Docker и Vagrant преследуют цель — упростить жизнь разработчикам, но с Докером открывается больше возможностей.

Так же, прошу заметить, если вы используете Vagrant, и решите установить Docker, то Vagrant перестанет работать. Такая жизнь, но с этим можно смириться, тем более, субъективно, Docker круче ^^.

Что вы узнаете из этой статьи

  • Как работает Docker?
  • Как установить Docker на Windows?
  • Что такое Docker Image (образ)?
  • Что такое Docker контейнер?
  • Что такое Docker Volumes?
  • Что такое Dockerfile?
  • Как пробрасывать локальную папку в контейнер Докера (монтирование папки)?
  • Как работают и пробрасываются Docker порты?
  • Слои Docker образа, особенности создания образов.
  • Что такое Docker-compose?
  • Что такое микросервисы и микросервисная архитектура?

Что такое Docker

О том, как появился Docker:

Docker — это программное обеспечение, которое начинало с того, что зародилось в одной компании, как внутренний проект platform-as-a-service в компании dotCloud.

В процессе развития Докера, он вырос из масштабов внутреннего проекта, стал доступен для широких масс, и затмил своей популярностью своего родителя dotCloud, из-за чего было принято решение создать новую отдельную компанию под названием Docker Incorporated. Направление новосозданной компании было только в разработке Докера, и развитию его экосистемы.

На сайте Докера можно найти статью, в которой подробно рассказывается, что такое Docker. Из их слов — это стандартизированное ПО для разработки и развёртывания проектов.

Но, что это на самом деле значит?

Давайте на секунду забудем про Докер, и вспомним про такую ностальгическую штуку, как GameBoy Color:game-boy-coloe

Если вы помните, игры для этой приставки поставлялись в виде картриджей:cartrige

И я уверен в том, что производители видео игр пользуются успехом из-за своей простоты:

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

Docker следует похожему принципу — позволяет запускать своё ПО настолько просто, что это соизмеримо с вставкой картриджа и нажатием кнопки ON на приставке.

Это основная суть, почему Docker настолько полезен — теперь кто угодно, у кого установлен Docker может запустить ваше приложение, выполнив для этого всего несколько команд.

Раньше, вы, создавая приложения, к примеру на PHP, устанавливали локально PHP, MySql, возможно, NodeJs, при этом устанавливая зависимости в виде нужных расширений и библиотек. И, в случае передачи вашего скрипта какому-то знакомому, ему требовалось настраивать аналогичное окружение, аналогичных версий, иметь аналогичные расширения и конфигурацию, чтобы успешно запустить ваше приложение.

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

Какое программное обеспечение можно запустить с помощью докера? В техническом плане, Docker чем-то похож на виртуальную машину:

Докер — это движок, который запускает виртуальную операционную систему, имеющую чрезвычайно маленький вес (в отличие от Vagrant-а, который создаёт полноценную виртуальную ОС, Докер, имеет особые образы ПО, запускающиеся в виртуальной среде, не создавая полную копию ОС).

Docker позволяет запустить ОС Linux в изолированной среде очень быстро, в течение нескольких минут.

Зачем использовать Docker?

Кошмар при установке ПО, с которым приходится сталкиваться. У вас когда-нибудь было такое, что вы пытаетесь установить ПО на ваш компьютер, а оно отказывается работать? Вы получаете несколько непонятных вам ошибок, из-за которых ничего не запускается. И после нескольких часов гугления, на десятой странице гугла…и на каком-то форуме, до этого неизвестного вам, вы наконец-то находите случайный комментарий, который помогает исправить вашу проблему.

Аналогично, что делает написание PC игр более сложным, чем написание Game Boy игр — это то, что приходится проектировать систему с учётом большого множества существующих PC девайсов и спецификаций. Так как разные компьютеры имеют различные операционные системы, драйвера, процессоры, графические карты, и т.д.
И потому задача разработчика — написать приложение совместимое со всеми популярными системами, является достаточно затруднительной и трудоёмкой.

Docker спасёт нас. Docker, как и Game Boy приставка, берёт стандартизированные части программного обеспечения и запускает их так, как Game Boy запускал бы игру.

В этом случае вы не должны беспокоиться об операционной системе, на которой пользователь будет запускать ваше приложение. Теперь, когда пользователи будут запускать приложение через Docker — конфигурация будет собрана автоматически, и код будет выполняться ВСЕГДА.

Как разработчик, теперь вы не должны волноваться о том, на какой системе будет запущено ваше приложение.
Как пользователь, вам не нужно волноваться о том, что вы скачаете неподходящую версию ПО (нужного для работы программы). В Докере эта программа будет запущена в аналогичных условиях, при которых это приложение было разработано, потому, исключается факт получить какую-то новую, непредвиденную ошибку.

Для пользователя все действия сводятся к принципу подключи и играй.

Установка Docker

Docker доступен для любой из операционных систем: Windows, Linux, Max. Для скачивания установочного файла — перейдите по ссылке и выберите подходящую вам версию. Я же, как и писал ранее, выбираю версию docker для Windows 10.

Docker предоставляет 2 сборки:

  • Community Edition (полностью бесплатная версия)
  • Enterprise Edition (платно). Enterprise Edition содержит в себе дополнительные свистелки-перделки функции, которые, на данном этапе, точно не нужны. Функциональность, которую мы будем использовать совершенно не отличается в этих двух сборках.

После установки потребуется перезагрузка системы, и уже можно начинать полноценно работать с Докером.

Для того, чтобы проверить, запущен ли Docker, откроем командную строку (на Windows 10 — Нажмите кнопку windows, и начните писать командная строка)command-call
Где, напишем команду docker, и в случае успешно работающего докера, получим ответ command-docker
Дальше, нужно удостовериться, что вместе с докером, доступен так же, docker-compose, для этого, выполним команду:

docker-compose (вывод обеих команд будет примерно одинакового содержания).

Если вы используете Linux, то, docker-compose нужно будет устанавливать отдельно по инструкции.

Что такое Docker Image?

Docker образ (он же Docker Image), похож на Game Boy картридж — это просто программное обеспечение. Это стандартизированное программное обеспечение, которое запускается на любой приставке Game Boy. Вы можете дать игру вашему другу, и он сможет просто вставить картридж в приставку, и играть.

Как в случае с картриджами, бывают различные игры, так и Docker имеет различные образы ПО: ubuntu, php (который наследуется от оригинального образа Ubuntu), nodejs, и т.д.

Рассмотрим пример скачивания нашего первого образа.

Для этого, существует команда:
docker pull <IMAGE_NAME>, где <IMAGE_NAME> — имя скачиваемого образа

Зная эту команду, скачаем образ Ubuntu 18.10:

docker pull ubuntu:18.10

docker-pull-ubuntu-18

Эта команда сообщает Докеру о том, что нужно скачать образ Ubuntu 18.10 с Dockerhub.com — основной репозиторий Docker-образов, на котором вы и можете посмотреть весь их список и подобрать нужный образ для вашей программы.

Это как поездка за новым картриджем в магазин, только намного быстрее :).

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

docker images

docke-images

У вас, как и на скрине, должен появиться только что скачанный образ Ubuntu 18.10.
Как и обсуждалось выше, по поводу маленького размера образов, чистый образ Ubuntu при установке из Docker-образа, весит всего 74 МБ. Не чудо ли?

Проводя аналогии, команда docker images выглядит как коллекция картриджей от приставки, которые у вас есть сейчас:Depositphotos_194136098_xl-2015

Что такое Docker контейнер?

Теперь представьте, что мы обновили нашу приставку с Game Boy на GameCube. Игры хранятся на диске, который предназначен только для чтения самого образа игры. А прочие файлы (сохранения, кеш и т.д.) сохраняются внутри самой приставки, локально.

Так же, как и игра на диске, исходный Docker Image (образ) — неизменяемый.

Docker контейнер — это экземпляр запущенного образа. Аналогично тому, что вы вставляете диск в приставку, после чего игра начинается.

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

Depositphotos_194135642_xl-2015

Запуск Docker контейнера соответствует тому, что вы играете в свою Gamecube игру. Docker запускает ваш образ в своей среде, аналогично тому, как Gamecube запускает игру с диска, не модифицируя оригинальный образ, а лишь сохраняя изменения и весь прогресс в какой-то песочнице.

Для запуска контейнера существует команда:

docker run <image> <опциональная команды, которая выполнится внутри контейнера>

Давайте запустим наш первый контейнер Ubuntu:

docker run ubuntu:18.10 echo 'hello from ubuntu'

docker-run

Команда echo 'hello from ubuntu' была выполнена внутри среды Ubuntu. Другими словами, эта команда была выполнена в контейнере ubuntu:18.10.

Теперь выполним команду для проверки списка запущенных контейнеров:

docker ps

docker-ps

Здесь пустота… это потому что docker ps показывает только список контейнеров, которые запущены в данный момент (наш же контейнер выполнил одну команду echo 'hello from ubuntu' и завершил свою работу).

А для того, чтобы посмотреть список всех контейнеров без исключения, нужно добавить флаг -a, выполним:

docker ps -a

docker-ps-a

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

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

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

Давайте добавим немного интерактивности в наше обучение. Мы можем подключиться к консоли виртуальной ОС (Ubuntu 18.10), и выполнять любое количество команд без завершения работы контейнера, для этого, запустим команду:

docker run -it ubuntu:18.10 /bin/bash

Опция -it вместе с /bin/bash даёт доступ к выполнению команд в терминале внутри контейнера Ubuntu.

Теперь, внутри этого контейнера можно выполнять любые команды, применимые к Ubuntu. Вы же можете представлять это как мини виртуальную машину, условно, к консоли которой мы подключились по SSH.
В результате, теперь мы знаем возможные способы, как подключиться к контейнеру, и как выполнить команду в контейнере Docker-а.

Узнаём ID контейнера

Иногда является очень полезным узнать ID контейнера, с которым мы работаем. И как раз-таки, при выполнении команды docker run -it <IMAGE> /bin/bash, мы окажемся в терминале, где все команды будут выполняться от имени пользователя root@<containerid>.

Теперь, все команды буду выполняться внутри операционной системы Ubuntu. Попробуем, например, выполнить команду ls, и посмотрим, список директорий, внутри этого образа Ubuntu.docker-ubuntu-ls

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

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

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

Теперь откройте новое окно терминала (не закрывая и не отключаясь от текущего), и выполните команду docker ps
docker-ps-new-window

Только на этот раз вы можете увидеть, что контейнер с Ubuntu 18.10 в текущий момент запущен.

Теперь вернёмся назад к первому окну терминала (который находится внутри контейнера), и выполним:

mkdir /truedir  #создаст папку truedir
exit #выйдет из контейнера, и вернётся в основную ОС

Выполнив команду exit, контейнер будет остановлен (чтобы убедиться, можете проверить командой docker ps). Теперь, вы так же знаете, как выйти из Docker контейнера.

Теперь, попробуем ещё раз просмотреть список всех контейнеров, и убедимся, что новый контейнер был создан docker ps -adocker-ps--a2

Так же, для того, чтобы запустить ранее созданный контейнер, можно выполнить команду docker start <CONTAINER_ID>,

где CONTAINER_ID — id контейнера, который можно посмотреть, выполнив команду docker ps -a (и увидеть в столбце CONTAINER_ID)

В моём случае, CONTAINER_ID последнего контейнера = 7579c85c8b7e (у вас же, он будет отличаться)

Запустим контейнер командой:

docker start 7579c85c8b7e    #ваш CONTAINER_ID
docker ps
docker exec -it 7579c85c8b7e /bin/bash #ваш CONTAINER_ID

И теперь, если внутри контейнера выполнить команду ls, то можно увидеть, что ранее созданная папка truedir существует в этом контейнереdocker-exex-truedir

Команда exec позволяет выполнить команду внутри запущенного контейнера. В нашем случае, мы выполнили /bin/bash, что позволило нам подключиться к терминалу внутри контейнера.

Для выхода, как обычно, выполним exit.

Теперь остановим и удалим Docker контейнеры командами:
docker stop <CONTAINER_ID>
docker rm <CONTAINER_ID>

docker ps a   # просмотрим список активных контейнеров 
docker stop aa1463167766   # остановим активный контейнер
docker rm aa1463167766     # удалим контейнер
docker rm bb597feb7fbe     # удалим второй контейнер

В основном, нам не нужно, чтобы в системе плодилось большое количество контейнеров. Потому, команду docker run очень часто запускают с дополнительным флагом —rm, который удаляет запущенный контейнер после работы:

docker run -it --rm ubuntu:18.10 /bin/bash

Что такое DockerFile?

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

Dockerfile — это обычный конфигурационный файл, описывающий пошаговое создание среды вашего приложения. В этом файле подробно описывается, какие команды будут выполнены, какие образы задействованы, и какие настройки будут применены. А движок Docker-а при запуске уже распарсит этот файл (именуемый как Dockerfile), и создаст из него соответствующий образ (Image), который был описан.

К примеру, если вы разрабатывали приложение на php7.2, и использовали ElasticSearch 9 версии, и сохранили это в Dockerfile-е, то другие пользователи, которые запустят образ используя ваш Dockerfile, получат ту же среду с php7.2 и ElasticSearch 9.

С Dockerfile вы сможете подробно описать инструкцию, по которой будет воссоздано конкретное состояние. И делается это довольно-таки просто и интуитивно понятно.

Представьте, что вы играете в покемонов

Вы пытаетесь пройти первый уровень, но безрезультатно. И я, как ваш друг, хочу с этим помочь. У меня есть 2 таблетки варианта:

  1. Я дам вам файл сохранений, в котором игра ничинается со второго уровня. Всё что вам нужно — это загрузить файл.
  2. Я могу написать инструкцию, в которой опишу шаг за шагом процесс прохождения уровня. Это как рецепт, которому нужно будет следовать в точности, как описано. Эта инструкция могла бы выглядеть как-то так:

Инструкция прохождения первого уровня

  • Выбрать покемона Squirtle
  • Направляйтесь к лесу, к северу от города
  • Тренируйтесь, пока покемон не достигнет 10 уровня
  • Направляйтесь в Оловянный город
  • Подойдите к боссу, и победите его заклинанием Watergun

Что является более полезным? Я склоняюсь, что это второй вариант. Потому что он демонстрирует, как добиться желаемого состояния. Это не просто чёрный ящик, который переносит игру на второй уровень.

С докером вы так же имеете два варианта при создании образа:

  1. Вы можете запаковать ваш контейнер, создать из него образ (аналогично тому, что вы запишите на диск новую игру с собственными модификациями). Это похоже на способ, когда вы делитесь сохранениями напрямую.
  2. Или же, можно описать Dockerfile — подробную инструкцию, которая приведёт среду к нужному состоянию.

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

Пришло время попрактиковаться на реальном примере. Для начала, создадим файл cli.php в корне проекта с содержимым:

<?php
$n = $i = 5;

while ($i--) {
    echo str_repeat(' ', $i).str_repeat('* ', $n - $i)."\n";
}

И файл под названием Dockerfile, с содержимым:

FROM php:7.2-cli
COPY cli.php /cli.php
RUN chmod +x /cli.php
CMD php /cli.php

Имена команд в Dockerfile (выделенные красным) — это синтаксис разметки Dockerfile. Эти команды означают:

  • FROM — это как буд-то вы выбираете движок для вашей игры (Unity, Unreal, CryEngine). Хоть вы и могли бы начать писать движок с нуля, но больше смысла было бы в использовании готового. Можно было бы использовать, к примеру, ubuntu:18.10, в нашем коде используется образ php:7.2-cli, потому весь код будет запускаться внутри образа с предустановленным php 7.2-cli.
  • COPY — Копирует файл с основной системы в контейнер (копируем файл cli.php внутрь контейнера, с одноимённым названием)
  • RUN — Выполнение shell-команды из терминала контейнера (в текущем случае, присвоим права на выполнение скрипта /cli.php
  • CMD — Выполняет эту команду каждый раз, при новом запуске контейнера

Для просмотра полного списка команд можете перейти по ссылке

При написании Dockerfile, начинать следует с наиболее актуального существующего образа, дополняя его в соответствии с потребностями вашего приложения.
К примеру, мы могли не использовать образ php:7.2-cli, а могли взять ubuntu:18.10, последовательно выполняя команды в RUN одна за одной, устанавливая нужное ПО. Однако, в этом мало смысла, когда уже есть готовые сборки.

Для создания образа из Dockerfile нужно выполнить:
docker build <DOCKERFILE_PATH> --tag <IMAGE_NAME>
<DOCKERFILE_PATH> — путь к файлу Dockerfile (. — текущая директория),
<IMAGE_NAME> — имя, под которым образ будет создан

Выполним:

docker build . --tag pyramid

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

build-image-1

После того, как команда выполнилась, мы можем обращаться к образу по его имени, которое было указано в <IMAGE_NAME>, проверим список образов: docker images
images-piramyd

Теперь, запустим контейнер из нашего образа командой docker run pyramid
run-pyramid

Круто! Shell скрипт был успешно скопирован, и выполнен благодаря указанному в Dockerfile параметру CMD.

Сначала мы скопировали файл cli.php в Docker образ, который создался с помощью Dockerfile. Для того, чтобы удостовериться в том, что файл действительно был проброшен внутрь контейнера, можно выполнить команду docker run pyramid ls, которая в списке файлов покажет и cli.php.

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

Для этого, отредактируем файл cli.php, и изменим, чтобы количество аргументов принималось из командной строки. Отредактируем вторую строку на:

$n = $i = $argv[1] ?? 5; //а было $n = $i = 5
// это значит, что мы принимаем аргумент из консоли, а если он не получен, то используем по-умолчанию 5

После чего, пересоберём образ: docker build . --tag pyramid
И запустим контейнер: docker run pyramid php /cli.php 9, получив вывод ёлки пирамиды в 9 строк
cli_arg

Почему это работает?
Когда контейнер запускается, вы можете переопределить команду записанную в Dockerfile в поле CMD.

Наша оригинальная CMD команда, записанная в Dockerfile php /cli.php — будет переопределена новой php /cli.php 9.
Но, было бы неплохо передавать этот аргумент самому контейнеру, вместо переписывания всей команды. Перепишем так, чтобы вместо команды php /cli.php 7 можно было передавать просто аргумент-число.

Для этого, дополним Dockerfile:

FROM php:7.2-cli
COPY cli.php /cli.php
RUN chmod +x /cli.php
ENTRYPOINT ["php", "/cli.php"]
## аргумент, который передаётся в командную строку
CMD  ["9"]

Мы немного поменяли формат записи. В таком случае, CMD будет добавлена к тому, что выполнится в ENTRYPOINT.

["php", "/cli.php"] на самом деле запускается, как php /cli.php. И, учитывая то, что CMD будет добавлена после выполнения текущей, то итоговая команда будет выглядеть как: php /cli.php 9 — и пользователь сможет переопределить этот аргумент, передавая его в командную строку, во время запуска контейнера.

Теперь, заново пересоберём образ

docker build . --tag pyramid

И запустим контейнер с желаемым аргументом

docker run pyramid 3

result-3

Монтирование локальной директории в Docker-контейнер

Монтирование директории в Docker контейнер — это предоставление доступа контейнеру на чтение содержимого вашей папки из основной операционной системы. Помимо чтения из этой папки, так же, контейнер может её изменять, и такая связь является двусторонней: при изменении файлов в основной ОС изменения будут видны в контейнере, и наоборот.

Когда игра читает файлы сохранений, файловая система Game Cube внедряет их в текущий сеанс игры (представим это, даже если это не так). Игра может изменять файл сохранений, и это изменение отразится на файловой системе Game Cube, т.е. возникает двусторонняя связь.

Монтирование директории в контейнер позволяет ему читать и писать данные в эту директорию, изменяя её состояние.

Для того, чтобы смонтировать папку из основной системы в контейнер, можно воспользоваться командой
docker run -v <DIRECTORY>:<CONTAINER_DIRECTORY> ...,
где DIRECTORY — это путь к папке, которую нужно смонтировать,
CONTAINER_DIRECTORY — путь внутри контейнера.

Только путь к монтируемой папке должен быть прописан полностью: C:\projects\docker-example, или на *nix-системах можно воспользоваться конструкцией $(pwd)

Выполним команду:

docker run -it -v C:\projects\docker-example\cli:/mounted  ubuntu:18.10 /bin/bash
ls
ls mounted
touch mounted/testfile

При выполнении этой команды, указанная папка смонтируется в папку /mounted, внутри файловой системы контейнера, а команда touch mounted/testfile создаст новый файл под названием testfile, который вы можете увидеть из основной ОС.

Теперь вы можете увидеть, что после выполнения этой команды в текущей директории появился новый файл testfile. И это говорит о том, что двусторонняя связь работает — при изменении директории на основной ОС всё отразится на смонтированную папку внутри контейнера, а при изменениях изнутри контейнера всё отразится на основную ОС.

Монтирование папки позволяет вам изменять файлы вашей основной системы прямо во время работы внутри Docker контейнера.

Это удобная особенность, которая позволяет нам редактировать код в редакторе на основной ОС, а изменения будут сразу же применяться внутри контейнера.

Что такое Docker Volumes?

Docker Volumes — что-то похоже на карты памяти для Game Cube. Эта карта памяти содержит данные для игры. Эти карты съемные, и могу работать, когда Gamecube приставка выключается. Вы так же можете подключить различные карты памяти, содержащие разные данные, а так же, подключать к разным приставкам.

Вы можете вставить вашу карту внутрь приставки, точно так же, как и Docker Volume может быть прикреплён к любому из контейнеров.

С Docker Volum-ами мы имеем контейнер, который хранит постоянные данные где-то на нашем компьютере (это актуально, потому что после завершения работы контейнер удаляет все пользовательские данные, не входящие в образ). Вы можете прикрепить Volume-данные к любому из запущенных контейнеров.

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

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

Порты контейнеров

Docker позволяет нам получить доступ к какому-то из портов контейнера, пробросив его наружу (в основную операционную систему). По умолчанию, мы не можем достучаться к каким-либо из портов контейнера. Однако, в Dockerfile опция EXPOSE позволяет нам объявить, к какому из портов мы можем обратиться из основной ОС.

Для этого, на по-быстрому, запустим Docker-образ php-apache, который работает на 80 порту.

Для начала, создадим новую папку apache (перейдём в неё cd apache), в которой создадим файл index.php, на основе которого мы и поймём, что всё работает.

<?php
echo 'Hello from apache. We have PHP version = ' . phpversion() . PHP_EOL;

А так же, в этой папке создадим файл Dockerfile:

FROM php:7.2-apache
# Указываем рабочую папку
WORKDIR /var/www/html
# Копируем все файлы проекта в контейнер
COPY . /var/www/html
EXPOSE 80

Пробежимся по командам:
FROM: это вам уже знакомо, это образ с уже установленным php и apache
WORKDIR: создаст папку если она не создана, и перейдёт в неё. Аналогично выполнению команд mkdir /var/www/html && cd /var/www/html
EXPOSE: Apache по-умолчанию запускается на 80 порту, попробуем «прокинуть» его в нашу основную ОС (посмотрим как это работает через несколько секунд)

Для работы с сетью в Docker, нужно проделать 2 шага:

  • Прокинуть системный порт (Expose).
  • Привязать порт основной ОС к порту контейнера (выполнить соответствие).

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

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

EXPOSE в Докерфайле разрешает подключение к 80 порту контейнера — как разрешение HDMI подключения к PS4.

Выполним первый шаг прокидывания порт. Сбилдим контейнер:

docker build . --tag own_php_apache

И после этого, запустим контейнер:

docker run own_php_apache

apache_call

После чего, попробуем перейти по адресу localhost:80

Но, это не сработало, потому что мы ещё не выполнили 2 шаг по маппингу портов.

Выйдите из контейнера, нажав CTRL+C.

Если у вас проблемы с остановкой контейнера, в новом окне откройте терминал, выполните docker ps, найдите ID контейнера, который сейчас запущен, и выполните docker stop {CONTAINER_ID} (указав ваш ID контейнера)

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

docker run -p <HOST_PORT>:<CONTAINER_PORT>

И мы можем указать любое соответствие портов, но сейчас просто укажем, что порт системы 80 будет слушать 80 порт контейнера:

docker run -p 80:80 own_php_apache

Здесь, вы уже наверное заметили, что добавился новый параметр -p 80:80, который говорит Docker-у: я хочу, чтобы порт 80 из apache был привязан к моему локальному порту 80.

И теперь, если перейти по адресу localhost:80, то должны увидеть успешный ответ: apache_result

Оказывается, это даже легче, чем подключение HDMI-кабеля. Сейчас, можем попробовать выполнить запуск на разных портах:

docker run -p 8080:80 own_php_apache

apache_result_8080

Теперь, немного подчистим за собой: нужно остановить и удалить контейнеры, которые в даный момент мы запустили:

docker ps
docker stop <CONTAINER_ID> ...
docker rm <CONTAINER_ID> ...

Для *nix пользователей есть небольшой хак, который позволит остановить и удалить все контейнеры Docker:

docker stop $(docker ps -a -q)   # Остановит все контейнеры
docker rm $(docker ps -a -q)     # Удалит все остановленные контейнеры

Запомните, что любой, кто будет запускать этот код на своём компьютере, не должен иметь установленный PHP, всё что ему нужно — один только Docker.

Docker образ: прослойка данных и кеширование

Docker умнее, чем вы могли бы подумать :).

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

Каждая команда в Dockerfile сохраняется как отельный слой образа.

Рассмотрим это на примере нашего прошлого Dockerfile-а:

FROM php:7.2-apache
# Копирует код ядра
COPY . /var/www/html
WORKDIR /var/www/html
EXPOSE 80

Когда вы пишите свой Dockerfile, вы добавляете слои поверх существующего основного образа (указанного в FROM), и создаёте свой собственный образ (Image).

FROM: говорит Докеру взять за основу этот существующий образ. А все новые команды будут добавлены слоями поверх этого основного образа.
COPY: копирует файлы с основной ОС в образ
WORKDIR: устанавливает текущую папку образа в /var/www/html

Слой Образа Докера это как точка сохранения в игре Super Mario. Если вы хотите изменить какие-то вещи, произошедшие до этой точки сохранения, то вам придётся перезапустить этот уровень полностью. Если вы хотите продолжить прогресс прохождения, вы можете начать с того места, где остановились.

Docker начинает кешировать с «того места, где остановился» во время билдинга Dockerfile. Если в Докерфайле не было никаких изменений с момента последнего билдинга, то образ будет взят полностью из кеша. Если же вы измените какую-то строку в Dockerfile — кеш будет взят только тех слоёв команд, которые находятся выше изменённой команды.

Для иллюстрации этого, добавим новые строки в Dockerfile:

FROM php:7.2-apache
WORKDIR /var/www/html
# Copy the app code
COPY . /var/www/html
RUN apt-get update && apt-get upgrade -y && apt-get install -y curl php7.2-mbstring php7.2-zip php7.2-intl php7.2-xml php7.2-json php7.2-curl
RUN echo "Hello, Docker Tutorial"
EXPOSE 80

После чего, пересоберём образ:

docker build . --tag own_php_apache

cache
Выполнив эту команду, из вывода в консоль можете увидеть, что некоторые слои были взяты из кеша. Это как раз те команды, выше которых в Dockerfile не было добавлено/изменено содержимого.

И можно заметить, что в случае изменения Dockerfile, билдинг занимает больше времени, потому что не используется кеш. Где бы вы не написали команду, все закешированные команды, которые находятся ниже в Dockerfile, будут перебилжены заново. А те, что находятся выше, будут по-прежнему браться из кеша.

Когда вы используете команду COPY, она копирует указанную директорию в контейнер. И, в случае изменения содержимого любого из файлов этой директории, кеш команды COPY будет сброшен. Docker сверяет изменения во время билдинга в каждом из файлов. Если они были изменены, кеш будет сброшен, как и для всех последующих слоёв.

Если честно, то это действительно крутая функция. Docker следит за изменениями в файлах и использует кеш всегда, когда это нужно (когда были произведены изменения в каких-то из файлов). Изменение ваших файлов потенциально может затрагивать будущие команды, из-за чего, и все последующие слои билдятся заново, а не берутся из кеша.

Какие выводы из этого можно сделать:

  1. Команды, которые вероятнее всего не будут меняться в будущем, нужно помещать как можно выше в Dockerfile.
  2. Команды копирования данных нужно помещать ниже, потому что файлы при разработке изменяются довольно часто.
  3. Команды, которые требуют много времени на билдинг, нужно помещать выше.

В заключение, так же хочу сказать, как можно уменьшить размер слоёв Docker образов.
В Dockerfile вы можете иметь несколько команд (RUN) на выполнение:

RUN apt-get update
RUN apt-get install -y wget
RUN apt-get install -y curl

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

RUN apt-get update && apt-get install -y wget curl

Если команда становится длинной, и нечитаемой, то для переноса на следующую строку делаем так:

RUN apt-get update && apt-get install -y wget curl && \
    && apt-get clean -y \
    && docker-php-ext-install soap mcrypt pdo_mysql zip bcmath

Если же команда становится слишком большой, и неудобной для чтения, то можно создать новый shell скрипт, в который поместить длинную команду, и запускать этот скрипт одной простой командой RUN.

Технически, только команды ADD, COPY, и RUN создают новый слой в Docker образе, остальные команды кешируются по-другому

Что такое Docker-Compose?

Docker-compose это как дирижёр оркестра, где ваш оркестр — это набор контейнеров, которыми нужно управлять. Каждый контейнер имеет отдельную задачу, как и музыкальные инструменты в разных частях песни.

Docker Compose управляет контейнерами, запускает их вместе, в нужной последовательности, необходимой для вашего приложения.
Его можно назвать дирижёром в мире Docker-а.

Docker-compose организовывает совместных запуск контейнеров, как инструменты в групповой игре в определённых участках песни.

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

Docker-compose написан в формате YAML который по своей сути похож на JSON или XML. Но YAML имеет более удобный формат для его чтения, чем вышеперечисленные. В формате YAML имеют значения пробелы и табуляции, именно пробелами отделяются названия параметров от их значений.

Создадим новый файл docker-compose.yml, для рассмотрения синтаксиса Docker Compose:

version: '3'

services:
  app:
    build:
      context: .
    ports:
      - 8080:80

Теперь, построчно разберёмся с заданными параметрами, и что они значат:
version: какая версия docker-compose используется (3 версия — самая последняя на даный момент).
services: контейнеры которые мы хотим запустить.
app: имя сервиса, может быть любым, но желательно, чтобы оно описывало суть этого контейнера.
build: шаги, описывающие процесс билдинга.
context: где находится Dockerfile, из которого будем билдить образ для контейнера.
ports: маппинг портов основной ОС к контейнеру.

Мы можем использовать этот файл для билдинга нашего предыдущего образа apache:

docker-compose build

После выполнения этой команды, Docker спарсит файл docker-compose и создаст описанные сервисы на основе инструкций во вкладке build.

А context говорит о том, из какой директории мы берём Dockerfile для создания образа сервиса (в текущем случае — это означает текущую директорию ., но могло быть и /php-cli, /nginx, и т.д.).

И теперь, запустим эти сервисы, которые создали:

docker-compose up

В результате чего, сервер должен был запуститься, и стать доступным по адресу localhost:8080.

Теперь, отключитесь от консоли, нажав CTRL+C.

Когда контейнер под названием app запускается, docker-compose автоматически связывает указанные порты во вкладке ports. Вместо того, как мы делали ранее, выполняя -v 8080:80, docker-compose делает это за нас, получив информацию параметра ports. Docker-compose избавляет нас боли, связанной с указанием параметров в командной строке напрямую.

С docker-compose.yml мы переносим все параметры, ранее записываемые в командной строке при запуске контейнера в конфигурационный YAML файл.

В этом примере мы записали BUILD и RUN шаги для нашего сервиса в docker-compose.yml. И преимущество такого подхода ещё в том, что теперь для билдинга и для запуска этих сервисов нам нужно запомнить только 2 команды: docker-compose build и docker-compose up. При таком подходе не нужно помнить, какие аргументы нужно указывать, какие опции нужно задавать при запуске контейнера.

Теперь давайте сделаем нашу разработку немного легче. Сделаем, чтобы вместо постоянного перестроения образа при каждом изменении файлов, мы можем примонтировать нашу рабочую папку в контейнер.
Для этого, удалите строку COPY . /var/www/html с Dockerfile — теперь все файлы будут прокинуты из основной ОС. Новый Dockerfile будет иметь вид:

FROM php:7.2-apache
WORKDIR /var/www/html
RUN apt-get update && apt-get install -y wget
EXPOSE 80

Ранее мы рассматривали, как примонтировать папку в контейнер, для этого мы запускали контейнер с аргументом -v <HOST_DIRECTORY>:<CONTAINER_DIRECTORY>.
С Docker-compose мы можем указать напрямую в docker-compose.yml:

version: '3'
services:
  app:
    build:
      context: .
    ports:
      - 8080:80
    volumes:
      - .:/var/www/html

Добавленная строка примонтирует текущую директорию основой операционной системы к директории /var/www/html контейнера.

В отличие от указания путь в консоли, здесь можно указывать относительный путь (.), не обязательно указывать полный путь (C:\projects\docker-example\apache), как было ранее при ручном запуске контейнера.

Теперь, выполните по очереди команды:

docker-compose stop
docker-compose rm

При удалении, вас спросят, действительно ли удалять, напишите y и нажмите кнопку enter. Эти команды остановят и удалят все контейнеры, описанные в файле docker-compose.yml (то же самое, как мы ранее запускали docker stop <CONTAINER_ID> и docker rm <CONTAINER_ID>)

Теперь перебилдим сервисы, потому что мы изменили Dockerfile:

docker-compose build

И заново запустим:

docker-compose up

И опять, по адресу localhost:8080 поднимется наш сервер.

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

Чтобы в этом убедиться, изменим файл index.php, добавим в него скрипт нами любимой пирамиды:

<?php
$n = $i = $_GET['count'] ?? 4;
echo '<pre>';
while ($i--) {
    echo str_repeat(' ', $i).str_repeat('* ', $n - $i)."\n";
}
echo '</pre>';

И теперь, если перейти по адресу localhost:8080?count=10, то увидим, что пирамида выводится: apache_index_count

Монтирование вашей локальной папки как Docker Volume это основной метод как разрабатывать приложения в контейнере.

Так же, как мы ранее выполняли команды внутри контейнера, указывая аргументы -it ... /bin/bash. Docker-compose так же предоставляет интерфейс по удобному выполнению команд внутри конкретного контейнера. Для этого нужно выполнить команду:

docker-compose exec {CONTAINER_NAME} {COMMAND}

где, вместо {CONTAINER_NAME} нужно записать имя контейнера, под которым он записан в сервисах;
а вместо {COMMAND} — желаемую команду.

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

docker-compose exec php-cli php -v

Но, сделаем это на основе текущего Dockerfile:

docker-compose down # остановим контейнеры
docker-compose up -d # здесь используется опция -d которая сообщает, что контейнер должен висеть в режиме демона
docker-compose exec app apache2 -v

И в результате должны получить exec

Пока что, в docker-compose.yml описан только один сервис, потому разворачиваем мы только один контейнер. Но реальный файл docker-compose выглядит больше. К примеру, для Laravel он такой:

version: '3'
services:
  nginx:
    build:
      context: ./
      dockerfile: docker/nginx.docker
    volumes:
      - ./:/var/www
    ports:
      - "8080:80"
    depends_on:
      - php-fpm
  php-fpm:
    build:
      context: ./
      dockerfile: docker/php-fpm.docker
    volumes:
      - ./:/var/www
    depends_on:
      - mysql
      - redis
    environment:
      - "DB_PORT=3306"
      - "DB_HOST=mysql"
      - "REDIS_PORT=6379"
      - "REDIS_HOST=redis"
  php-cli:
    build:
      context: ./
      dockerfile: docker/php-cli.docker
    volumes:
      - ./:/var/www
    depends_on:
      - mysql
      - redis
    environment:
      - "DB_PORT=3306"
      - "DB_HOST=mysql"
      - "REDIS_PORT=6379"
      - "REDIS_HOST=redis"
    tty: true
  mysql:
    image: mysql:5.7
    volumes:
      - ./storage/docker/mysql:/var/lib/mysql
    environment:
      - "MYSQL_ROOT_PASSWORD=secret"
      - "MYSQL_USER=app"
      - "MYSQL_PASSWORD=secret"
      - "MYSQL_DATABASE=app"
    ports:
      - "33061:3306"
  redis:
    image: redis:3.0
    ports:
      - "6379:6379"

И при выполнении одной только команды docker-compose up, поднимутся 5 сервисов. В сравнении с тем, что мы бы вручную выполняли 5 раз команду docker run .... Так что, использование docker-compose в этом случае — очевидно. Так что, теперь, ещё один шаг позадчи, теперь вы знаете, что такое docker и docker compose, и для чего нужен каждый из них.

Как писать Микро Сервисы с Docker? Что такое микросервисы?

Docker найболее часто используемый инструмент для написания Микросервисов. Микросервисы — это архитектурный шаблон проектирования который следует философии «разделения ответственности».

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

Микросервис должен выполнять свою задачу в изолированной среде, управлять своей собственной локальной информацией, и быть независимым от общей системы настолько, насколько это возможно. В основном, каждый из микросервисов имеет собственную, отдельную базу данных (если она нужна).
Это позволяет создавать максимально гибкие и легко масштабируемые приложения.

Идея разделения по ответственности предоставляет преимущество в том, что команда разработчиков может работать параллельно, фокусируясь над разными компонентами.

В основном, микросервисы имеют канал коммуникации мужду собой, в виде REST API, который возвращает данные в JSON, или что-то типа того.

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

Использование микросервисов позволяет быстро масшабироваться под большой нагрузкой, без масшабирования остальных частей вашего приложения. То есть, такая архитектура позволяет вам масшабировать систему компонентно, там, где это требуется. В случае монолитной, единой системы, вам придётся масшабировать всё приложение.

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

Резюме

Я попытался написать эту статью максимально просто, построив всё объяснение на аналогиях и примерах их жизни. Эта статью можно считать простой инструкцией по работе с Docker. Помимо того, что я описал, как пользоваться Docker-ом, добавив несколько рабочих примеров, которые вы можете попробовать у себя на компьютере, я добавил много дополнительной информации, и некоторых тонкостей работы с Docker-ом. Надеюсь, что эта статья показала вам, что такое Docker, и с чем его едят. В следующей статья я затрону более продвинутые темы и приведу примеры.

  • Docker для windows как использовать
  • Docs microsoft com активация windows
  • Docker compose windows volume path
  • Document and settings в windows 10 отказано в доступе
  • Docker engine windows server 2019