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

«IT-специалист с нуля» наш лучший курс для старта в IT
Платформа Docker представлена в двух вариантах: бесплатная Community Edition под лицензией Apache и платная Enterprise Edition. Платная версия предназначена для коммерческого использования и распространяется по проприетарной лицензии. Изначально системой можно было пользоваться в Linux и UNIX-системах, но начиная с 2015 года в ПО добавили поддержку Windows.
Профессия / 8 месяцев
IT-специалист с нуля
Попробуйте 9 профессий за 2 месяца и выберите подходящую вам

Что такое контейнеры
Контейнеризация — это способ упаковки приложения и всех его зависимостей в один образ, который запускается в изолированной среде, не влияющей на основную операционную систему. С помощью контейнера можно отделить приложение от инфраструктуры: не важно, в каком окружении оно будет работать, есть ли там нужные зависимости и настройки, — разработчикам достаточно создать программу и упаковать все зависимости и настройки в единый образ. Затем ее можно разворачивать и запускать на других системах. Это ускоряет процесс разработки, сокращает промежуток между написанием кода и его выкладкой.
Контейнеризация напоминает виртуализацию, но технологии отличаются друг от друга. Виртуализация работает как отдельный компьютер со своей операционной системой и виртуальным оборудованием. Внутри одной операционной системы можно запустить другую. При контейнеризации виртуальная среда может запускаться прямо из ядра основной ОС и не виртуализирует оборудование. Поэтому контейнер может работать только в той же операционной системе, что и основная. Так как контейнеры не виртуализируют оборудование, они потребляют меньше ресурсов.
Как устроен Docker

На изображении представлена примерная структура платформы. Docker — клиент-серверное приложение. Это означает, что оно состоит из двух частей: сервера и клиента.
Сервер еще называют Docker-движком или демоном (daemon). Это фоновый процесс, который непосредственно управляет контейнерами. Именно демон создает, разворачивает и запускает контейнеры. Его можно сравнить с двигателем машины.
Клиент — это программа-интерфейс для командной строки, с которой взаимодействует пользователь. Он отдает команды через терминал. Клиент сообщает нужные сведения демону и отдает ему указания. Если продолжать аналогию с машиной, клиент — это руль и педали.
Клиент и сервер могут находиться на одном устройстве, а могут — на разных. Во втором случае клиент подключают к удаленному серверу через сокеты или API.

Курс для новичков «IT-специалист
с нуля» – разберемся, какая профессия вам подходит, и поможем вам ее освоить
Компоненты для контейнеризации
Docker работает со следующими компонентами.
Dockerfile. Это файл для предварительной работы, набор инструкций, который нужен для записи образа. В нем описывается, что должно находиться в образе, какие команды, зависимости и процессы он будет содержать.
Для сборки образа из Dockerfile используют команду:
docker build
Docker Image. Это образ — неизменяемый файл, из которого разворачивается контейнер. Для этого нужно запустить образ в клиенте с помощью специальной команды:
docker run
Docker Registry. Это реестр, или репозиторий — открытая или закрытая база образов. К ней можно подключиться через клиент Docker и загрузить нужный с помощью команды:
docker pull
При запуске команды docker run программа сначала проверяет, есть ли нужный образ в локальном хранилище. Если его нет, она сама находит файл в репозитории и скачивает на компьютер.
Docker Container. Это уже готовый и развернутый контейнер, который находится на каком-либо устройстве.

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

DevOps-инженер — связующее звено между всеми этапами создания продукта. Станьте незаменимым специалистом
за 6 месяцев.
Docker контейнер
Docker контейнер — это стандартизированный, изолированный и портативный пакет программного обеспечения, который включает в себя все необходимое для запуска приложения, включая код, среду выполнения, системные инструменты, библиотеки и настройки. Контейнеры позволяют упаковать приложение и все его зависимости в единый объект, который может быть запущен на любой системе, поддерживающей Docker, без изменения среды выполнения.
Преимущества использования Docker контейнеров:
- Изоляция: Контейнеры изолируют приложения друг от друга и от хост-системы, что уменьшает возможные конфликты между зависимостями и обеспечивает более надежную среду выполнения.
- Портативность: Контейнеры могут быть созданы и запущены на различных системах без изменений, что делает развертывание приложений более простым и надежным.
- Эффективность использования ресурсов: Контейнеры используют общие ресурсы операционной системы и разделяют ядро, что делает их более эффективными по сравнению с виртуальными машинами.
- Масштабируемость: Контейнеры легко масштабируются горизонтально, позволяя быстро добавлять экземпляры приложения в ответ на увеличение нагрузки.
- Управление версиями: Контейнеры позволяют управлять версиями приложений и их зависимостей, что упрощает процесс развертывания и обновления.
Чем контейнеризация отличается от виртуализации
Контейнеры и виртуальные машины (ВМ) — это методы изоляции приложений и окружений. Docker использует виртуализацию на уровне операционной системы, позволяя запускать приложения в изолированных контейнерах, которые делят ядро ОС с хост-системой. ВМ, напротив, создают полные виртуальные компьютеры с отдельными ОС и ресурсами.
Это означает, что Docker-контейнеры более легкие, потому что они не требуют дублирования всей ОС, как ВМ. Контейнеры также быстрее запускаются и имеют меньший объем, что делает их более эффективными в ресурсоемких средах. Однако ВМ предоставляют большую изоляцию, так как каждая ВМ имеет свою собственную ОС и не зависит от хост-системы.
Таким образом, Docker контейнеры предоставляют легковесное и быстрое решение для изоляции приложений, в то время как виртуальные машины обеспечивают более глубокую изоляцию за счет полной виртуализации.
| Характеристика | Docker контейнеры | Виртуальные машины |
|---|---|---|
| Уровень изоляции | Операционная система | Аппаратное обеспечение |
| Ресурсоемкость | Меньше | Больше |
| Запуск и остановка | Быстрее | Медленнее |
| Размер | Меньше | Больше |
| Изоляция | Менее глубокая | Глубокая |
| Нагрузка на хост-систему | Меньше | Больше |
| Совместимость | Ограниченная | Высокая |
| Виртуализация ОС | Да | Да |
| Гипервизор | Не требуется | Требуется |
Эта таблица демонстрирует основные различия между Docker контейнерами и виртуальными машинами.
Docker и виртуальные машины не всегда хорошо сочетаются вместе. Иногда в практике используется подход, при котором сервер разделяется на виртуальные машины, на которых запускаются контейнеры. Однако такая двойная виртуализация приводит к лишнему расходу ресурсов. Если в организации установилась такая практика, то вместо гипервизора можно использовать Kubernetes, который будет устанавливать приложения непосредственно на физическое оборудование.
Обычно крупные компании работают с виртуальными машинами, развернутыми на физическом оборудовании в центрах обработки данных. Инженеры инфраструктуры создают виртуальные компьютеры и настраивают на них инфраструктуру. Используя оркестраторы, можно избавиться от этого дополнительного уровня.
Если у вас есть избыток ресурсов, то можно установить Docker на виртуальную машину, чтобы обеспечить изоляцию между приложениями.
Что такое Docker Hub
Образ можно создать самостоятельно с помощью Dockerfile или уже готового контейнера, в котором произошли какие-либо изменения, а также скачать из открытого репозитория Docker Hub.
Разработчики со всего мира могут выкладывать Docker-образы. Другие пользователи имеют возможность скачать их, развернуть в контейнеры и использовать на своих машинах.
Сейчас в Docker Hub более 100 тысяч образов. Некоторые из них загрузили в базу официальные разработчики. Это, например, Docker Images для mySQL или GitLab.
Поддержка репозитория уже включена в Docker. Это значит, что достаточно написать команду для установки какой-либо программы, и система сама начнет искать ее в базе данных. По умолчанию это Docker Hub, но платформу можно настроить и под другие репозитории. Например, под внутренние корпоративные базы.
Docker Compose: множественные образы
Считается, что один контейнер должен выполнять одну функцию. Поэтому для настройки сложной среды понадобится несколько образов.
Можно скачать их вручную и настроить либо воспользоваться Docker Compose — инструментом для работы с множественными образами и многоконтейнерными приложениями.

ПО позволяет управлять несколькими образами и контейнерами как одним. С помощью Docker Compose можно создать файл YAML для определения служб и с одной командой запускать и останавливать все что нужно. Инструмент способен ускорить разработку: в многоконтейнерных приложениях количество контейнеров может доходить до нескольких десятков.
DevOps-инженер
Помогайте компаниям быстрее выпускать качественный продукт

Как хранятся данные в Docker
При остановке и перезапуске контейнера можно потерять часть рабочей информации, которая в нем записана. Чтобы этого избежать, программисты стремятся разрабатывать приложения с минимальным использованием хранилищ внутри контейнеров. Но обойтись без хранения данных получается не всегда, а от основной системы контейнер изолирован. Существует несколько способов решить проблему.
Docker Volumes. Это тома — способ хранения информации, который рекомендуют использовать разработчики платформы. Внутри лежат файлы и другие данные. Тома можно подключать к разным контейнерам, выбирать специальные драйверы и хранить информацию не на хосте, а в облаке или на удаленном сервере.
В Linux тома по умолчанию находятся в /var/lib/docker/volumes/. Другие программы могут получить к ним доступ только через контейнер, а не напрямую. Для создания и управления томами используются средства Docker: команда docker volume create, указание тома при создании контейнера в Dockerfile или docker-compose.yml.
Bind Mount. Более простой способ реализовать удаленное хранение памяти — папки, которые монтируются в контейнер прямо с хоста. Этот вариант используют для передачи конфигурационных файлов или в процессе разработки. Программист может писать код в среде хоста, а потом передавать его в контейнер.
Tmpfs и Named Pipes. Так называется особое файловое хранилище, которое есть только в системах Linux. Как правило, оно используется не для хранения файлов, а для обеспечения безопасности. Tmpfs — временное хранилище. Стоит остановить контейнер — данные будут потеряны. Доступ к Tmpfs очень быстрый, поэтому хранилище используют, чтобы оптимизировать работу контейнера.
Named Pipes — это именованные каналы. Через них с Docker могут работать только пользователи Windows.
Задачи, которые решает Docker
Развертывание среды или приложения
Docker позволяет перенести приложение со всеми зависимостями на другую систему с помощью пары команд в терминале. Настройка зависимостей вручную занимает больше времени. Также с помощью Docker можно быстро развернуть рабочую среду с определенными настройками. Существуют «системные контейнеры», которые содержат дистрибутивы ОС.
Изолированный запуск
Docker позволяет запустить приложение отдельно от всей системы без конфликтов с другими программами. Программа становится практически автономной и не вызывает ошибок зависимости.
Контроль ресурсов
Еще одна возможность Docker — распределение ресурсов между разными приложениями. Неизолированные процессы могут конкурировать за память и вычислительные мощности процессора. Изолированные друг от друга программы не делают этого. Docker позволяет эффективнее использовать ресурсы и не допускать конфликтов.
Повышение безопасности
Если код контейнерного приложения окажется небезопасным, это не навредит серверу-хосту. При правильной настройке контейнера деятельность кода не затронет основную систему. Даже фатальная ошибка не повлияет на работоспособность остальных служб и программ.
Работа с микросервисами
Микросервисная архитектура — такой тип организации ПО, при котором функции большого приложения разделяются на маленькие независимые программные модули. Они общаются друг с другом с помощью протоколов, но в целом работают автономно друг от друга. Docker подходит для реализации архитектуры этого типа: каждый микросервис упаковывается в отдельный контейнер, который можно настроить и протестировать, запустить или остановить отдельно от других.
Читайте также Возможна ли цифровая трансформация в нынешних условиях?
Ускорение цикла разработки
Технологии контейнеризации помогают программировать быстрее. На настройку среды, разворачивание приложений под разными платформами тратится меньше времени. В результате повышается производительность всей команды.
Управление сложными системами
Для автоматизации большинства процессов со сложными контейнерными приложениями используются платформы оркестрации. Многие возможности специального ПО завязаны на контейнеризации и функциях Docker.
Например, платформы автоматизируют разворачивание контейнеров, их настройку и масштабирование. Это нужно, так как программная архитектура становится более сложной. Приложения могут состоять из сотен отдельных контейнеров, каждый из которых нужно развернуть и настроить. Поддержка таких приложений вручную занимает много времени.
Масштабирование
Это еще одна задача для платформ оркестрации. Во многих из них поддерживается автоматическое масштабирование систем под разные площадки и условия. Пример такой платформы — Kubernetes, которая часто используется в связке с Docker.
Автомасштабирование помогает быстро оптимизировать сектор под повышенную нагрузку. Если сайт неожиданно получит больше трафика, чем обычно, система перераспределит ресурсы и сервисы адаптируются.
Как начать работу с Docker
Docker доступен для Linux, Windows, Mac. Чтобы скачать установочный файл, нужно перейти по ссылке и выбрать подходящую версию. Подробную инструкцию по установке можно найти в официальной документации.
Расскажем про работу с «первым контейнером». Это практически аналог “Hello, World” для Docker: скачивание и разворачивание популярного образа из репозитория. Обычно используется какой-либо дистрибутив Linux:
docker run ubuntu echo “Hi, I'm Ubuntu”
Запись означает «Разверни образ Ubuntu в контейнер и выполни в нем команду echo “Hi, I’m Ubuntu” ». Эта команда написана на bash — языке сценариев Linux.
- Docker-клиент получит эту запись и отправит инструкции демону.
- Тот проверит, есть ли образ Ubuntu на компьютере. Если его не найдется, программа скачает его из Docker Hub и сохранит.
- Затем движок развернет образ в контейнер — внутри изолированно от основной системы запустится Ubuntu.
- И уже внутри Ubuntu выполнится команда echo “Hi, I’m Ubuntu” . Она выведет в консоль надпись “Hi, I’m Ubuntu” .
Это наиболее простой пример — возможностей у Docker намного больше.
Недостатки Docker
Высокая потребность в ресурсах
Docker добавляет дополнительный слой абстракции и требует дополнительных вычислительных ресурсов. Это означает, что нужно балансировать между удобством и оптимальным использованием ресурсов.
Оркестрация для крупных приложений
Docker хорош для управления небольшим числом контейнеров. Однако при наличии 50–100 сервисов может потребоваться оркестратор, так как Docker не обладает достаточными инструментами для эффективного управления ресурсами и обеспечения надежности в случае разных сценариев обновления контейнеров.
Большие приложения с микросервисной архитектурой часто используют оркестраторы, такие как Kubernetes или OpenShift, чтобы обеспечить более высокий уровень управления и надежности. Docker в таких случаях часто оказывается недостаточным.
Сложности на Windows и macOS
Docker, изначально разработанный для Linux, может столкнуться с проблемами совместимости на других ОС. Кроме того, установка Docker на Windows иногда может конфликтовать с VirtualBox, что может вызвать трудности при настройке.
IT-специалист с нуля
Наш лучший курс для старта в IT. За 2 месяца вы пробуете себя в девяти разных профессиях: мобильной и веб-разработке, тестировании, аналитике и даже Data Science — выберите подходящую и сразу освойте ее.

Статьи по теме:
Почему писать игры лучше на C#, а для создания крупных проектов подходит Java
Почему для больших проектов обычно выбирают Java, средних — PHP, а быстро развивающихся стартапов — Ruby или Go
Что такое Docker: для чего он нужен и где используется
Docker — один из самых известных инструментов по работе с контейнерами. В статье мы расскажем, что такое контейнеры, где они применяются и чем могут быть полезны. Managed Kubernetes помогает разворачивать контейнерные приложения в инфраструктуре Selectel. Сосредоточьтесь на разработке, а мы займемся рутинными операциями по обеспечению работы вашего кластера Kubernetes. В конце будет практическая часть: мы […]

Docker — один из самых известных инструментов по работе с контейнерами. В статье мы расскажем, что такое контейнеры, где они применяются и чем могут быть полезны.
Managed Kubernetes помогает разворачивать контейнерные приложения в инфраструктуре Selectel. Сосредоточьтесь на разработке, а мы займемся рутинными операциями по обеспечению работы вашего кластера Kubernetes.
В конце будет практическая часть: мы создадим небольшое приложение, обернем его в образ и запустим. Все действия будем показывать на примере виртуальной машины облачной платформы Selectel.
Контейнеры — хорошая альтернатива аппаратной виртуализации. Они позволяют запускать приложения в изолированном окружении, но при этом потребляют намного меньше ресурсов.
В первую очередь эта статья будет полезна тем, кто вообще не знаком с контейнерами или Docker. Мы расскажем самые базовые вещи, а наш пример по созданию приложения будет довольно простым. Но это позволит вам понять основы Docker и затем двигаться дальше — изучать более сложные материалы.
Что такое контейнеры
Прежде чем рассказывать про Docker, нужно сказать несколько слов о технологии контейнеризации.
Контейнеры — это способ стандартизации развертки приложения и отделения его от общей инфраструктуры. Экземпляр приложения запускается в изолированной среде, не влияющей на основную операционную систему.
Разработчикам не нужно задумываться, в каком окружении будет работать их приложение, будут ли там нужные настройки и зависимости. Они просто создают приложение, упаковывают все зависимости и настройки в некоторый единый образ. Затем этот образ можно запускать на других системах, не беспокоясь, что приложение не запустится.
Docker — это платформа для разработки, доставки и запуска контейнерных приложений. Docker позволяет создавать контейнеры, автоматизировать их запуск и развертывание, управляет жизненным циклом. Он позволяет запускать множество контейнеров на одной хост-машине.
Контейнеризация похожа на виртуализацию, но это не одно и то же. Виртуализация запускает полноценный хост на гипервизоре со своим виртуальным оборудованием и операционной системой. При этом внутри одной ОС можно запустить другую ОС. В случае контейнеризации процесс запускается прямо из ядра основной операционной системы и не виртуализирует оборудование. Это означает, что контейнеризованное приложение может работать только в той же ОС, что и основная. Контейнеры не виртуализируют оборудование, поэтому потребляют меньше ресурсов.
Преимущества использования контейнеров Docker
Контейнеры упрощают работу как программистам, так и администраторам, которые развертывают эти приложения.
Docker решает проблемы зависимостей и рабочего окружения
Контейнеры позволяют упаковать в единый образ приложение и все его зависимости: библиотеки, системные утилиты и файлы настройки. Это упрощает перенос приложения на другую инфраструктуру.
Например, разработчики создают приложение в системе разработки — там все настроено, приложение работает. Когда оно готово, его нужно перенести в систему тестирования, а затем в продуктивную среду. Если в одной из них нет нужной зависимости, приложение не будет работать. Программистам придется отвлечься от разработки и совместно с командой поддержки разобраться в ситуации.
В контейнерах такой проблемы нет, так как они содержат в себе все необходимое для запуска приложения. Специалисты занимаются разработкой, а не решением инфраструктурных проблем.
Изоляция и безопасность
Контейнер — это набор процессов, изолированных от основной операционной системы. Приложения работают только внутри контейнеров и не имеют доступа к основной операционной системе. Это повышает безопасность приложений:они не смогут случайно или умышленно навредить основной системе. Если приложение в контейнере завершится с ошибкой или зависнет, это никак не затронет основную ОС.
Ускорение и автоматизация развертывания приложений и масштабируемость
Контейнеры упрощают развертывание приложений. В классическом подходе для установки программы нужно совершить несколько действий: выполнить скрипт, изменить файлы настроек и так далее. В этом процессе не исключена вероятность человеческой ошибки: пользователь запустит скрипт два раза, перепутает последовательность или что-то не поймет. Контейнеры позволяют полностью автоматизировать этот процесс, так как включают в себя все нужные зависимости и порядок выполнения действий.
Также контейнеры упрощают развертывание на нескольких серверах. В классическом подходе для того, чтобы развернуть одно и то же приложение на нескольких машинах, нужно будет повторять одни и те же действия. Контейнеры избавляют от этой рутинной работы и позволяют автоматизировать развертывание.
Контейнеры приближают к микросервисной архитектуре
Контейнеры хорошо вписываются в микросервисную архитектуру. Это подход к разработке, при котором приложение разбивается на небольшие компоненты, по возможности независимые. Обычно противопоставляется монолитной архитектуре, где все части системы сильно связаны друг с другом.
Это позволяет разрабатывать новую функциональность быстрее, ведь в случае с монолитной архитектурой изменение какой-то части может затронуть всю остальную систему.
Docker compose — одновременно развернуть несколько контейнеров
Docker-compose позволяет разворачивать и настраивать несколько контейнеров одновременно. Например, для веб-приложения нужно развернуть стек LAMP: Linux + Apache, MySQL, PHP. Каждое из приложений — это отдельный контейнер для ОС Linux. Но в этой ситуации нам нужны именно все контейнеры вместе, а не отдельно взятое приложение. Docker-compose позволяет развернуть и настроить все приложения одной командой, а без него пришлось бы разворачивать и настраивать каждый контейнер отдельно.
Создайте кластер любой конфигурации в несколько кликов
Упростите процесс развертывания, масштабирования и обслуживания контейнерной инфраструктуры с Managed Kubernetes.
Хранение данных в Docker
Одна из главных особенностей контейнеров — эфемерность. Это означает, что контейнеры могут быть в любой момент остановлены, перезапущены или уничтожены. При этом все накопленные данные в контейнере будут потеряны. Поэтому приложения нужно разрабатывать так, чтобы они не полагались на хранилище данных в контейнере, это называется принципом Stateless.
Это хорошо подходит для приложений или сервисов, которые не сохраняют результаты своей работы. Например, функции расчета или преобразования данных: им на вход поступил один набор данных, они его преобразовали или рассчитали и вернули результат. Все, ничего никуда сохранять не нужно.
Но далеко не все приложения такие, и есть много данных, которые нужно сохранить. В контейнерах для этого предусмотрены несколько способов.
Тома (Docker volumes)
Это способ, при котором Docker сам создает директории для хранения данных. Их можно сделать доступными для разных контейнеров, чтобы они могли обмениваться данными. По умолчанию эти директории создаются на хост-машине, но можно использовать и удаленные хранилища: файловый сервер или объектное хранилище.
Монтирование каталога (bind mount)
В этом случае директория сначала создается на хост-машине а уже потом монтируется в контейнеры.
Но этот способ не рекомендуется, потому что он усложняет резервное копирование, миграцию и совместное использование данных несколькими контейнерами.
Архитектура (компоненты) Docker
Теперь расскажем подробнее про компоненты, из которых состоит Docker.
Docker daemon
Это некоторый резидентный процесс, который запущен на хост-машине постоянно. Он владеет всей инфраструктурой, а также предоставляет интерфейс взаимодействия с контейнерами, включающего создание и удаление, запуск и остановку.
В ранних версиях платформы Docker можно встретить упоминание о dockerd, но на текущий момент демоны уже успели разбиться на отдельные проекты. Все чаще можно встретить его современника — containerd.
Docker client (клиент)
Это интерфейс командной строки для управления Docker daemon. Мы пользуемся этим клиентом, когда создаем и разворачиваем контейнеры, а клиент отправляет эти запросы в Docker daemon.
Docker image (образ)
Это неизменяемый файл (образ), из которого разворачиваются контейнеры. Приложения упаковываются именно в образы, из которых потом уже создаются контейнеры. В технической литературе можно также встретить описание image как шаблона запуска процесса.
Приведем аналогию на примере установки операционной системы. В дистрибутиве (образе) ОС есть все, что необходимо для ее установки. Но этот образ нельзя запустить, для начала его нужно «развернуть» в готовую ОС. Так вот, дистрибутив для установки ОС — это образ, а установленная и работающая ОС — это контейнер. Но контейнеры обычно разворачиваются одной командой — это намного проще и быстрее, чем установка ОС.
Docker container (контейнер)
Это уже развернутое из образа и работающее приложение.
Docker Registry
Это репозиторий с образами. Разработчики создают образы своих программ и выкладывают их в репозиторий, чтобы их можно было скачать и воспользоваться ими. Распространенный публичный репозиторий — Docker Hub. В нем собраны образы множества популярных программ или платформ: базы данных, веб-серверы, компиляторы, операционные системы и так далее. Также можно создать свой приватный репозиторий, например внутри компании. Разработчики будут размещать там образы, которые будут использоваться всей компанией.
Dockerfile
Dockerfile — это инструкция для сборки образа. Это простой текстовый файл, содержащий по одной команде в каждой строке. В нем указываются все программы, зависимости и образы, которые нужны для разворачивания образа.
Для примера рассмотрим Dockerfile, который мы будем использовать далее в этой статье чтобы развернуть собственное приложение:
FROM python:3 COPY main.py / CMD [ "python", "./main.py" ]
Первая строчка означает, что за основу мы берем образ с названием python версии 3 это называется базовый образ. Docker найдет его в docker registry, скачает и будет использовать за основу. Вторая строчка означает, что нужно скопировать файл main.py в корень файловой системы контейнера. Третья строчка означает, что нужно запустить python и передать ему в качестве параметра название файла main.py.
Далее рассмотрим примеры нескольких команд докер и что происходит, когда мы их выполняем.

Все эти команды выполняются в Docker client, который отправляет их в Docker daemon:
- Команда docker build (зеленая стрелка) читает dockerfile и собирает образ.
- Команда docker pull (красная стрелка) скачивает образ из docker registry. По умолчанию docker скачивает образы из публичного репозитория Docker Hub. Но можно создать свой репозиторий и настроить докер, чтобы он работал с ним.
- Команда docker run (черная стрелка) берет образ и запускает из него контейнер.
Создаем виртуальную машину для работы с Docker
Перейдем к практической части. Мы установим докер, создадим приложение, обернем его в контейнер и запустим. Мы для примера будем использовать виртуальную машину на платформе Selectel.
В панели управления заходим в раздел «Облачная платформа» — «Серверы», нажимаем кнопку «Создать сервер».

На следующем экране выбираем параметры сервера: имя, регион, ОС, параметры производительности и так далее. Сейчас для нас важны параметры «Источник» — выбираем ОС Ubuntu 20.04 и «Конфигурация» — выбираем 2 vCPU и 8 ГБ оперативной памяти.

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

После этого внизу страницы нажимаем кнопку «Создать». Виртуальная машина создается за несколько минут, и после того, как она перейдет в статус ACTIVE, к ней можно подключаться по SSH.

Установка Docker
Мы рассмотрим установку докера на примере Ubuntu. Если у вас другой дистрибутив Linux или операционная система — ищите соответствующую инструкцию на официальном сайте.
Для начала синхронизируем пакетную базу apt и установим нужные зависимости:
sudo apt-get update
sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ gnupg \ lsb-release
Далее импортируем GPG-ключ для репозитория docker:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
Теперь добавим новый репозиторий в список apt:
echo \ "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Теперь можно устанавливать докер:
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
По умолчанию, доступ к docker daemon есть только у пользователя root. Чтобы с докером могли работать и другие пользователи, их нужно добавить в специальную группу — docker. Выполните эту команду из под обычного пользователя:
sudo usermod -aG docker $USER
После этого необходимо перелогиниться, чтобы изменение вступило в силу.
Запуск контейнера
Теперь попробуем запустить какое-нибудь готовое приложение. Выполните команду:
docker run ubuntu echo 'hello from ubuntu'
Команда docker run создает и запускает контейнер из образа. В этом примере мы создаем контейнер из образа ubuntu, затем выполняем в нем команду echo ‘hello from ubuntu’. Но так как у нас чистая установка докера и мы не скачали ни одного образа, докер сначала найдет этот образ в публичном репозитории Docker Hub, скачает, а потом создаст из него контейнер. В следующий раз, когда нам понадобится образ ubuntu, докер уже не будет его скачивать.
После выполнения команды в терминале появится строка hello from ubuntu, и контейнер сразу остановится. Теперь выполним другую команду:
docker run -it ubuntu
Эта команда запустит контейнер в интерактивном режиме, то есть контейнер запустится и будет ждать дальнейших команд. При этом мы окажемся внутри операционной системы контейнера: запустится оболочка (bash), и мы сможем выполнять какие-то команды внутри контейнера. Чтобы выйти из контейнера, введите команду exit.
Создание собственного образа и запуск контейнера
Теперь создадим HelloWorld-приложение на Python, обернем его в образ и запустим.
Для начала создадим директорию, в которой мы будем работать и перейдем в нее:
mkdir first-docker-app
cd first-docker-app
Создадим файл main.py и запишем в него одну строчку кода:
echo 'print("Hello from python");' >> main.py
Проверим, что наша программа работает. Для этого выполним команду:
python main.py
В консоли должно выйти сообщение Hello from python. Это и есть наше простое приложение. Теперь нужно обернуть его в докер-образ. Для этого создадим файл Dockerfile и напишем в нем три строчки:
FROM python:3 COPY main.py / CMD [ "python", "./main.py" ]
В первой строке мы указываем образ, который берем за основу. Так как мы пишем приложение на Python, нужно чтобы в нашем образе он уже был установлен. Самый простой способ это сделать — использовать готовый официальный образ с Docker Hub. Цифра 3 — это тег. Он означает, что нужно использовать третью версию Python. Вместо этого можно было бы использовать тег latest, который означает самую последнюю версию, или можно было указать номер конкретной версии, например 3.8.8.
Во второй строчке мы копируем наш файл main.py в корневую директорию образа.
Третья строчка — запускаем python и передаем ему в качестве параметра имя нашего файла.
Теперь из этого докер-файла можно собирать образ. Выполним команду:
docker build -t first-docker-app .
Параметр -t обозначает имя нашего образа, мы назвали его first-docker-app.
Так как у нас еще нет скачанного образа python, то докер сам скачает его из Docker Hub и затем будет использовать его в качестве основы для создания нашего образа.
Проверим список установленных у нас образов:
docker images
Мы увидим, что у нас установлено три образа:
REPOSITORY TAG IMAGE ID CREATED SIZE first-docker-app latest 649cceb4dfd2 4 seconds ago 885MB python 3 b1aa63f57d3c 2 days ago 885MB ubuntu latest 8e428cff54c8 4 days ago 72.9MB
first-docker-app — это наш образ, который мы только что создали. python — это образ python, который докер автоматически скачал чтобы собрать наш образ. ubuntu — образ, который мы пробовали для запуска готового приложения.
Теперь создадим контейнер из нашего образа и запустим его:
docker run first-docker-app
В результате нам выведется результат: Hello from python.
Итог: Мы создали свое приложение, упаковали его в докер-образ и запустили. Конечно, это очень простой пример. Наша программа состоит всего из одной строчки, а dockerfile из трех. Но это позволяет понять базовые принципы работы докера, как он устроен, как создавать свои образы и запускать контейнеры.
Заботимся о работе и доступности вашего кластера даже в пиковые нагрузки
Managed Kubernetes — это готовый сервис Selectel. Мы отвечаем за автоматическое обновление кластера, несем ответственность по SLA за его доступность и бесперебойную работу Control Plane.
Список полезных команд
Теперь приведем список полезных команд, которые могут пригодиться при работе с докером.
Посмотреть список всех контейнеров
Эта команда выведет список всех докер контейнеров:
docker ps
Но по умолчанию выводятся только работающие контейнеры. Чтобы вывести все, в том числе и остановленные, используйте опцию -a:
docker ps -a
Остановить и удалить все докер контейнеры
Чтобы удалить контейнеры, сначала их нужно остановить. Первая команда остановит запущенные контейнеры, если они есть. А вторая команда — удалит их.
docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)
Запустить контейнер с последующим удалением
По умолчанию контейнеры после завершения работы останавливаются, но не удаляются. Они сохраняют свое состояние и при необходимости их можно запустить снова. Чтобы контейнер удалялся сразу после остановки, добавьте к команде docker run параметр —rm, например:
docker run --rm ubuntu echo 'hello from ubuntu'
Посмотреть список всех скачанных образов
docker images
Удалить докер образ
docker rmi
Если у этого образа есть контейнеры, пусть даже остановленные, докер не позволит его удалить. Он выдаст сообщение:
unable to remove repository reference (must force) - container is using its
Чтобы принудительно удалить образ, добавьте флаг -f:
docker rmi -f
Получить список всех контейнеров, созданных из определенного образа
docker ps -a --filter ancestor=
Итог
В статье мы рассмотрели, что такое контейнеры и Docker, как они работают и чем отличаются от виртуализации. Также мы создали простое python-приложение, обернули его в образ и запустили контейнер.
Мы рассказали основы технологий, но не затронули более сложные темы, вроде Docker Swarm, настройку сети или настройки процессов CI/CD. Но этого вполне достаточно, чтобы погрузиться в основы технологий.
Что такое контейнер. Принципы контейнерной виртуализации
В IT-сфере есть понятия, схожие с теми, которые мы используем в обыденной жизни, но имеющие иное значение. Одно из таких понятий — контейнер. Давайте вместе разберемся, что это такое, зачем нужны контейнеры и для каких целей их лучше использовать.
Прежде чем говорить о том, что такое контейнеризация, нужно разобраться в том, что такое виртуализация. Без объяснения этого понятия логика работы контейнеров будет непонятна.
Облачные серверы нового поколения
Виртуализация KVM, почасовая оплата, резервные копии, готовые шаблоны, 10 доступных ОС на выбор!

Что такое виртуализация
Виртуализация — это технология, с помощью которой на одном физическом устройстве (компьютере или сервере) можно создать несколько виртуальных компьютеров. Иначе говоря, на компьютере с одной операционной системой можно запустить несколько других операционных систем или приложений. ОС запускаются в виртуальной среде, что позволяет им работать на одном устройстве изолированно друг от друга. Операционную систему компьютера, на котором работает виртуальная среда, называют хост-системой, а операционную систему, которая запускается в этой виртуальной среде — гостевой системой. Хостовая и гостевая ОС могут иметь взаимоисключающие компоненты, но виртуальная среда позволяет им жить «дружно».
Чтобы создать на компьютере или сервере виртуальную среду, можно установить специальную программу — виртуальную машину. Подробнее об этом читайте в статье Что такое виртуальная машина. Также для этих целей можно использовать контейнеры. Рассмотрим, чем отличается принцип виртуализации у машин и контейнеров.
Виртуальные машины и контейнеры: отличия
Виртуальные машины работают благодаря аппаратной виртуализации — это способ, при котором в создании изолированной виртуальной среды задействованы гостевые операционные системы. ОС используют ресурсы (память и процессор) основного компьютера, но при этом запускаются в виртуальной среде и работают изолированно.
В основе аппаратной виртуализации лежит работа гипервизора — он отвечает за изоляцию виртуальных сред и распределение ресурсов центральной машины. По такому принципу работают технологии KVM и XEN. Подробнее в статьях Виртуализация KVM и Виртуализация XEN.

Контейнерная виртуализация — это способ, при котором виртуальная среда запускается прямо из ядра хостовой операционной системы. В данном случае изоляцию ОС и приложений поддерживает контейнер — программная единица. Он содержит специальный набор файлов, а также все зависимости запускаемого в нем приложения: код, библиотеки, инструменты и настройки. Всё это упаковано в отдельный образ, работу которого запускает движок. В качестве таких движков выступают OpenVZ, LXC, Docker, DOSBox, Virtualbox и другие.
С точки зрения пользователя, контейнеры полностью идентичны отдельной операционной системе. Приложения в них функционируют так, как будто напрямую взаимодействуют с хостовой ОС и используют все её ресурсы. При этом ядро хоста обеспечивает изолированность запускаемых приложений и ОС. Таким образом, контейнер — это альтернатива виртуальной машине.

Особенности и преимущества контейнеризации
При выборе между контейнером и виртуальной машиной лучше всего ориентироваться на цели, которых вы хотите достичь. Также стоит определить, какие критерии виртуализации для вас принципиально важны, а какими можно поступиться.
Плюсы использования
- Легкость: контейнеры мало весят. Как правило, размер одного экземпляра измеряется в мегабайтах.
- Скорость: для запуска приложений требуется меньше времени. Иногда приложения в контейнере могут запускаться практически мгновенно.
- Изоляция: процессы одного контейнера полностью изолированы от общей инфраструктуры и других контейнеров. Изоляция позволяет делать независимое обновление, а также точечно вносить изменения.
- Отсутствие зависимостей: приложение не использует процессор, диск или память хоста, а значит не зависит от архитектуры и ресурсов хостовой системы.
- Инкапсуляция: необходимая для запуска приложений инфраструктура (файлы, настройки и зависимости) собирается в отдельный образ-капсулу. Его можно легко перенести из одной среды в другую.
- Повторное использование: уже собранные готовые образы можно использовать повторно. Поскольку это ускоряет время запуска, для часто используемых приложений виртуальный контейнер — это оптимальный вариант.
Минусы использования
- Сложность в управлении: каждый контейнер модерируется по отдельности, а это трудоемкий процесс. Для одновременной работы с большим количеством экземпляров или управления взаимосвязанными контейнерами потребуется установить специальный инструмент — оркестратор. Например, для этих целей можно использовать Kubernetes.
- Контейнеризация Linux: большинство технологий контейнеризации создавались специально под Linux. Нужно быть готовым к тому, что использование Linux-технологии в среде Microsoft может вызвать сложности.
- Уровень изоляции: контейнеры слабее изолированы, поскольку их изоляцию обеспечивает ядро хост-системы. Поэтому при использовании контейнеризации стоит уделять больше внимания настройкам безопасности.
- Новизна: контейнеризация — относительно новая технология. Если вы столкнетесь со сложностями при настройке или работе с контейнерами, может потребоваться больше времени на устранение проблемы.
Основные принципы эксплуатации контейнеров
Для эффективной работы приложения в контейнерах недостаточно просто создать образ и запустить его. Стоит учитывать и соблюдать основные принципы эффективной работы.
Один контейнер обслуживает одну функцию. Не стоит собирать в образ сразу все сущности приложения. Разведение их по разным контейнерам позволяет сохранять высокий уровень производительности. Помимо этого, принцип «один контейнер — один сервис» открывает возможность использовать образы повторно. При соблюдении этого принципа масштабировать приложения проще и эффективнее.
Статичность образа. Не стоит вносить изменения в контейнер, если образ уже сформирован. Это может привести к полному уничтожению или потере части данных. Также статичность контейнера позволяет параллельно проводить тестирования в CI/CD системах.
Лимитирование ресурсов. Чтобы процессы в контейнерах работали максимально эффективно, желательно настроить трекинг лимитов (CPU и RAM). Это позволит отслеживать состояние ресурсов и вовремя реагировать на их избыточное потребление.
Мы рассказали, что такое контейнер и как он работает. Теперь вы знаете, чем отличаются технологии контейнеризации и виртуализации, и сможете выбрать подходящую вам технологию.
Помогла ли вам статья?
Спасибо за оценку. Рады помочь
Стилизация контейнеров для содержимого веб-страниц
Содержимое веб-страниц должно быть размещено в некоем элементе, ширина которого, ограничивающая ширину содержимого, позволяет пользователям удобно работать с материалами сайта. Такие элементы называют «обёртками» (wrapper) или «контейнерами» (container). Стилизовать контейнеры средствами CSS можно по-разному. Некоторые способы работы с контейнерами ставят дизайнера перед необходимостью решать достаточно сложные задачи.

В этом материале я расскажу о контейнерах для содержимого веб-страниц: о том, как они работают, о том, как ими пользоваться, и о тех случаях, когда лучше обойтись без них. Обратите внимание на то, что я буду использовать здесь термины «обёртка» и «контейнер» как равнозначные.
Общие сведения
Когда вы, при разговоре о некоем элементе веб-страницы, узнаёте о том, что речь идёт об обёртке или о контейнере, это значит, что, на самом деле, перед вами — группа элементов, которая «обёрнута» в другой элемент или «размещена» внутри этого элемента. Если, настраивая веб-страницу, не пользоваться дополнительными элементами, отведя роль контейнера элементу , то стилизовать этот элемент можно так:
body
Но в современных условиях использование в качестве контейнера элемента может оказаться непрактичным. Контейнер позволяет не допустить выхода дочерних элементов за его границы.

Контейнер не даёт дочерним элементам выходить за его границы
Здесь имеется боковая и основная области страницы. Обе эти области находятся внутри элемента-контейнера. Ему назначен класс .wrapper . Среди прочих свойств контейнера, естественно, задана и его ширина. Структура HTML-кода такой страницы выглядит так:
Без использования элемента-обёртки дочерние элементы будут размещаться, ориентируясь на края экрана. Это может быть неудобным для пользователей. Особенно — для тех, которые работают на больших экранах.

Страница без элемента-контейнера, включающего в себя её содержимое
Здесь показано, как элементы, растягиваясь, занимают весь экран. Происходит это в том случае, если в макете страницы нет элемента-контейнера. Полагаю, не следует предлагать пользователям работать с подобными страницами. Позвольте мне объяснить эту мысль.
О необходимости использования контейнеров для содержимого веб-страниц
Использование контейнера для содержимого веб-страниц имеет множество сильных сторон, о которых стоит знать дизайнерам и разработчикам. Вот некоторые из этих сильных сторон:
- Использование контейнера улучшает читабельность содержимого страницы. Без контейнера содержимое, вроде текста, может растягиваться на всю ширину экрана. На маленьких экранах подобное может давать вполне приемлемый результат. Но на больших экранах это выглядит очень плохо.
- Группировка элементов дизайна страницы упрощает настройку расстояния между ними.
- Если элементы дизайна нужно сгруппировать по столбцам, это будет сложно сделать без использования контейнера.
Настройка элемента-контейнера средствами CSS
Теперь, когда мы поговорили об основах применения контейнеров, и о том, какие преимущества даёт их использование, давайте остановимся на том, как настраивать их средствами CSS.
▍Настройка ширины контейнера

Элемент-контейнер с настроенной шириной
При создании контейнера первое, что нужно решить, это то, какой ширины он будет. На вопрос о желаемой ширине контейнера можно ответить, проанализировав дизайн страницы. В целом, можно сказать, что чаще всего используются контейнеры с шириной, находящейся в пределах 1000px — 1300px . Например, в популярном фреймворке Bootstrap используется ширина, равная 1170px .
.wrapper
Здесь показана установка ширины элемента с классом .wrapper в 1170px , но, на самом деле, свойство width для настройки ширины контейнеров использовать не рекомендуется. Дело в том, что это приводит к необходимости горизонтального скроллинга страницы в том случае, если ширина области окна браузера, доступной для вывода страницы, меньше 1170px . Решить эту проблему можно, воспользовавшись свойством max-width :
.wrapper
Хотя это — вполне рабочий приём, можно полностью избавиться от свойства width и, как в следующем примере, пользоваться лишь свойством max-width :
.wrapper
Теперь, когда мы нашли подходящий механизм настройки ширины контейнера, давайте поговорим о том, как выровнять контейнер по центру страницы.
▍Выравнивание контейнера по центру страницы

Контейнер, выровненный по центру страницы
Для того чтобы выровнять контейнер по центру страницы, нужно, при настройке его внешних отступов, воспользоваться значением auto для левого и правого отступов:
.wrapper
Вот как, в соответствии со спецификацией CSS, ведут себя отступы, которым назначено значение auto :
Если margin-left и margin-right установлены в значение auto, то значения, которые будут использованы для этих отступов, будут одними и теми же. Это позволяет центрировать элемент по горизонтали относительно краёв содержащего его блока.
Если вас интересуют подробности об использовании ключевого слова auto в CSS — взгляните на эту мою статью.
Я воспользовался здесь конструкцией margin: 0 auto . Она сбрасывает размеры верхнего и нижнего отступов в значение 0, а левый и правый отступы настраивает в соответствии с особенностями применения ключевого слова auto . У такого шага есть некоторые последствия, о которых я расскажу ниже. А пока же хочу отметить, что рекомендуется использовать полный вариант вышеописанной сокращённой конструкции для настройки внешних отступов:
.wrapper
▍Настройка левого и правого внутренних отступов

Горизонтальные (левый и правый) внутренние отступы
При проектировании контейнера важно уделить внимание настройке его левого и правого внутренних отступов. Когда размер области просмотра меньше максимальной ширины контейнера, это приведёт к тому, что края контейнера будут прижаты к границам области просмотра. Вот пример стилизации контейнера, в котором предусмотрены внутренние отступы:
.wrapper
Настроив внутренние отступы контейнера, мы можем быть уверены в том, что края контейнера, в любом случае, будут находиться как минимум в 16px от краёв области просмотра, даже в том случае, если ширина области просмотра окажется меньше максимальной ширины контейнера. Внутренние отступы — это нечто вроде защитного механизма, который не даёт границам контейнера прижиматься к границам области просмотра даже в том случае, когда область просмотра уже, чем максимальная ширина контейнера.
▍Использование процентных значений при настройке контейнеров
Мне, после публикации исходного варианта этого материала, написали об использовании процентных значений при настройке контейнеров. В частности, речь идёт о применении CSS-свойства max-width: 90% вместо использования свойств padding-left и padding-right .

Использование процентных значений при настройке контейнеров и ситуации, когда значение max-width: 90% приводит к приемлемым и неприемлемым результатам
Хотя этот подход оказался вполне рабочим, выяснилось, что на больших экранах 90% ширины области просмотра — это слишком много. Но данную проблему можно решить, воспользовавшись медиа-запросом:
.wrapper < max-width: 90%; margin-left: auto; margin-right: auto; >/* Медиа-запрос для больших экранов */ @media (min-width: 1170px) < .wrapper < max-width: 1170px; >>
В результате оказывается, что, используя процентное значение, мы усложняем CSS-код. Для того чтобы избавить себя от необходимости применения медиа-запроса, мы можем использовать фиксированное значение для ширины. Ещё одно решение, предложенное в этом твите, заключается в применении комбинации свойств width: 90% и max-width: 1170px :
.wrapper
Это — интересный подход, но я предпочёл бы настраивать внутренние отступы самостоятельно, не полагаясь на процентные значения.
▍Свойство display элемента-контейнера
Так как для оформления контейнеров используют теги , контейнеры, по умолчанию, являются блочными элементами. Что если понадобится поменять свойство контейнера display на grid , сделав это для того чтобы разместить его дочерние элементы в сетке?
Я не рекомендую этого делать, так как это идёт вразрез с идеей разделения ответственностей. Элемент-контейнер, «обёртка», это сущность, предназначение которой заключается в том, чтобы «оборачивать» другие элементы. Если нужно разместить дочерние элементы контейнера в сетке, тогда стоит добавить в контейнер ещё один , включающий в себя другие элементы, свойство которого display установлено в значение grid . Это будет проще и чище, чем настройка сетки средствами основного контейнера. Такой подход, кроме того, позволяет говорить о том, что в будущем проект, в котором он используется, будет легче поддерживать.
Пусть имеется такой контейнер:
Задавать свойство display: grid подобного элемента не рекомендуется из-за того, что такой элемент может использоваться на разных страницах. Его особые настройки могут случайно привести к нарушению размещения элементов. Вот неудачный вариант настройки контейнера, о котором идёт речь:
.wrapper
Лучше будет использовать такой HTML-код:
Элемент с классом featured-news можно стилизовать так:
.featured-news
Обратите внимание на то, что в этом примере мы использовали отдельный элемент в качестве ещё одной обёртки для содержимого страницы. На имена классов, использованных здесь, можете внимания не обращать. Для решения подобной задачи можно подобрать более удачные имена классов, которые подойдут для многократного использования на различных страницах сайта. Однако именование CSS-сущностей выходит за рамки данного материала.
▍Настройка внешних отступов, разделяющих элементы-контейнеры
Помните, как выше я не рекомендовал использование сокращённого способа настройки внешних отступов для центрирования элемента-контейнера? Речь шла о такой конструкции:
.wrapper
Хотя это — вполне рабочий стиль, в том случае, если на странице имеется несколько элементов-обёрток, и между ними должно быть некоторое расстояние, применение подобного стиля может привести к путанице. Если вы, по какой-то причине, решите уточнить стилизацию элемента-обёртки, применив дополнительный класс, то настройка внешних отступов с помощью этого класса не даст нужных результатов из-за особенностей расчёта значений специфичности CSS-правил.
Я имею в виду такую схему стилизации:
.wrapper-variation
Свойство margin для элемента с классом .wrapper-variation не будет применено к элементу из-за того, что его переопределяет свойство margin: 0 auto . Краткая форма настройки свойства переопределяет его полную форму. Для того чтобы подобного избежать, рекомендуется в таких случаях использовать полную форму записи свойств. То есть, при стилизации элемента с классом .wrapper нужно поступить так:
.wrapper
Теперь поговорим о настройке внешних отступов элементов. При работе над каждым своим проектом я готовлю набор вспомогательных классов для настройки внутренних и внешних отступов. Я использую их там, где они нужны. Взгляните на следующий рисунок.

Автономный контейнер и контейнер внутри элемента
При таком подходе CSS-код для элемента-обёртки остаётся в неизменном виде, а расстояния между элементами настраиваются с использованием вспомогательных CSS-классов. Тут у вас может появиться вопрос о том, зачем мне понадобилось использовать на странице несколько контейнеров, когда можно обойтись одним. Обратите внимание на то, что в вышеприведённом HTML-коде имеется элемент , расположенный между двух элементов-обёрток.
Здесь хорошо показывает себя использование модификатора !important . Дело в том, что смысл использования вспомогательных классов заключается в том, чтобы принудительно менять значения свойств. Обеспечить такое поведение можно с помощью !important .
Контейнер внутри полноэкранного элемента
В некоторых случаях бывает так, что есть элемент с фоном, занимающий 100% ширины области просмотра, а внутри этого элемента имеется элемент-контейнер. Эта схема похожа на ту, которую мы рассматривали в предыдущем разделе.
HTML-структура страницы в такой ситуации может выглядеть так:
Элемент занимает 100% ширины области просмотра. Этому элементу можно назначить фоновое изображение или фоновый цвет. Контейнер, находящийся внутри этого элемента, не даёт содержимому занимать всю ширину области просмотра.

Элемент занимает всю ширину области просмотра, контейнер ограничивает пространство, в котором выводится содержимое страницы
На этом рисунке у элемента задано фоновое изображение. Он занимает всю ширину области просмотра, а содержимое страницы, выводимое в контейнере, ограничено шириной контейнера.
Нужно ли заключать в контейнер содержимое верхнего блока страницы?
Нужен ли контейнер для оформления верхнего блока страницы, который часто называют «Hero Section»? Это зависит от каждой конкретной ситуации. Исследуем два самых распространённых подхода к оформлению верхних блоков страниц.
Первый подход предусматривает центровку содержимого блока и ограничение ширины содержимого.

Ширина содержимого верхнего блока страницы ограничена
Второй вариант предусматривает распределение содержимого в пределах верхнего блока.

Содержимое распределено в пределах верхнего блока страницы
Для того чтобы лучше разобраться в этих паттернах, предлагаю исследовать особенности их внутреннего устройства.
Верхний блок страницы, содержимое которого выровнено по центру
Возможно, разрабатывая верхний блок страницы, вам захочется разместить в соответствующем элементе некое содержимое и выровнять его по центру без использования элемента-контейнера.
How to make bread at home
.
Sign up
При стилизации вышеприведённого HTML-кода выровнять его содержимое по центру можно, воспользовавшись свойством text-align :
.hero
При таком подходе всё будет выглядеть достойно до тех пор, пока не изменится ширина окна браузера. Вот разбор проблем, которые это может вызвать.
▍Проблема №1: содержимое раздела прижимается к краям области просмотра
Так как в данном примере не настроены правый и левый внутренние отступы, содержимое раздела будет размещено вплотную к границам этого раздела. Это создаёт неудобства для пользователей, так как им сложнее будет читать содержимое верхнего блока страницы.

Содержимое раздела прижато к его краям
▍Проблема №2: слишком большая длина строк текста на экранах большого размера
На экранах большого размера текст, оформленный тегом
, может быть очень тяжело читать из-за того, что длина абзаца окажется слишком большой. В соответствии с этим документом, рекомендованное число символов в строке составляет 45-75. Выход длины строки за пределы этого диапазона усложняет чтение.

Длина строки слишком велика
▍Решение проблем
Для решения вышеозначенных проблем можно использовать контейнер. Он позволит и удержать длину строки в разумных пределах, и предотвратить плотное прилегание содержимого к границам раздела.
How to make bread at home
.
Sign up
Здесь я, настраивая контейнер, использую имя класса hero__wrapper , так как этот контейнер, вполне возможно, будет уникальным и будет применяться только для оформления верхнего блока страницы. Поэтому, в частности, ширина контейнера может быть меньше, чем ширина контейнеров, используемых в обычных условиях.
.hero__wrapper
Выровнять содержимое верхнего блока страницы по центру можно, используя любой удобный подход. Тут всё зависит от каждой конкретной ситуации. В данном примере для выравнивания контента достаточно воспользоваться свойством text-align: center .
Как выравнивать контейнер: по центру, или по левому краю страницы?
Я не могу дать однозначного ответа на этот вопрос, однако я видел сайты, контейнеры, используемые на которых, выравниваются на экранах ноутбуков по центру, а на экранах настольных компьютеров — по левому краю страницы.
Примером такого сайта является Techcrunch. Обратите внимание на то, что на экране настольного компьютера содержимое сайта выровнено по левому краю страницы.

Выравнивание содержимого на экране ноутбука и на экране настольного компьютера
Мне нравится работать с сайтами, содержимое которых выровнено по центру. На страницах таких сайтов имеются симметричные отступы слева и справа. Но у того, что содержимое некоторых сайтов выравнивают по левому краю страницы, может быть какая-то причина, о которой я не знаю. Если вы знаете о том, почему это так, дайте мне знать.
Использование CSS-переменных для создания различных вариантов стилизации контейнеров
Редко бывает так, что все элементы-контейнеры, используемые в некоем проекте, имеют одну и ту же ширину. Ширина контейнера может меняться в зависимости от содержимого контейнера и от того, как именно он используется. Большую гибкость в работе с контейнерами даёт использование CSS-переменных. Это, кроме того, весьма современный подход к настройке контейнеров. Рассмотрим пример.
Вот HTML-код контейнера:
.wrapper
Если вы внимательно прочли CSS-код, вы могли заметить, что var() передаётся два значения: первое — это переменная —wrapper-width , второе — это обычное значение 1170px . Второе значение является запасным. Смысл его существования заключается в том, что оно будет использовано в том случае, если значение переменной —wrapper-width окажется неустановленным.
Что это значит? А это значит, что в наших руках оказывается инструмент для создания различных вариантов элементов-обёрток благодаря возможности переопределения значения переменной —wrapper-width . Выглядит это так:
Благодаря этому подходу я смог создать особый контейнер, не прибегая при этом к следующим действиям:
- Добавление к элементу нового класса.
- Копирование и дублирование существующих стилей.
Если вам не нравится этот подход из-за использования в нём встроенного стиля для переопределения значения CSS-переменной, вы вполне можете решить эту задачу и с помощью добавления к элементу нового класса. Например — так, как показано ниже.
Так выглядит стиль:
.wrapper--small < --wrapper-width: 720px; /* благодаря этому стандартная ширина контейнера будет переопределена. */ >
Здесь можно найти рабочий пример.
Использование display: contents
Для начала позвольте немного рассказать о значении contents свойства display . Каждый элемент в CSS — это блок. В этом блоке что-то содержится, у него есть внутренние и внешние отступы и граница. Использование свойства display: contents приводит к тому, что блок, которому оно назначено, удаляется из потока документа. Это можно представить себе как удаление открывающего и закрывающего тегов блока.
.site-header__wrapper

Элемент-обёртка
При реализации чего-то, напоминающего этот пример, может понадобиться сделать так, чтобы заголовочный раздел сайта мог бы растягиваться до полной ширины страницы, чтобы его ширина не ограничивалась бы свойствами контейнера.
.site-header__wrapper < display: contents; >.site-header
Здесь, благодаря использованию свойства display: contents , элемент-обёртка будет как бы «скрыт». Теперь, когда свойство display: flex применяется к элементу с классом .site-header , дочерние элементы контейнера становятся дочерними элементами .site-header .

Заголовочная часть сайта занимает, в ширину, всё доступное пространство
Отзывчивый фон и фиксированное содержимое
В книге CSS Secrets представлена интересная техника, которая может быть использована для стилизации разделов, имеющих отзывчивый фон (фон, способный занимать всю доступную ширину области просмотра) и элемент-контейнер для содержимого. Рассмотрим обычный способ создания макетов подобных разделов.
section < background-color: #ccc; >.wrapper
Здесь значения свойств margin-left: auto и margin-right: auto вычисляются путём взятия половины ширины области просмотра и вычитания из неё ширины содержимого. Того же самого можно добиться с использованием внутренних отступов.

Внутренние отступы
section
Но дело пока ещё не сделано. На мобильных устройствах содержимое будет прижато к краям области просмотра. Решить эту проблему можно, например, так:
section < padding: 1rem; >@media (min-width: 1170px) < section < padding: 1rem calc(50% - 585px); >>
В качестве альтернативного решения можно предложить применение новой CSS-функции max() . Используя её, мы задаём минимальный размер внутреннего отступа, равный 1rem , а в качестве второго значения, передаваемого ей, указываем выражение 50% — 585px .
section
Если вам интересны подробности о CSS-функциях min() , max() и clamp() — вот мой материал на эту тему.
Как вы стилизуете элементы-контейнеры?