Прежде чем углубиться в то, что такое Dockerfile, проведем небольшой эксперимент. Помните образ Python, который мы загрузили в предыдущем разделе? Давайте сначала войдем в контейнер с помощью команды docker run -it. Вспомните, что делает параметр -it — он выделяет псевдо-TTY для контейнера, позволяя пользователю взаимодействовать с ним. Оказавшись внутри контейнера, выведем список всех файлов в текущем каталоге:
[root@novita ~]# docker run -it python:3.7 /bin/bash
root@692f87774bf7:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@692f87774bf7:/#
Затем создадим файл с именем hello.py и снова выведем список файлов:
root@692f87774bf7:/# touch hello.py
root@692f87774bf7:/# ls
bin boot dev etc hello.py home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
Как видите, hello.py создан. Теперь выйдем из контейнера и снова войдем в интерактивный режим контейнера с помощью той же команды docker run -it python:3.7 /bin/bash, после чего снова выведем все файлы:
root@692f87774bf7:/# exit
exit
[root@novita ~]# docker run -it python:3.7 /bin/bash
root@65c767655e8a:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@65c767655e8a:/#
Вы, наверное, уже заметили проблему. Как ни странно, файл, который мы создали ранее, исчез. Это происходит потому, что действия внутри контейнера не изменяют образ. Контейнер лишь добавляет поверх образа записываемый слой, словно калька на прописи — что бы вы ни писали на кальке, это не влияет на нижний слой. Это свойство чем-то напоминает снимок виртуальной машины.
Но вот проблема: если действия внутри контейнера не изменяют образ, как же мы можем достичь быстрого развертывания без повторения определенных операций перед каждым развертыванием кода? Это было бы крайне неэффективно. Представьте, что вы технический руководитель платформы социальных сетей, и внезапно происходит вирусное событие, требующее быстрого масштабирования до сотен облачных серверов, чтобы справиться с огромным потоком пользователей. Ваша команда выбрала Docker для развертывания приложений. Если бы вы развертывали описанным выше способом, пользователи могли бы разочароваться. К тому времени, как ваш сервис восстановится, они уже могли бы уйти.
Тут-то и появляется Dockerfile. Как указано в официальном введении Docker:
Docker может автоматически собирать образы, читая инструкции из Dockerfile. Dockerfile — это текстовый документ, содержащий все команды, которые пользователь может вызвать в командной строке для сборки образа. С помощью docker build пользователи могут создать автоматизированную сборку, выполняющую последовательность командных инструкций.
Проще говоря, Dockerfile — это текстовый документ, содержащий все команды, необходимые для сборки образа из командной строки. Это как инструкция по сборке набора кубиков в нужный образ.
Давайте разберемся, как составить Dockerfile, на практическом примере с использованием образа Python. На моем локальном компьютере (вне контейнера) есть Python-скрипт с именем Optimal_Hotel_Matching.py. Это программа для веб-скрапинга. Попробуем запустить её внутри контейнера:
Как и ожидалось, возникает ошибка, потому что библиотека requests (HTTP-библиотека), являющаяся сторонним модулем, не установлена в образе Python. Это типичный сценарий, когда нам нужно настроить окружение зависимостей. Попробуем решить эту проблему с помощью Dockerfile.
Прежде чем написать наш первый Dockerfile, познакомимся с некоторыми распространенными инструкциями Dockerfile:
FROM: Указывает базовый образ для сборки.MAINTAINER: Описывает создателя образа с именем и email.RUN: Одна из самых важных команд в Dockerfile. Выполняет команды в контейнере и фиксирует результаты.CMD: Задает команду, которая будет выполняться при запуске контейнера.COPY: Копирует файлы с хоста в файловую систему контейнера.WORKDIR: Устанавливает рабочую директорию для любых последующих инструкцийRUN,CMDилиENTRYPOINTв Dockerfile.
Теперь напишем наш первый Dockerfile для решения задачи: установка библиотеки requests и запуск скрипта. Вот возможное решение:
FROM python:3.7 # Указываем базовый образ python:3.7
MAINTAINER ultra "tech@novita.ai" # Имя и email создателя образа
RUN pip install requests # Устанавливаем библиотеку requests
WORKDIR /dockerfileTest # Устанавливаем рабочую директорию
COPY . . # Копируем содержимое текущей директории в контейнер
CMD ["python", "Optimal_Hotel_Matching.py"] # Команда для запуска скрипта
Сохраните приведенное выше содержимое в файле с именем Dockerfile в директории вашего проекта. Теперь соберем образ с помощью команды docker build, пометив его для удобной идентификации:
[root@novita dockerfileTest]# docker build --tag python:requests .
Sending build context to Docker daemon 5.12 kB
...
После завершения сборки проверьте результат командой docker images:
[root@novita dockerfileTest]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
python requests 04f20acdc288 2 hours ago 926 MB
...
Как видите, на локальном компьютере появился новый образ Python с тегом requests. Попробуйте запустить этот образ, чтобы увидеть, не исчезла ли ошибка No module named 'requests' и выполняется ли программа как ожидается.
[root@novita dockerfileTest]# docker run python:requests
Computing distance between 116.368816,39.866464 and 116.438946,39.921624
Computing distance between 116.370910,39.869603 and 116.438946,39.921624
...
Успех! Контейнер запустил код и завершил работу. И это всё? В этой статье я поделился простым примером использования Dockerfile. В реальных производственных средах предприятий Dockerfile, как правило, более сложные.
Novita AI — это универсальная облачная платформа, которая воплощает ваши AI-амбиции. Благодаря бесшовно интегрированным API, бессерверным вычислениям и ускорению GPU, мы предоставляем экономически эффективные инструменты, необходимые для быстрого создания и масштабирования вашего AI-бизнеса. Устраните проблемы с инфраструктурой и начните бесплатно — Novita AI воплощает ваши AI-мечты в реальность.
Рекомендуемое чтение:
