Скромный, но мощный Dockerfile — это строительный блок образов и контейнеров Docker. По сути, это список команд, которые движок Docker выполняет для сборки изображения, и, следовательно, экземпляры изображений в виде контейнеров.
Давайте посмотрим на пример, прежде чем учиться строить свой собственный.
Это Dockerfile для RethinkDB , популярной базы данных в реальном времени с открытым исходным кодом.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
dockerfile FROM debian:jessie MAINTAINER Daniel Alan Miller dalanmiller @rethinkdb .com RUN apt-key adv --keyserver pgp.mit.edu --recv-keys 1614552E5765227AEC39EFCFA7E00EF33A8F2399 RUN echo "deb http://download.rethinkdb.com/apt jessie main" > /etc/apt/sources.list.d/rethinkdb.list ENV RETHINKDBPACKAGEVERSION 2.0 . 4 ~0jessie RUN apt-get update \ && apt-get install -y rethinkdb=$RETHINKDBPACKAGEVERSION \ && rm -rf /var/lib/apt/lists/* VOLUME [ "/data" ] WORKDIR /data CMD [ "rethinkdb" , "--bind" , "all" ] EXPOSE 28015 29015 8080 |
Первая команда FROM
— важная команда Docker, позволяющая извлекать зависимости из других образов; в этом случае, версия Джесси Debian . Следующая команда устанавливает сопровождающего изображения для справки и информации.
Команда RUN
— это то, что вы будете часто использовать. Они определяют команды для запуска из контейнера при его первом создании. Это может быть любая инструкция командной строки, которую вы пожелаете, если у вас есть зависимость для ее поддержки. Например, если вы используете образ, который содержит среду выполнения Ruby, это могут быть команды Ruby.
-
ENV
устанавливает переменную среды, доступную внутри контейнера, полезную для установки переменных, которые должны запускать программы. -
VOLUME
определяет путь в контейнере, который Docker предоставляет хост-системе и отображает с помощью аргумента-v
при запуске контейнера. -
WORKDIR
изменяет активный каталог контейнера на указанное место, если вам нужно запускать команды из или в определенном месте.
В то время как RUN
выдает команды, используемые для подготовки контейнера к использованию, CMD
запускает программное обеспечение, для которого предназначен контейнер (в формате CMD
[ "executable"
, "parameter1"
, "parameter2"
]), и лучше всего используется для команд, которые результат в интерактивной оболочке, такой как Python.
Отражая микросервисную структуру Докера, в идеале должна быть только одна CMD
, а если их больше одной, то будет иметь значение только последняя.
Если вашему контейнеру нужно что-то более сложное, используйте команду ENTRYPOINT
. Используемая совместно с CMD
для параметров, ENTRYPOINT
устанавливает основную команду для образа, позволяя вам запускать образ, как если бы он был этой командой.
Например, следующее запускает команду swarm
, передавая --help
в качестве параметра:
1
|
dockerfile ENTRYPOINT [ "/swarm" ] CMD [ "--help" ] |
Другое распространенное использование команды ENTRYPOINT
— запуск сценария bash в образе, что позволяет выполнять более сложные операции.
EXPOSE
предоставляет порты, которые использует программное обеспечение, и вы можете отобразить его на хост при запуске контейнера с аргументом -p
.
! Новый призыв к действию
Создать Dockerfile с нуля
В этом примере я собираюсь создать изображение (и, следовательно, контейнер) для тестирования сайта и процесса сборки для сайта, созданного в Jekyll . Я выбираю Jekyll, потому что все мои сайты используют его, это простая система для понимания, и мне это нравится.
Официальное изображение есть , но оно не использует последнюю версию Jekyll, оно (на мой взгляд) слишком сложное, и в любом случае, я хочу показать вам, как написать свою собственную.
Создайте новую папку, а затем Dockerfile внутри нее. Начните с установки базового образа, который в этом случае будет официальным образом Ruby , и установите сопровождающий.
1
|
dockerfile FROM ruby:latest MAINTAINER Name <info @example .com> |
Теперь создайте пользователя и группу для Jekyll, установите соответствующие разрешения и установите гем Jekyll:
1
|
dockerfile RUN \ mkdir -p /home/jekyll && \ groupadd -rg 1000 jekyll && \ useradd -rg jekyll -u 1000 -d /home/jekyll jekyll && \ chown jekyll:jekyll /home/jekyll && \ gem install jekyll |
Я работаю над исходными файлами для проекта локально, поэтому создайте точку монтирования, чтобы контейнер Docker мог обращаться к файлам в хост-системе.
1
|
dockerfile VOLUME /home/jekyll |
Вы также можете скопировать файлы в контейнер, но это сделает изображение менее гибким:
1
|
dockerfile COPY . /home/jekyll/ |
В контейнере есть .dockerignore
папки, поэтому создайте новый файл .dockerignore
чтобы игнорировать определенные пути:
1
|
dockerfile .bundle .git _site |
Далее установите каталог, содержащий сайт, и обслуживайте сайт.
1
|
dockerfile WORKDIR /home/jekyll ENTRYPOINT [ "jekyll" , "serve" ] EXPOSE 4000 |
Теперь вы можете построить изображение с:
1
|
dockerfile docker build . |
Создайте контейнер на основе изображения с любым вариантом команды docker run
вы хотите. Однако что-то вроде команды ниже создаст контейнер на основе образа, который задает имя и монтирует локальный том в точке монтирования. Вы можете получить IMAGE_ID
из команды Docker images:
1
|
bash docker run --name cs_jk -it -d -P -v <PATH_TO_SITE>:/home/jekyll <IMAGE_ID> |
Все идет нормально. Но помните, что по мере роста сайта Jekyll вы будете добавлять гемы и другие зависимости, которые также должны быть доступны в контейнере. Давайте исправим это, добавив эти строки под командой WORKDIR
:
1
|
dockerfile COPY Gemfile /home/jekyll COPY Gemfile.lock /home/jekyll RUN bundle install |
Теперь, когда вы перестроите и перезапустите контейнер, добавленные драгоценные камни будут доступны.
Push Image в Docker Hub
Большой! Теперь у вас есть простое пользовательское изображение. Следующим шагом является его установка в Docker Hub, где он может быть более полезным для вас и других пользователей Docker.
Создайте учетную запись в Docker Hub, а затем войдите в свой терминал с такими же учетными данными:
1
|
bash docker login |
Теперь отметьте свое изображение:
1
|
bash docker tag <IMAGE_ID> <USERNAME>/jekyll:devel |
Конечно, не стесняйтесь менять все значения на что-то другое. Это может быть все, что вам подходит, но есть некоторые стандартные теги, которые ожидают пользователи. Теперь, если вы запустите образы Docker, вы, наконец, увидите удобочитаемое имя в столбце REPOSITORY
.
И отправьте его в Docker Hub:
1
|
bash docker push <USERNAME>/jekyll |
Если вы войдете в свою учетную запись Hub, вы увидите изображение в списке и готовы для использования другими с командой docker pull <USERNAME>/jekyll
.
Следующие шаги и лучшие практики
Dockerfile прост, и это намеренно. Одна из основных концепций Docker заключается в том, чтобы каждый компонент был как можно меньшим и дискретным, при этом каждый контейнер в идеале выполнял одну задачу каждый.
Взять, к примеру, сайт Jekyll. Возможно, вы также хотите скопировать код и текст для ошибок, а затем создать другое изображение и контейнер. Хотите создать ePub вашего текста? Создайте еще один контейнер с процессом Pandoc. Нужен поиск на вашем сайте? Подключите изображение Elasticsearch и контейнер. Затем вы можете связать их вместе и совместно использовать одну и ту же базу кода с Docker Compose , что позволит вам создавать сложные, взаимосвязанные контейнеры и приложения.
Dockerfiles являются строительными блоками Docker, и ничто иное в цепочке инструментов не работает без них. Хотя они просты, на практике может быть трудно понять, как лучше всего их написать, чтобы обеспечить максимальную гибкость. Если вы хотите прочитать больше, я рекомендую официальное руководство Докера , и я приветствую любые ваши комментарии или вопросы.
Ссылка: | Руководство для начинающих по Dockerfile от нашего партнера по JCG Криса Уорда в блоге Codeship Blog . |