Как создать Docker образ с нуля: Dockerfile и docker build

В этом руководстве мы посмотрим как создать свой Docker образ при помощи Dockerfile на Raspberry Pi (ОС Debian) или другом компьютере под управлением Linux. Пошагово соберём образ командой docker build и запустим контейнер.

Что же такое образы (images)? В технологии Docker — образы это неизменяемый шаблон. Он содержит: код, библиотеки, зависимости, среду выполнения и конфигурационные файлы — весь базовый набор для запуска приложения. Сам образ изменить нельзя, он служит шаблоном для создания и запуска контейнера.

Контейнер — это запущенный экземпляр образа (image). Когда вы выполняете команду docker run, Docker создаёт изолированную среду на основе образа, где приложение начинает работать. Контейнер можно запускать, останавливать, удалять и создавать заново — при этом исходный образ остаётся неизменным.

Это второй урок из курса по Docker для Raspberry Pi. Если вы ещё не установили Docker и не знаете как запустить свой первый контейнер — начните с первого урока.

Как скачивать и запускать Docker образы

Хотя команда docker run и умеет загружать образ из репозитория при запуске контейнер, если он отсутствует, иногда бывает нужно просто скачать образ, не запуская контейнер из него. Для этого используется команда для предварительной загрузки образа в локальный реестр:

Terminal
Copy

Вместо «Имя образа» укажите образ, который планируете скачивать. Загрузка образа по умолчанию будет выполнена из Docker Hub на ваш компьютер (хост).

Terminal
Copy

Будет загружен образ с установленной Java-средой.

Terminal
Copy

Загрузится образ с Python.

Каждый контейнер, который создается из образа, работает независимо: вы можете запустить один контейнер с Java, другой — с Python, они не будут мешать друг другу. Обычно один контейнер основан на одном образе и выполняет одну задачу.

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

Где скачать Docker — образ: Docker Hub и репозитории

Архитектура Docker состоит из трёх ключевых компонентов:

  • Client (Клиент)
    Это интерфейс для взаимодействия с Docker. Вы вводите в терминале docker run или docker pull и клиент передаёт их серверной части.
  • Host (Хост)
    Это серверная часть docker, которая принимает запросы от клиента. На хосте создаются, запускаются и управляются контейнеры, а также хранятся локальные образы. В вашем случае хостом может быть сам Raspberry Pi с установленным Docker.
  • Registry (Реестр образов)
    Удалённое хранилище образов (например, Docker Hub). Отсюда клиент скачивает готовые образы для запуска или загружает свои собственные сборки.

Как выглядит процесс: вы пишете команду в Client → он отправляет её на Host → если нужного образа нет локально, Host скачивает его из Registry → затем запускает контейнер.

Наиболее популярный публичный Registry — Docker Hub. Чтобы скачивать общедоступные образы регистрация не требуется. Создание аккаунта нужно только для публикации своих образов или для работы с приватными репозиториями.

Перейдите на сайт Docker Hub и справа вверху выберите:

Docker Hub sign in sign up форма
Выбрать «Sign in» для авторизации или «Sign up» для регистрации

Для регистрации нового логина (Sign up) укажите ваш e-mail, произвольные имя пользователя и пароль:

Docker Hub create account форма
Форма регистрации нового аккаунта (Sign up)

Введите название приложения, чтобы найти соответствующий образ в реестре, например, Python и нажмите enter:

Строка поиска образов Search Docker Hub
В строке «Search Docker Hub» вверху сайта введите название образа для поиска

Вы увидите список образов. Они отличаются версией, размером и автором. При выборе образа лучше ориентироваться на метку OFFICIAL. Это гарантирует безопасность при загрузке.

Результаты поиска python image на Docker Hub
Образ Python с отметкой OFFICIAL

После перехода на страницу с образом обратите внимание на правую часть страницы. Там вы найдете pull — команду для его зарузки:

Команда docker pull для загрузки образа из Docker Hub
Пример команды для загрузки образа из Docker hub

Мы можем выбрать любую другую версию образа для загрузки. Список доступных указан на странице самого образа. Для того, чтобы загрузить образ, который нам подходит, нужно после знака двоеточия «:» указать версию:

Terminal
Copy

Если не указать ни одну из версий, а ограничиться командой docker pull python, по умолчанию будет загружена последняя (соответствующая команде :latest). В реальных проектах никогда не используйте версию :latest. Если ваше приложение написано с учетом особенностей старой версии, после автоматического обновления оно может перестать работать или начнет выдавать ошибки.

После загрузки образа, можно проверить актуальный список командой docker images. Ниже мы видим, что на локальный хост был загружен образ с именем python.

Результат команды docker images со списком образов
Список образов через docker images

Запуск контейнера docker run из локального образа

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

Terminal
Copy

Обращайте внимание на версии при запуске. Если вы скачали образ python:3.13-slim, то в команде docker run нужно указывать именно этот тег. Если написать просто docker run python, Docker не найдет локальную копию образа и начнет скачивать из Registry версию latest.

Когда контейнер будет запущен командой docker run — он сразу завершит свою работу. Убедитесь в этом, введя команду docker ps -a, контейнер будет иметь статус Exited. Это нормально. Образ Python не содержит «оболочки» или постоянно работающей программы. Он просто проверяет версию и завершает работу, так как ему не дали никакой задачи.

Статус Exited контейнера python в выводе docker ps -a
Контейнер python имеет статус Exited после запуска

Интерактивный режим docker

Если вы хотите взаимодействовать с контейнером, чтобы писать код, используйте интерактивый режим (флаг -it):

Terminal
Copy

  • -i (interactive) — сохраняет STDIN открытым, даже если вы не подключены напрямую.
  • -t (tty) — подключает псевдотерминал, чтобы вы видели приглашение командной строки.

Вы окажетесь внутри контейнера с установленной средой Python и сможете выполнять команды:

Интерактивный режим docker run -it с приглашением Python
Ввод команд внутри контейнера доступен в -it

Внутри интерактивного режима можно писать код и тут же его выполнять в терминал. Вот простой пример выполнения команды «Hello world» на python в интерактивном режиме контейнера:

Результат выполнения Python кода в интерактивном режиме Docker
python контейнер выведет результат работы кода

Пока вы работаете внутри интерактивного режима, контейнер активен. Когда вам понадобится выйти из него — введите команду exit или комбинацию Ctrl+D. Контейнер остановится и перейдет в статус Exited.

Именованные контейнеры docker

Каждый запуск команды docker run создаёт новый контейнер со случайным именем, даже если вы используете тот же образ. Чтобы не запутаться в автоматически сгенерированных именах, вы можете задать своё имя с помощью флага —name:

Terminal
Copy

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

Terminal
Copy

Если контейнер был создан без интерактивной оболочки (без флага -it), то подключить терминал при запуске контейнера командой docker start -it не получится. Внутри просто не будет программы, способной принимать команды. Проще удалить старый контейнер и создать новый с нужными параметрами.

Создание и запуск Dockerfile

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

Перед созданием Dockerfile нужно подготовить файловую директорию. Создайте отдельную папку для вашего проекта — там будет храниться сам файл и необходимые скрипты. Лучше размещать папки с проектами в вашей домашней директории (~/). Этот подход считается Best practice при работе с Linux.

Terminal
Copy

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

  • mkdir — make directory, то есть создаст новую папку.
  • -p — если директория (папка) уже создана, флаг игнорирует ошибку «File exists», позволяя следующим командам после && выполняться.
  • ~/docker_projects — имя папки, которая будет создана (тильда ~ означает домашнюю директорию /home/ваше_имя)
  • cd — change directory, перейдем в созданную папку docker_projects.
  • touch — создать пустой файл.
  • Dockerfile — имя файла, создаваемой командой touch.

Инструкция Dockerfile

Инструкция Dockerfile — это описание процесса создания образа, в котором определяются: команды при запуске контейнера, базовый образ запуска, рабочая директория.

Инструкция Dockerfile FROM — обязательная первая строка файла. Она задаёт базовый образ (base image), на его основе будет создан ваш новый образ. Всегда указывайте конкретную версию (например, python:3.13-slim), чтобы избежать проблем с совместимостью при будущих обновлениях.

Dockerfile
Copy

Инструкция WORKDIR устанавливает рабочую папку внутри будущего контейнера. Все последующие команды (COPY, RUN и другие) будут выполняться относительно этой директории.

Dockerfile
Copy

В примере: в качестве рабочей директории будет папка /app внутри будущего контейнера.

Инструкция COPY копирует файлы и папки с вашего сервера/компьютера (хоста) внутрь создаваемого образа. У неё два обязательных аргумента: источник (путь на хосте) и назначение (путь внутри контейнера).

  • Источник: принимает только относительные пути. Точка . указывает на папку, в которой лежит Dockerfile. Также можно указать любую подпапку (пр.: src/) или файл (пр.: requirements.txt) внутри этой директории. Пути, которые начинаются с / (абсолютные), не работают. Все копируемые файлы должны находиться строго внутри папки проекта.
  • Назначение: относительный путь через точка . или через ./ (возможны оба варианта) означает директорию, заданную ранее через WORKDIR. Также можно указать любой другой путь внутри контейнера, например /app/data.

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

Dockerfile
Copy

В примере: сначала копируем текстовый файл requirements.txt, лежащий рядом с Dockerfile в рабочую директорию (WORKDIR) создаваемого контейнера, а затем — всю остальную директорию проекта.

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

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

Инструкция RUN выполняет команды только один раз — во время сборки образа (при запуске docker build). Она нужна для установки того, чего нет в базовом образе: системных пакетов, библиотек, компиляторов и других зависимостей. Информация о необходимых компонентах обычно содержится в документации к образу или в файле requirements.txt.

Dockerfile
Copy

В примере: команда RUN устанавливает библиотеки Python из файла requirements.txt, после инструкции его копирования внутрь контейнера (COPY). Флаг -r говорит, что нужно прочитать список пакетов из файла, а —no-cache-dir запрещает сохранять временные файлы установки внутри образа.

Docker воспринимает каждую инструкцию как отдельный слой и кэширует его при сборке. Если файл requirements.txt не изменился, то слои COPY requirements.txt ./ и RUN pip install … будут взяты из кэша. Заново выполнится только последняя команда COPY . ., что значительно ускорит повторную сборку образа.

Инструкция EXPOSE документирует, какие порты использует приложение внутри будущего контейнера. Сама по себе эта инструкция не открывает доступ к порту снаружи. Она делает Dockerfile самодокументируемым: глядя на код, сразу видно, какой порт использует приложение, без необходимости читать внешний README. Также эти метаданные считывают инструменты оркестрации (такие как Docker Compose или Kubernetes) для автоматической настройки сети без ручного указания портов в конфигурации.

Dockerfile
Copy

В примере: запись EXPOSE 8000 указывает, что сервис ожидает подключения именно на этом порту.

Инструкция CMD определяет команду, которая автоматически запустится при старте контейнера из образа. В отличие от RUN, она выполняется не во время сборки образа, а каждый раз при запуске контейнера из образа, созданного на базе Dockerfile.

Команду из CMD можно переопределить: если при запуске контейнера (docker run) указать другую команду, она заменит ту, что прописана в CMD.

Dockerfile
Copy

В примере: первый элемент «python» — это интерпретатор, который уже установлен в базовом образе. Docker находит его автоматически по имени через системные пути. Второй элемент «hello.py» — это пример скрипта, который лежит в рабочей директории (WORKDIR). Он передаётся интерпретатору как аргумент для выполнения.

Создание Dockerfile для запуска python — скрипта

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

Перейдем в папку проекта и создадим простой Python-скрипт:

Terminal
Copy

Создадим файл Dockerfile в этой же директории:

Terminal
Copy

Наполним его инструкциями, которые изучили ранее:

Dockerfile
Copy

  • Для сохранения в редакторе nano нажмите кнопки Ctrl+O
  • Для выхода из nano нажмите Ctrl+X

В этом примере мы не используем requirements.txt и RUN pip install, так как скрипт не имеет внешних зависимостей. Инструкция EXPOSE также не нужна, потому что нет приложения, которое слушает сетевой порт. Мы будем использовать только те инструкции, которые необходимы для конкретной задачи.

Убедитесь, что в директории проекта находятся файлы hello.py и Dockerfile:

Директория проекта с файлами hello.py и Dockerfile
Если доступен только терминал используйте команду ls -l

Сборка образа из Dockerfile командой docker build

Перейдём к последнему шагу — сборке образа из созданного Dockerfile. Для этого воспользуемся командой docker build.

Terminal
Copy

Разберём аргументы:

  • docker build — стандартная команда для сборки образа.
  • -t hello — задаёт имя новому образу (можете указать любое свое). Под этим именем он будет отображаться в выводе команды docker images.
  • . (точка) — указывает путь к директории, где лежит Dockerfile. Точка означает «текущая папка», то есть команду нужно выполнять из той же директории, где находится Dockerfile. Если вы находитесь в другой папке (например, в домашней директории ~), укажите путь к директории проекта явно: ./docker_projects.

Docker начнет сборку образа:

Процесс сборки образа через docker build в терминале
Пример запуска docker build из терминала

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

Список образов docker images с собранным образом hello
Используя команду docker images можно увидеть список образов

Теперь запустим контейнер из собранного именованного образа hello:

Terminal
Copy

Контейнер выведет в терминале Hello world и сразу остановится. Это ожидаемое поведение: скрипт выполнил свою задачу и завершился, а вместе с ним остановился и контейнер. В отличие от веб-сервера или базы данных, здесь нет долгоживущего процесса, который поддерживал бы работу контейнера. Для одноразовых задач такой цикл «запуск → выполнение → остановка» является нормой:

Вывод команды docker run с сообщением Hello World из Python
Команда docker run выведет на терминал код из Python — скрипта

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

Итоги: сборка образа из Dockerfile и запуск контейнера

В этой статье мы посмотрели полный цикл создания образа: сформировали Dockerfile с инструкциями FROM, WORKDIR, COPY, RUN и CMD, собрали образ командой docker build -t hello . и запустили контейнер через docker run. Скрипт вывел результат и корректно завершил работу, что подтверждает правильность всех шагов. Разобрали назначение каждого аргумента команды сборки и механизм кэширования слоёв, который ускоряет повторные сборки при неизменных зависимостях.

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

FAQ. Вопросы и ответы

Чтобы создать Docker-образ, нужно создать файл Dockerfile с инструкциями сборки, а затем выполнить команду: docker build -t имя-образа . Например: docker build -t hello. Образ будет собран на основе указанных в Dockerfile команд и сохранён локально.

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

Да, Dockerfile полностью поддерживается на Raspberry Pi 4 и Pi 5. Главное — использовать базовые образы, совместимые с архитектурой ARM64 (например, python:3.11-slim). Официальные образы от Docker Hub обычно поддерживают ARM.

1) в текущей директории нет файла Dockerfile;
2) в Dockerfile есть синтаксическая ошибка;
3) базовый образ не поддерживает ARM (на Raspberry Pi);
4) нет интернета при первой сборке, если базовый образ ещё не скачан.
Проверьте наличие Dockerfile и включите точку в конце команды: docker build -t имя .

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *