Как использовать команду docker compose push для отправки образов сервисов

DockerDockerBeginner
Практиковаться сейчас

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

В этой лабораторной работе вы научитесь использовать команду docker compose push для отправки образов сервисов, определённых в файле docker-compose.yaml, в реестр (registry). Вы начнёте с подготовки файла docker-compose.yaml с образами сервисов, затем соберёте эти образы. В завершение вы попрактикуетесь в отправке этих образов сервисов в реестр, включая обработку потенциальных ошибок, которые могут возникнуть в процессе отправки.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL docker(("Docker")) -.-> docker/ImageOperationsGroup(["Image Operations"]) docker(("Docker")) -.-> docker/DockerfileGroup(["Dockerfile"]) docker/ImageOperationsGroup -.-> docker/pull("Pull Image from Repository") docker/ImageOperationsGroup -.-> docker/tag("Tag an Image") docker/ImageOperationsGroup -.-> docker/push("Push Image to Repository") docker/ImageOperationsGroup -.-> docker/images("List Images") docker/DockerfileGroup -.-> docker/build("Build Image from Dockerfile") subgraph Lab Skills docker/pull -.-> lab-555088{{"Как использовать команду docker compose push для отправки образов сервисов"}} docker/tag -.-> lab-555088{{"Как использовать команду docker compose push для отправки образов сервисов"}} docker/push -.-> lab-555088{{"Как использовать команду docker compose push для отправки образов сервисов"}} docker/images -.-> lab-555088{{"Как использовать команду docker compose push для отправки образов сервисов"}} docker/build -.-> lab-555088{{"Как использовать команду docker compose push для отправки образов сервисов"}} end

Подготовка файла docker-compose.yaml с образами сервисов

На этом шаге вы узнаете, как создать файл docker-compose.yaml для определения и управления многоконтейнерными приложениями Docker. Docker Compose — это инструмент, позволяющий описывать и запускать многоконтейнерные приложения Docker. С помощью Compose вы используете YAML-файл для настройки сервисов вашего приложения. Затем одной командой создаёте и запускаете все сервисы из конфигурации.

Сначала перейдите в директорию проекта:

cd ~/project

Теперь создадим файл docker-compose.yaml с помощью редактора nano. Этот файл будет определять два сервиса: веб-сервис и сервис базы данных.

nano docker-compose.yaml

Вставьте следующее содержимое в файл docker-compose.yaml:

version: "3.8"
services:
  web:
    image: nginx:latest
    ports:
      - "80:80"
  db:
    image: postgres:latest
    environment:
      POSTGRES_PASSWORD: mysecretpassword

Разберём этот файл подробнее:

  • version: '3.8' — указывает версию формата файла Docker Compose.
  • services: — определяет различные сервисы, из которых состоит ваше приложение.
  • web: — определяет сервис с именем web.
  • image: nginx:latest — указывает, что сервис web будет использовать Docker-образ nginx:latest. Если образ отсутствует локально, Docker загрузит его из Docker Hub.
  • ports: — сопоставляет порт 80 на хосте с портом 80 в контейнере.
  • db: — определяет сервис с именем db.
  • image: postgres:latest — указывает, что сервис db будет использовать Docker-образ postgres:latest.
  • environment: — задаёт переменные окружения внутри контейнера. Здесь мы устанавливаем пароль POSTGRES_PASSWORD для базы данных PostgreSQL.

Сохраните файл, нажав Ctrl + X, затем Y и Enter.

Просмотреть содержимое созданного файла можно с помощью команды cat:

cat docker-compose.yaml

Эта команда отобразит содержимое файла docker-compose.yaml, что позволит вам проверить его корректность.

Сборка образов сервисов

На предыдущем шаге вы определили сервисы, используя готовые Docker-образы в файле docker-compose.yaml. В этом шаге вы научитесь создавать собственные Docker-образы для сервисов с помощью Dockerfiles и интегрировать их в файл docker-compose.yaml.

Сначала создадим простую директорию для веб-сервиса и Dockerfile внутри неё. Перейдите в директорию проекта, если вы ещё не там:

cd ~/project

Создайте директорию web и перейдите в неё:

mkdir web
cd web

Теперь создайте Dockerfile с именем Dockerfile в директории web с помощью редактора nano:

nano Dockerfile

Вставьте следующее содержимое в Dockerfile:

FROM ubuntu:latest
RUN apt-get update && apt-get install -y nginx
COPY index.html /var/www/html/
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Этот Dockerfile выполняет следующее:

  • FROM ubuntu:latest: Использует последний образ Ubuntu в качестве базового.
  • RUN apt-get update && apt-get install -y nginx: Обновляет список пакетов и устанавливает Nginx.
  • COPY index.html /var/www/html/: Копирует файл index.html (который мы создадим далее) в корневую директорию Nginx.
  • EXPOSE 80: Открывает порт 80 на контейнере.
  • CMD ["nginx", "-g", "daemon off;"]: Задаёт команду для запуска контейнера — запуск Nginx в foreground-режиме.

Сохраните Dockerfile, нажав Ctrl + X, затем Y и Enter.

Теперь создадим файл index.html, который копируется в Dockerfile. Оставаясь в директории ~/project/web, создайте файл:

nano index.html

Вставьте следующий простой HTML-код в index.html:

<!doctype html>
<html>
  <head>
    <title>Hello from Docker!</title>
  </head>
  <body>
    <h1>Welcome to my Dockerized Nginx!</h1>
    <p>This page is served from a custom Docker image.</p>
  </body>
</html>

Сохраните файл index.html, нажав Ctrl + X, затем Y и Enter.

Теперь вернитесь в корневую директорию проекта, где находится файл docker-compose.yaml:

cd ~/project

Нам нужно изменить файл docker-compose.yaml, чтобы сервис web собирался из созданного Dockerfile, а не использовал готовый образ. Откройте файл для редактирования:

nano docker-compose.yaml

Измените определение сервиса web, заменив image на инструкцию build:

version: "3.8"
services:
  web:
    build: ./web
    ports:
      - "80:80"
  db:
    image: postgres:latest
    environment:
      POSTGRES_PASSWORD: mysecretpassword

Здесь build: ./web указывает Docker Compose собрать образ для сервиса web с использованием Dockerfile из директории ./web (относительно расположения docker-compose.yaml).

Сохраните изменённый файл docker-compose.yaml, нажав Ctrl + X, затем Y и Enter.

Теперь вы можете собрать образы, определённые в docker-compose.yaml, с помощью команды docker-compose build. Поскольку Docker Compose не предустановлен, сначала установите его:

sudo apt-get update
sudo apt-get install docker-compose-plugin -y

После установки плагина Docker Compose используйте команду docker compose (обратите внимание на пробел вместо дефиса в новых версиях):

docker compose build

Эта команда прочитает файл docker-compose.yaml и соберёт образ для сервиса web на основе Dockerfile в директории ./web. Также она загрузит образ postgres:latest для сервиса db, если он отсутствует. Вы увидите вывод процесса сборки образа web.

После завершения сборки вы можете просмотреть список Docker-образов в системе, чтобы увидеть новый образ:

docker images

Вы должны увидеть образ с именем, связанным с директорией проекта и именем сервиса (например, project-web), а также образ postgres.

Отправка образов сервисов в реестр

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

Перед отправкой обычно необходимо пометить образы адресом реестра, именем пользователя и названием образа. В этой лабораторной работе мы смоделируем отправку в локальный реестр или реестр, не требующий аутентификации, для упрощения. В реальных условиях вам сначала потребуется войти в реестр с помощью команды docker login.

Сначала выведем список образов, чтобы идентифицировать образ, собранный для веб-сервиса. Перейдите в директорию проекта, если вы ещё не там:

cd ~/project

Выведите список Docker-образов:

docker images

Вы должны увидеть образ с именем, похожим на project-web. Точное имя может незначительно отличаться в зависимости от названия директории проекта.

Теперь пометим образ project-web для отправки в реестр. Мы будем использовать гипотетический адрес реестра your-registry.example.com. В реальных условиях замените your-registry.example.com на фактический адрес реестра. Для этого упражнения мы используем localhost:5000 для имитации локального реестра.

docker tag project-web localhost:5000/my-web-app:latest

Эта команда помечает образ project-web именем localhost:5000/my-web-app:latest. Здесь:

  • localhost:5000 — адрес реестра
  • my-web-app — название репозитория
  • latest — тег

Проверим новый тег, снова выведя список образов:

docker images

Теперь вы должны увидеть образ project-web с двумя тегами: оригинальным и localhost:5000/my-web-app:latest.

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

docker push localhost:5000/my-web-app:latest

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

В реальном сценарии с работающим реестром эта команда загрузила бы слои образа в реестр.

Отправка образов сервисов с игнорированием ошибок

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

Docker Compose предоставляет возможность отправки всех образов сервисов, определённых в файле docker-compose.yaml. По умолчанию, если отправка одного образа завершается ошибкой, вся команда останавливается. Однако вы можете использовать флаг --ignore-pull-failures с командой docker compose push. Хотя название флага предполагает игнорирование ошибок при загрузке, в контексте docker compose push он также влияет на обработку ошибок отправки в зависимости от версии Compose и контекста. Более прямой способ обработки отдельных ошибок отправки в скрипте — перебор сервисов и попытка отправить каждый из них с обработкой ошибок для каждой операции.

Сначала выведем список сервисов, определённых в файле docker-compose.yaml. Перейдите в директорию проекта, если вы ещё не там:

cd ~/project

Имена сервисов (web и db) можно увидеть в файле docker-compose.yaml:

cat docker-compose.yaml

Теперь попробуем отправить все сервисы, определённые в файле docker-compose.yaml. Напомним, что сервис db использует образ postgres:latest из Docker Hub, а сервис web собран локально и помечен для localhost:5000.

docker compose push

Эта команда попытается отправить как образ weblocalhost:5000), так и образ postgres (в Docker Hub). Отправка в localhost:5000, скорее всего, завершится ошибкой, как и ранее. Отправка postgres в Docker Hub может завершиться успешно, если у вас есть доступ в интернет и образ ещё не присутствует в целевом реестре (хотя обычно вы не отправляете официальные образы вроде postgres в свой реестр). Команда, вероятно, сообщит об ошибке из-за невозможности подключиться к localhost:5000.

Чтобы продемонстрировать игнорирование ошибок, рассмотрим сценарий, где у вас несколько сервисов и вы хотите отправить их независимо, продолжая выполнение при ошибках. Хотя docker compose push не имеет прямого флага "игнорировать ошибки отправки" для всех сервисов сразу, аналогичного поведения можно добиться в скрипте, перебирая сервисы и пытаясь отправить каждый по отдельности.

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

Ключевой вывод здесь — понимание, что отправка образов является критически важным этапом CI/CD-конвейера, и обработка потенциальных ошибок (таких как проблемы с сетью или аутентификацией) важна. Хотя docker compose push по умолчанию останавливается при первой ошибке, в скриптах или более сложных сценариях вы бы реализовали логику для обработки результатов каждой операции отправки.

Подтвердим выполнение команды docker compose push:

grep "docker compose push" ~/.zsh_history

Это подтверждает, что вы пытались отправить образы с помощью Docker Compose. Вывод самой команды показал бы ошибку при отправке сервиса web.

Итоги

В этой лабораторной работе вы научились подготавливать файл docker-compose.yaml для определения многоконтейнерных Docker-приложений, в частности настраивая такие сервисы как веб-сервер (nginx) и базу данных (PostgreSQL) с соответствующими образами, портами и переменными окружения. Затем вы попрактиковались в сборке образов этих сервисов на основе определений в файле docker-compose.yaml.

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