Как решить проблему с Docker Buildx: Требуется ровно 1 аргумент

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

Введение

Docker Buildx расширяет стандартную команду сборки Docker, добавляя расширенные функции для создания многоархитектурных образов. Однако пользователи часто сталкиваются с ошибкой "docker buildx build requires exactly 1 argument" при работе с этим инструментом. Этот подробный учебник проведет вас через понимание Docker Buildx, диагностику этой распространенной ошибки и реализацию эффективных решений.

К концу этой лабораторной работы вы получите практический опыт настройки Docker Buildx, создания образов Docker, устранения неполадок с ошибкой "requires exactly 1 argument" и сборки образов для нескольких архитектур. Эти навыки необходимы для современной разработки и развертывания контейнеризированных приложений.

Настройка Docker Buildx

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

Проверка установки Docker

Сначала давайте убедимся, что Docker установлен и запущен в нашей системе:

docker --version

Вы должны увидеть вывод, похожий на:

Docker version 20.10.21, build baeda1f

Это подтверждает, что Docker установлен и готов к использованию.

Понимание Docker Buildx

Docker Buildx - это плагин командной строки (CLI), который расширяет функциональность Docker с помощью BuildKit. Он обеспечивает:

  • Сборку образов для нескольких платформ (например, AMD64, ARM64) одновременно
  • Более эффективное кэширование слоев
  • Улучшенную производительность сборки
  • Расширенные функции сборки

Создание билдера Docker Buildx

Давайте создадим и используем новый билдер Docker Buildx:

docker buildx create --name mybuilder --use

Вывод должен выглядеть примерно так:

mybuilder

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

docker buildx ls

Вы должны увидеть вывод, похожий на:

NAME/NODE    DRIVER/ENDPOINT             STATUS  PLATFORMS
mybuilder *  docker-container
  mybuilder0 unix:///var/run/docker.sock inactive
default      docker
  default    default                     running  linux/amd64, linux/386

Звездочка (*) рядом с mybuilder указывает, что это текущий активный билдер.

Инспектирование билдера

Давайте рассмотрим детали нашего билдера:

docker buildx inspect mybuilder

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

Теперь, когда мы успешно настроили Docker Buildx, мы готовы перейти к созданию Dockerfile для использования с нашим билдером.

Создание простого Dockerfile для тестирования

Прежде чем использовать Docker Buildx для сборки образов, нам необходимо создать простой Dockerfile. Он послужит нашим тестовым примером для понимания ошибки "requires exactly 1 argument".

Понимание Dockerfile

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

Давайте создадим каталог для нашего проекта:

mkdir -p ~/project/buildx-test
cd ~/project/buildx-test

Создание базового Dockerfile

Теперь давайте создадим простой Dockerfile, используя текстовый редактор nano:

nano Dockerfile

Скопируйте и вставьте следующее содержимое в Dockerfile:

FROM ubuntu:22.04

RUN apt-get update && apt-get install -y \
  curl \
  nginx \
  && rm -rf /var/lib/apt/lists/*

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

Нажмите Ctrl+O, затем Enter для сохранения, затем Ctrl+X для выхода из nano.

Давайте разберем этот Dockerfile:

  • FROM ubuntu:22.04 - Использует Ubuntu 22.04 в качестве базового образа
  • RUN apt-get update... - Обновляет списки пакетов и устанавливает curl и nginx
  • EXPOSE 80 - Указывает, что контейнер будет прослушивать порт 80
  • CMD ["nginx", "-g", "daemon off;"] - Запускает nginx в foreground при запуске контейнера

Создание файла .dockerignore

Файл .dockerignore помогает исключить файлы и каталоги, которые не нужны в контексте сборки, делая сборки быстрее и эффективнее:

nano .dockerignore

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

.git
.gitignore
*.md

Нажмите Ctrl+O, затем Enter для сохранения, затем Ctrl+X для выхода из nano.

Проверка структуры проекта

Давайте проверим, что наши файлы созданы правильно:

ls -la

Вы должны увидеть вывод, похожий на:

total 16
drwxrwxr-x 2 labex labex 4096 Jan 1 00:00 .
drwxr-xr-x 3 labex labex 4096 Jan 1 00:00 ..
-rw-rw-r-- 1 labex labex   21 Jan 1 00:00 .dockerignore
-rw-rw-r-- 1 labex labex  159 Jan 1 00:00 Dockerfile

Теперь, когда у нас есть базовый Dockerfile, мы готовы протестировать Docker Buildx и изучить ошибку "requires exactly 1 argument" на следующем шаге.

Понимание и решение ошибки "Requires Exactly 1 Argument"

На этом этапе мы намеренно вызовем ошибку "requires exactly 1 argument", чтобы понять ее причины, а затем узнаем, как ее решить.

Вызов ошибки

Сначала перейдем в каталог нашего проекта, если мы еще не там:

cd ~/project/buildx-test

Теперь давайте попробуем собрать образ, используя Docker Buildx, не указав контекст сборки:

docker buildx build

Вы должны увидеть сообщение об ошибке, похожее на:

"docker buildx build" requires exactly 1 argument.
See 'docker buildx build --help'.

Usage:  docker buildx build [OPTIONS] PATH | URL | -

Эта ошибка возникает, потому что команда docker buildx build требует контекст сборки (каталог, содержащий Dockerfile) в качестве аргумента.

Понимание ошибки

Ошибка "requires exactly 1 argument" означает, что Docker Buildx должен знать, где найти файлы, необходимые для сборки образа. Этим аргументом обычно является путь к каталогу, содержащему ваш Dockerfile (контекст сборки).

Распространенные сценарии, вызывающие эту ошибку, включают:

  1. Забыли указать контекст сборки
  2. Использование неверного синтаксиса команды
  3. Размещение опций в неправильном порядке

Исправление ошибки

Давайте исправим команду, добавив контекст сборки. Самый простой способ - использовать . для обозначения текущего каталога:

docker buildx build .

На этот раз Docker начнет процесс сборки, но мы заметим, что он не помечает образ, что затрудняет его последующую ссылку.

Давайте остановим сборку с помощью Ctrl+C, если она все еще выполняется, и попробуем еще раз с правильным тегом:

docker buildx build -t nginx-test:latest .

Вы должны увидеть вывод, показывающий ход сборки:

[+] Building 12.8s (7/7) FINISHED
 => [internal] load build definition from Dockerfile                          0.0s
 => => transferring dockerfile: 203B                                          0.0s
 => [internal] load .dockerignore                                             0.0s
 => => transferring context: 34B                                              0.0s
 => [internal] load metadata for docker.io/library/ubuntu:22.04               0.5s
 => [1/3] FROM docker.io/library/ubuntu:22.04@sha256:...                      0.0s
 => CACHED [2/3] RUN apt-get update && apt-get install -y     curl     nginx  0.0s
 => CACHED [3/3] EXPOSE 80                                                    0.0s
 => exporting to image                                                        0.0s
 => => exporting layers                                                       0.0s
 => => writing image sha256:...                                               0.0s
 => => naming to docker.io/library/nginx-test:latest                          0.0s

Использование различных опций Buildx

Давайте рассмотрим некоторые дополнительные опции с Docker Buildx:

  1. Сборка и загрузка образа в локальное хранилище образов Docker:
docker buildx build --load -t nginx-test:local .
  1. Сборка без использования кэша сборки (принудительная новая сборка):
docker buildx build --no-cache -t nginx-test:nocache .
  1. Сборка и вывод только идентификатора конечного образа:
docker buildx build -q -t nginx-test:quiet .

Проверка собранных образов

Давайте проверим образы, которые мы собрали:

docker images | grep nginx-test

Вы должны увидеть вывод, похожий на:

nginx-test     quiet      abcdef123456   5 minutes ago   123MB
nginx-test     nocache    fedcba654321   5 minutes ago   123MB
nginx-test     local      123456abcdef   5 minutes ago   123MB
nginx-test     latest     abcdef123456   5 minutes ago   123MB

Теперь вы понимаете распространенную ошибку "requires exactly 1 argument" с Docker Buildx и знаете, как правильно собирать образы с различными опциями.

Сборка многоархитектурных образов с помощью Docker Buildx

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

Понимание многоархитектурных образов

Многоархитектурные образы позволяют одному и тому же имени образа работать на разных платформах (например, AMD64, ARM64 и т. д.). Docker автоматически выбирает подходящую версию для архитектуры хоста при извлечении образа.

Это особенно полезно для:

  • Поддержки устройств на базе x86 и ARM
  • Обеспечения работы ваших приложений у различных поставщиков облачных услуг
  • Сборки для устройств IoT с разными архитектурами

Настройка для многоархитектурных сборок

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

docker buildx inspect --bootstrap mybuilder

Если вы видите ошибку о том, что сборщик недоступен, давайте воссоздадим его с правильной конфигурацией:

docker buildx rm mybuilder
docker buildx create --name mybuilder --driver docker-container --bootstrap --use

Создание многоархитектурного образа

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

docker buildx build --platform linux/amd64,linux/arm64 -t nginx-test:multi .

Вы можете увидеть сообщение об ошибке, похожее на:

error: multiple platforms feature is currently not supported for docker driver. Please switch to a different driver (eg. "docker buildx create --use")

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

В демонстрационных целях мы будем собирать для конкретных платформ отдельно:

docker buildx build --platform linux/amd64 -t nginx-test:amd64 --load .

Это собирает образ специально для архитектуры AMD64 и загружает его в локальное хранилище образов Docker.

Использование аргументов сборки

Docker Buildx позволяет нам использовать аргументы сборки для настройки наших сборок. Давайте изменим наш Dockerfile, чтобы использовать аргумент сборки:

nano Dockerfile

Обновите содержимое Dockerfile до:

FROM ubuntu:22.04

ARG PACKAGE=nginx
RUN apt-get update && apt-get install -y \
  curl \
  ${PACKAGE} \
  && rm -rf /var/lib/apt/lists/*

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

Нажмите Ctrl+O, затем Enter для сохранения, затем Ctrl+X для выхода из nano.

Теперь мы можем собрать образ с пользовательским пакетом:

docker buildx build --build-arg PACKAGE=nginx-extras -t nginx-extras:latest .

Отправка в реестр (необязательно)

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

## Example only - not required for this lab
## docker buildx build --platform linux/amd64,linux/arm64 -t username/nginx-test:multi --push .

Проверка образов

Давайте рассмотрим образы, которые мы создали:

docker images | grep nginx

Вы должны увидеть вывод, похожий на:

nginx-extras    latest     abcdef123456   1 minute ago    130MB
nginx-test      amd64      123456abcdef   2 minutes ago   123MB
nginx-test      latest     fedcba654321   10 minutes ago  123MB

Тестирование нашего образа

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

docker run -d --name test-nginx -p 8080:80 nginx-test:latest

Проверьте, работает ли контейнер:

docker ps

Вы должны увидеть вывод, указывающий на то, что ваш контейнер работает:

CONTAINER ID   IMAGE              COMMAND                  CREATED          STATUS          PORTS                  NAMES
abcdef123456   nginx-test:latest  "nginx -g 'daemon of…"   10 seconds ago   Up 10 seconds   0.0.0.0:8080->80/tcp   test-nginx

Давайте выполним curl на сервере nginx, чтобы убедиться, что он отвечает:

curl http://localhost:8080

Вы должны увидеть HTML-страницу приветствия Nginx по умолчанию.

Когда закончите, очистите контейнер:

docker stop test-nginx
docker rm test-nginx

Поздравляем! Вы успешно поработали с Docker Buildx, поняли и решили ошибку "requires exactly 1 argument" и узнали, как создавать специализированные сборки для разных архитектур.

Резюме

В этой лабораторной работе вы получили практический опыт работы с Docker Buildx и узнали, как устранять распространенную ошибку "requires exactly 1 argument". Вот чего вы достигли:

  1. Настроили Docker Buildx и создали экземпляр сборщика
  2. Создали базовый Dockerfile для тестирования
  3. Столкнулись с ошибкой "requires exactly 1 argument", поняли ее и устранили
  4. Собрали образы Docker с различными опциями и конфигурациями
  5. Изучили основы сборки многоархитектурных образов

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

Продолжая свой путь с Docker, рассмотрите возможность изучения более продвинутых функций Buildx, интеграции его в конвейеры CI/CD и использования его для создания по-настоящему переносимых приложений, которые могут работать где угодно.