Введение
Этот исчерпывающий учебник по Docker предоставляет разработчикам и IT-специалистам глубокое погружение в технологию контейнеризации. От понимания основных концепций Docker до практических методов установки и управления, руководство охватывает все необходимое для использования мощных возможностей контейнеризации Docker в современной разработке и развертывании программного обеспечения.
Основы Docker
Введение в технологию контейнеризации
Docker — это мощная платформа для технологии контейнеризации, позволяющая разработчикам эффективно упаковывать, распространять и запускать приложения. Контейнеры предоставляют легковесные, переносимые среды, которые инкапсулируют программное обеспечение и его зависимости.
Основные концепции Docker
graph TD
A[Docker Engine] --> B[Container]
A --> C[Image]
A --> D[Dockerfile]
| Концепция | Описание |
|---|---|
| Docker Image | Шаблон только для чтения, содержащий код приложения и зависимости |
| Container | Запускаемый экземпляр Docker-образа |
| Docker Engine | Среда выполнения для создания и управления контейнерами |
Проверка установки Docker
Ваша среда LabEx поставляется с предустановленным Docker. Давайте проверим версию Docker, чтобы убедиться, что он готов к использованию.
docker --version
Вывод должен отобразить версию Docker, например, Docker version 20.10.21, build baeda1f. Это подтверждает, что Docker установлен корректно и доступен.
Загрузка первого Docker-образа
Docker-образ — это шаблон только для чтения, содержащий набор инструкций для создания контейнера. Мы загрузим образ hello-world, который является минимальным образом, используемым для тестирования установки Docker.
docker pull hello-world
Эта команда загружает образ hello-world из Docker Hub на вашу локальную машину. Вы увидите вывод, указывающий на прогресс загрузки и подтверждение того, что образ был загружен.
Запуск первого Docker-контейнера
Теперь, когда у нас есть образ, давайте запустим контейнер из него. Запуск контейнера означает создание экземпляра образа.
docker run hello-world
При запуске hello-world Docker выполняет следующие действия:
- Проверяет, существует ли образ
hello-worldлокально. Если нет, он загружает его (что мы уже сделали). - Создает новый контейнер из образа.
- Запускает исполняемый файл внутри контейнера.
- Контейнер выводит сообщение "Hello from Docker!" и затем завершает работу.
Это демонстрирует базовый жизненный цикл Docker-контейнера: загрузка образа, запуск контейнера, и контейнер выполняет свою определенную задачу.
Список Docker-образов
Чтобы увидеть загруженные вами образы, используйте команду docker images.
docker images
Эта команда выводит список всех Docker-образов, хранящихся в вашей локальной системе, включая образ hello-world, который мы только что загрузили. Вы увидите такие детали, как репозиторий, тег, ID образа, дату создания и размер.
Понимание жизненного цикла контейнера
Контейнеры предоставляют изолированные среды со своим собственным файловым пространством, процессами и сетевыми интерфейсами. Их можно быстро запускать, останавливать, перемещать и удалять, что делает их идеальными для микросервисов и облачных приложений.
Управление файлами Dockerfile
Основы Dockerfile
Dockerfile — это текстовый документ, содержащий все команды, которые пользователь может вызвать из командной строки для сборки образа. Он определяет среду, зависимости и конфигурацию для контейнеризированных приложений.
graph TD
A[Dockerfile] --> B[Команда сборки]
B --> C[Docker Image]
C --> D[Container]
Создание первого Dockerfile
Перейдите в каталог docker_app, который был создан на этапе настройки. Это будет наш рабочий каталог для данной лаборатории.
cd /home/labex/project/docker_app
Теперь давайте создадим простой Dockerfile с именем Dockerfile в этом каталоге. Этот Dockerfile создаст образ на основе Ubuntu и добавит в него простой текстовый файл.
nano Dockerfile
Добавьте следующее содержимое в Dockerfile:
## Используем официальный базовый образ Ubuntu
FROM ubuntu:22.04
## Устанавливаем рабочий каталог внутри контейнера
WORKDIR /app
## Создаем простой текстовый файл
RUN echo "Hello from Dockerfile!" > /app/message.txt
## Команда для выполнения при запуске контейнера
CMD ["cat", "/app/message.txt"]
FROM ubuntu:22.04: Эта инструкция указывает базовый образ для нашего нового образа. Мы используем Ubuntu 22.04.WORKDIR /app: Эта инструкция устанавливает рабочий каталог для любых последующих инструкцийRUN,CMD,ENTRYPOINT,COPYилиADDв Dockerfile. Если/appне существует, он будет создан.RUN echo "Hello from Dockerfile!" > /app/message.txt: Эта инструкция выполняет команду внутри образа в процессе сборки. Здесь она создает файл с именемmessage.txtв каталоге/appс содержимым "Hello from Dockerfile!".CMD ["cat", "/app/message.txt"]: Эта инструкция предоставляет команды по умолчанию для запускаемого контейнера. Когда контейнер запускается из этого образа, он выполнитcat /app/message.txt, отображая содержимое нашего файла сообщения.
Сохраните файл, нажав Ctrl+S, и выйдите из nano, нажав Ctrl+X.
Сборка Docker-образа
Теперь, когда у нас есть Dockerfile, давайте соберем из него Docker-образ. Команда docker build считывает Dockerfile и создает Docker-образ.
docker build -t my-ubuntu-app .
docker build: Команда для сборки Docker-образа.-t my-ubuntu-app: Это присваивает нашему образу тег с именемmy-ubuntu-app. Вы можете выбрать любое имя..: Это указывает контекст сборки, который представляет собой набор файлов по указанномуPATHили URL. Точка (.) означает, что текущий каталог (/home/labex/project/docker_app) является контекстом сборки. Docker будет искатьDockerfileв этом каталоге.
Вы увидите вывод, показывающий каждый шаг процесса сборки, соответствующий инструкциям в вашем Dockerfile.
Запуск пользовательского Docker-контейнера
После успешной сборки образа давайте запустим из него контейнер, чтобы увидеть содержимое message.txt.
docker run my-ubuntu-app
Эта команда создаст и запустит новый контейнер из вашего образа my-ubuntu-app. Будет выполнена инструкция CMD из вашего Dockerfile, и вы должны увидеть "Hello from Dockerfile!" напечатанное в вашем терминале.
Инспекция файловой системы контейнера
Чтобы лучше понять, как файлы управляются внутри контейнера, давайте запустим интерактивную сессию и проверим созданный нами файл.
docker run -it my-ubuntu-app /bin/bash
-it: Этот флаг выделяет псевдо-TTY и оставляетSTDINоткрытым, позволяя вам взаимодействовать с контейнером.my-ubuntu-app: Имя образа, который мы хотим запустить./bin/bash: Это переопределяет инструкциюCMDв Dockerfile и вместо этого запускает оболочку Bash внутри контейнера, предоставляя вам командную строку.
Оказавшись внутри контейнера, вы увидите новую командную строку (например, root@<container_id>:/app#). Теперь вы можете вывести список файлов и просмотреть содержимое message.txt.
ls -l
cat message.txt
Вы должны увидеть message.txt в списке и его содержимое. Чтобы выйти из контейнера, просто введите exit.
exit
Эта интерактивная сессия демонстрирует, что файл message.txt был успешно создан и доступен в файловой системе контейнера.
Продвинутые техники Docker
Стратегии многоэтапной сборки (Multi-Stage Build)
Многоэтапная сборка — это мощная функция, позволяющая использовать несколько инструкций FROM в вашем Dockerfile. Каждая инструкция FROM может использовать другой базовый образ, и каждая инструкция FROM начинает новый этап сборки. Это помогает оптимизировать сложность Dockerfile и уменьшить размер конечного образа, разделяя среды сборки и выполнения.
graph TD
A[Этап сборки] --> B[Компиляция/Сборка]
B --> C[Этап выполнения]
C --> D[Минимальный образ для продакшена]
Подготовка к многоэтапной сборке
Для этого примера мы смоделируем простое приложение, требующее этапа сборки. Мы создадим файлы build_script.sh и final_app.txt.
Сначала убедитесь, что вы находитесь в каталоге docker_app:
cd /home/labex/project/docker_app
Теперь создайте простой скрипт сборки:
nano build_script.sh
Добавьте следующее содержимое в build_script.sh:
#!/bin/bash
echo "Running build process..."
echo "This is the final application output." > /app/output/final_app.txt
echo "Build complete."
Сохраните файл (Ctrl+S) и выйдите (Ctrl+X).
Затем создайте заполнитель для содержимого нашего финального приложения. В реальном сценарии это будет сгенерировано процессом сборки.
nano final_app.txt
Добавьте следующее содержимое в final_app.txt:
This is a placeholder for the final application.
Сохраните файл (Ctrl+S) и выйдите (Ctrl+X).
Реализация многоэтапного Dockerfile
Теперь давайте модифицируем наш Dockerfile для использования многоэтапной сборки. У нас будет этап "сборщика" (builder), который выполнит наш build_script.sh, а затем этап "продакшена" (production), который скопирует только необходимые выходные данные из этапа сборщика.
nano Dockerfile
Замените существующее содержимое следующим:
## Этап 1: Этап сборки
FROM ubuntu:22.04 AS builder
## Устанавливаем bash для выполнения скрипта
RUN apt-get update && apt-get install -y bash
## Устанавливаем рабочий каталог для этапа сборки
WORKDIR /build
## Копируем скрипт сборки и делаем его исполняемым
COPY build_script.sh .
RUN chmod +x build_script.sh
## Создаем каталог для выходных данных
RUN mkdir -p /build/output
## Запускаем скрипт сборки
RUN ./build_script.sh
## Этап 2: Этап продакшена
FROM ubuntu:22.04
## Устанавливаем рабочий каталог для этапа продакшена
WORKDIR /app
## Копируем только необходимый артефакт из этапа сборки
COPY --from=builder /build/output/final_app.txt .
## Команда для выполнения при запуске контейнера
CMD ["cat", "final_app.txt"]
FROM ubuntu:22.04 AS builder: Это начинает первый этап и присваивает ему имяbuilder.RUN apt-get update && apt-get install -y bash: Устанавливаетbashна этапе сборки, который необходим для выполнения нашего скрипта.WORKDIR /build: Устанавливает рабочий каталог для этапа сборки.COPY build_script.sh .: Копирует наш скрипт сборки в этап сборки.RUN chmod +x build_script.sh: Делает скрипт исполняемым.RUN mkdir -p /build/output: Создает выходной каталог на этапе сборки.RUN ./build_script.sh: Выполняет скрипт сборки, который генерируетfinal_app.txtв/build/output.FROM ubuntu:22.04: Это начинает второй этап (этап продакшена). Он использует свежий образubuntu:22.04, что означает, что он по умолчанию не наследует ничего от этапаbuilder.WORKDIR /app: Устанавливает рабочий каталог для этапа продакшена.COPY --from=builder /build/output/final_app.txt .: Это ключевая инструкция для многоэтапной сборки. Она копируетfinal_app.txtиз каталога/build/outputэтапаbuilderв текущий каталог (/app) этапа продакшена. Это гарантирует, что включен только конечный артефакт, что делает образ продакшена меньше.CMD ["cat", "final_app.txt"]: Команда, которая будет выполнена при запуске контейнера продакшена, отображая содержимое скопированного файла.
Сохраните файл (Ctrl+S) и выйдите (Ctrl+X).
Сборка и запуск многоэтапного образа
Теперь давайте соберем новый образ, используя наш многоэтапный Dockerfile.
docker build -t multi-stage-app .
Наблюдайте за выводом сборки. Вы увидите шаги как для этапа builder, так и для финального этапа.
После завершения сборки запустите контейнер, чтобы убедиться, что отображается содержимое final_app.txt.
docker run multi-stage-app
Вы должны увидеть "This is the final application output.", что подтверждает, что многоэтапная сборка успешно скопировала артефакт из этапа сборки в конечный образ.
Очистка ресурсов Docker
Хорошей практикой является очистка ресурсов Docker (контейнеров и образов), которые больше не нужны, чтобы освободить дисковое пространство.
Сначала выведите список всех контейнеров (включая остановленные):
docker ps -a
Вы можете удалить конкретные контейнеры по их ID или имени:
docker rm $(docker ps -aq)
Эта команда удаляет все остановленные контейнеры. docker ps -aq выводит список всех ID контейнеров, а docker rm удаляет их.
Затем выведите список всех образов:
docker images
Вы можете удалить конкретные образы по их ID или имени. Будьте осторожны, чтобы не удалить образы, которые все еще используются запущенными контейнерами.
docker rmi my-ubuntu-app multi-stage-app hello-world ubuntu:22.04
Эта команда удаляет образы, которые мы создали и использовали в этой лаборатории. Если образ все еще используется контейнером, вам сначала потребуется удалить контейнер.
docker images
Эта команда покажет, что образы были удалены.
На этом завершается лаборатория по основам Docker и продвинутым техникам. Вы узнали, как создавать Dockerfile, собирать образы, запускать контейнеры и оптимизировать размер образов с помощью многоэтапной сборки.
Резюме
Овладев основами Docker, управлением Dockerfile и продвинутыми техниками, разработчики могут создавать более эффективные, переносимые и масштабируемые программные среды. Этот учебник вооружил вас практическими навыками в создании контейнеров, управлении образами и стратегиях развертывания, позволяя оптимизировать рабочие процессы разработки и применять архитектуры облачных приложений (cloud-native).



