- Docker, часть 3 – создание образов при помощи Dockerfile
- Обзор команд Dockerfile
- Создание Dockerfile
- Создание нового образа и контейнера
- Тестирование работы Nginx и PHP-FPM в контейнере
- Заключение
- Создание собственного образа Docker
- Установка Docker
- Red Hat/CentOS
- Debian/Ubuntu
- После установки
- Сборка нового образа
- Редактирование образа
- Загрузка образа на Docker Hub
- Описание инструкций Dockerfile
- Резервное копирование и восстановление контейнера
- Создание резерва
- Восстановление
Docker, часть 3 – создание образов при помощи Dockerfile
В предыдущей части данного руководства мы увидели, как можно сохранить изменения в контейнере в новый образ. Такой способ подходит, если количество изменений относительно невелико – вводить все команды вручную каждый раз может быть затруднительно. Для упрощения процесса сборки можно воспользоваться Dockerfile. Это специальный скрипт, в котором содержатся команды и инструкции, которые будут в заданной последовательности выполнены для сборки нового образа Docker.
В данном руководстве мы рассмотрим создание собственного образа Docker при помощи Dockerfile. Он будет подробно разобран, чтобы в дальнейшем вы легко смогли создать свой собственный скрипт.
Обзор команд Dockerfile
Dockerfile – это скрипт, содержащий набор команд dockerfile и операционной системы (то есть команд Linux). Прежде чем создать свой dockerfile, давайте познакомимся с этими командами. Вот наиболее важные из них:
FROM — Указывает базовый образ для создания нового образа. Эта команда должна быть первой в dockerfile.
MAINTAINER — Необязательная команда, указывает имя владельца образа.
RUN — Используется для выполнения команды в ходе сборки образа.
ADD — Скопировать файл из файловой системы хоста в новый образ. Можно указать URL файла, в этом случае Docker загрузит его в заданную директорию.
ENV — Определяет переменную среды.
CMD — Команда которая будет запущена при создании нового контейнера на основе образа.
ENTRYPOINT — Задает команду по умолчанию, которая будет выполнена при запуске контейнера.
WORKDIR — рабочий каталог для выполнения команды CMD.
USER — Задает пользователя или UID для создаваемого на основе образа контейнера.
VOLUME — Монтирует директорию хоста в контейнер.
EXPOSE — Указывает какие порты будут слушаться в контейнере.
На первый взгляд команды CMD и ENTRYPOINT кажутся одинаковыми. Они выполняют команду при запуске контейнера. Но все таки между ними есть разница. Мы не будем вдаваться в тонкости, запомните только то что если вы укажете CMD то докер выполнит эту команду, используя стандартную команду ENTRYPOINT, которая является /bin/sh -c. И эту команду вы сможете переопределить при запуске контейнера Если вы укажете ENTRYPOINT то при запуске контейнера переопределить команду вы уже не сможете.
Создание Dockerfile
На данном этапе мы создадим для Dockerfile новую директорию и определим, что мы хотим сделать при помощи Dockerfile.
Создайте новую директорию и пустой файл в ней
Затем определим, какой образ требуется создать. В данном руководстве мы установим Nginx и PHP-FPM7, используя образ Ubuntu 18.04. Кроме того, нам потребуется Supervisord, чтобы запустить Nginx и PHP-FPM 7 одной командой.
Откройте Dockerfile в любом текстовом редакторе, например vim:
В начале файла добавьте строку с указанием базового образа, который мы будем использовать (Ubuntu 18.04):
Обновим программный репозиторий Ubuntu внутри Dockerfile при помощи команды ‘RUN‘.
Теперь установим приложения, который требуются для нашего образа. При помощи apt можно установить Nginx, PHP-FPM и Supervisord из репозитория Ubuntu. Добавьте соответствующую команду RUN:
После установки приложений их нужно настроить. Мы настроим Nginx для работы с PHP путем изменения конфигурации виртуального хоста по умолчанию. Можно отредактировать существующий файл конфигурации командой sed или заменить его новым файлом при помощи команды Dockerfile COPY.
Теперь настроим Supervisord для Nginx and PHP-FPM, точно так же заменив файл конфигурации по умолчанию новым файлом, используя команду COPY.
Создадим новую директорию для sock-файла php-fpm и изменим владельца директории /var/www/html и директории PHP на www-data.
Определим том, чтобы смонтировать указанные ниже директории на хост:
Наконец, нужно установить команду по умолчанию при запуске контейнера и открыть порты для HTTP и HTTPS. Для заданной ‘CMD’ команды по умолчанию мы создадим новый файл
start.sh, содержащий команду «supervisord», и скопируем его в новый образ командой ‘COPY‘.
Указываем порты для nginx
Сохраните и закройте файл.
Вот весь скрипт Dockerfile целиком:
Теперь внутри директории с Dockerfile создайте новый файл конфигурации виртуального хоста под названием «default», файл конфигурации supervisord «supervisord.conf» и скрипт конфигурации сервисов «start.sh».
Вставьте в файл конфигурации виртуального хоста следующий код:
Откройте файл конфигурации Supervisord:
Вставьте следующий код конфигурации:
Откройте файл start.sh.
Вставьте следующие параметры конфигурации:
Сохраните и закройте файл.
При помощи команды chmod сделайте файл start.sh исполняемым:
Создание нового образа и контейнера
Теперь, когда у нас есть все необходимые файлы конфигурации, можно собрать новый образ Docker на основе Ubuntu 18.04, используя наш Dockerfile. Для этого нужно выполнить следующую команду Docker:
Обратите внимание на точку, если вы находитесь в каталоге в котором создан Dockerfile. Если вы находитесь не в корне каталога, то вместо точки укажите директорию с докфайлом. Если создание образа прошло без ошибок вы должны увидеть примерно следующее
Successfully built e7e5dc3d6cd1, говорит о том что образ создан. После успешного выполнения команды можно проверить наличие нового образа при помощи команды images:
Попробуем создать на основе этого образа новый контейнер. Предварительно создадим на хосте новую директорию для данных корня документов:
Запустим новый контейнер командой run:
И командой ps проверим, запустился ли новый контейнер под названием my_container:
Разберем команду run более подробно:
—name my_container nginx_image — на основе образа «nginx_images» создаем новый контейнер с именем «my_container».
-p 80:80 — контейнер запускаетcя на 80 порте хоста.
-v /webroot:/var/www/html — содержимое директории хоста /webroot перезаписывает директорию /var/www/html в контейнере.
Новый контейнер на основе образа nginx_image должен работать без ошибок.
Тестирование работы Nginx и PHP-FPM в контейнере
Командой echo создайте в директории /webroot новый файл index.html:
Тестирование при помощи доступа к IP-адресу хоста командой curl (замените 192.168.1.5 на свой IP-адрес):
curl 192.168.1.5
curl -I 192.168.1.5
Теперь проверим, что PHP-FPM 7.2 работает – создадим в директории /webroot новый файл c phpinfo.
Откройте веб-браузер и введите IP-адрес хоста:
Если все работает правильно, вы увидите следующий результат:
Заключение
Мы успешно создали новый образ и теперь можем создавать на его основе новые контейнеры. Более подробную информацию о создании образов и Dockerfile можно получить в документации Docker.
Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.
Создание собственного образа Docker
Docker позволяет не только загружать и использовать готовые контейнеры, но создавать свои. В данной инструкции мы пошагово разберем установку Docker на Linux, создание собственного образа и загрузку его на Docker Hub.
Установка Docker
Рассмотрим примеры установки на базе операционных систем Red Hat/CentOS и Debian/Ubuntu.
Red Hat/CentOS
Устанавливаем репозиторий — для этого загружаем файл с настройками репозитория:
* если система вернет ошибку, устанавливаем wget командой yum install wget.
. и переносим его в каталог yum.repos.d:
mv docker-ce.repo /etc/yum.repos.d/
yum install docker-ce docker-ce-cli containerd.io
Если система вернет ошибку Необходимо: container-selinux >= . , переходим на страницу пакетов CentOS, находим нужную версию container-selinux и копируем на него ссылку:
. с помощью данной ссылки выполняем установку:
yum install http://mirror.centos.org/centos/7/extras/x86_64/Packages/container-selinux-2.99-1.el7_6.noarch.rpm
После повторяем команду на установку докера:
yum install docker-ce docker-ce-cli containerd.io
Debian/Ubuntu
В deb-системе ставится командой:
apt-get install docker docker.io
После установки
Разрешаем запуск сервиса docker:
systemctl enable docker
. и запускаем его:
systemctl start docker
docker run hello-world
. мы должны увидеть:
.
Hello from Docker!
This message shows that your installation appears to be working correctly.
.
Сборка нового образа
Сборка начинается с создания файла Dockerfile — он содержит инструкции того, что должно быть в контейнере. В качестве примера, соберем свой веб-сервер nginx.
И так, чтобы создать свой образ с нуля, создаем каталог для размещения Dockerfile:
mkdir -p /opt/docker/mynginx
* где /opt/docker/mynginx — полный путь до каталога, где будем создавать образ.
. переходим в данный каталог:
. и создаем Dockerfile:
FROM centos:7
MAINTAINER Dmitriy Mosk
RUN yum install -y epel-release && yum install -y nginx
RUN yum clean all
RUN echo «daemon off;» >> /etc/nginx/nginx.conf
RUN sed -i «0,/nginx/s/nginx/docker-nginx/i» /usr/share/nginx/html/index.html
CMD [ «nginx» ]
* в данном файле мы:
- используем базовый образ centos 7;
- в качестве автора образа указываем Dmitriy Mosk;
- устанавливаем epel-release и nginx;
- чистим систему от метаданных и кэша пакетов после установки;
- указываем nginx запускаться на переднем плане (daemon off);
- в индексном файле меняем первое вхождение nginx на docker-nginx;
- запускаем nginx.
* подробное описание инструкций Dockerfile смотрите ниже.
docker build -t dmosk/nginx:v1 .
* где dmosk — имя автора; nginx — название для сборки; v1 — тег с указанием версии. Точка на конце указывает, что поиск Dockerfile выполняем в текущей директории.
. начнется процесс сборки образа — после его завершения мы должны увидеть что-то на подобие:
Successfully built eae801eaeff2
Successfully tagged dmosk/nginx:v1
Посмотреть список образов можно командой:
Создаем и запускаем контейнер из образа:
docker run -d -p 8080:80 dmosk/nginx:v1
* в данном примере мы запустим контейнер из образа dmosk/nginx:v1 и укажем, что необходимо опубликовать внешний порт 8080, который будет перенаправлять трафик на порт 80 внутри контейнера.
Открываем браузер и переходим по адресу http:// :8080 — мы должны увидеть страницу приветствия с нашим docker-nginx:
Посмотреть созданные контейнеры можно командой:
Запустить или остановить контейнеры можно командами:
docker stop 5fe78aca2e1d
docker start 5fe78aca2e1d
* где 5fe78aca2e1d — идентификатор контейнера.
Редактирование образа
В примере выше мы рассмотрели создание нового образа с нуля. Также, мы можем взять любой другой образ, отредактировать его и сохранить под своим названием.
Скачаем образ операционной системы CentOS:
docker pull centos:latest
Войдем в скачанный образ для его изменения:
docker run -t -i centos:latest /bin/bash
Внесем небольшие изменения, например, создадим учетную запись:
[root@8f07ef93918f /]# useradd dmosk -G wheel -m
[root@8f07ef93918f /]# passwd dmosk
* в данном примере мы создали пользователя dmosk и задали ему пароль.
docker commit -m «Add user dmosk» -a «Dmitry Mosk» 8f07ef93918f centos:my
* где -m — параметр для указания комментария; -a — указывает автора; 8f07ef93918f — идентификатор контейнера, который был нами изменен (его можно было увидеть в приглашении командной строки); centos:my — название нашего нового образа.
Новый образ создан.
Загрузка образа на Docker Hub
Заходим на Docker Hub страницу регистрации. Создаем пользователя:
На следующей странице также заполняем данные профиля. После переходим в почтовый ящик, который был указан при регистрации и переходим по ссылке Confirm Your Email With Docker для подтверждения регистрации. Регистрация закончена.
Переходим на страницу Repositories и создаем свой репозиторий, например, dmosk. Теперь можно загрузить наши образы в репозиторий.
Сначала авторизуемся в Linux под нашим зарегистрированным пользователем:
docker login —username dmosk
Задаем тег для одного из образов и загружаем его в репозиторий:
docker tag centos:my dmosk/dmosk:centos
docker push dmosk/dmosk:centos
Загрузим второй образ:
docker tag dmosk/nginx:v1 dmosk/dmosk:nginx
docker push dmosk/dmosk:nginx
В Docker Hub должны появиться наш образы:
Чтобы воспользоваться образом на другом компьютере, также авторизуемся под зарегистрированным пользователем docker:
docker login —username dmosk
docker pull dmosk/dmosk:nginx
docker run -d -p 8080:80 dmosk/dmosk:nginx
Описание инструкций Dockerfile
Инструкция | Описание | Пример |
---|---|---|
FROM | Указывает, какой базовый образ нужно использовать. Обязательная инструкция для Dockerfile | FROM ubuntu:16.04 |
MAINTAINER | Автор образа. | MAINTAINER DMosk |
RUN | Выполняет команду в новом слое при построении образа. | RUN apt-get install python |
CMD | Запускает команду каждый раз при запуске контейнера. Может быть вызвана только один раз. Если в Dockerfile указать несколько таких инструкций, то выполнена будет последняя. | CMD [«openvpn»] |
LABEL | Добавляет метаданные. | LABEL version=»2″ |
EXPOSE | Указывает, какой порт должно использовать приложение внутри контейнера. | EXPOSE 8080 |
ENV | Задает переменные окружения в образе. | ENV PGPASSWORD pass |
ADD | Добавляет файлы/папки из текущего окружения в образ. Если в качестве копируемого файла указать архив, то он будет добавлен в образ в распакованном виде. Также в качестве источника принимает URL. | ADD /root/.ssh/ |
COPY | Также как и ADD добавляет файлы в образ, но обладает меньшими функциями — не принимает URL и не распаковывает архивы. Рекомендован для использования в случаях, где не требуются возможности ADD или когда нужно перенести архив, как архив. | COPY ./mypasswd /root/ |
ENTRYPOINT | Указывает команду, которой будет передаваться параметр при запуске контейнера. | ENTRYPOINT [«/sbin/apache2»] |
VOLUME | Добавляет том в контейнер. | VOLUME [«/opt/myapp»] |
USER | Задает пользователя, от которого будет запущен образ. | USER user:group |
WORKDIR | Можно задать каталог, откуда будут запускаться команды ENTRYPOINT и CMD. | WORKDIR /opt/apps |
ARG | Создает переменную, которую может использовать сборщик. | ARG folder=/opt/apps WORKDIR $folder |
ONBUILD | Действия, которые выполняются, если наш образ используется как базовый для другой сборки. | ONBUILD ADD . /app/src |
STOPSIGNAL | Переопределяет сигнал SIGTERM для завершения контейнера. | STOPSIGNAL SIGINT |
HEALTHCHECK | Команда, которая будет проверять работоспособность контейнера. | HEALTHCHECK —interval=5m —timeout=3s CMD curl -f http://localhost/ || exit 1 |
SHELL | Позволяет заменить стандартную оболочку для выполнения команд на пользовательскую. | SHELL [«/bin/sh», «-c»] |
Резервное копирование и восстановление контейнера
Созданный нами контейнер можно сохранить в виде архива и, при необходимости, перенести на другой сервер или оставить как бэкап.
Создание резерва
И так, для создания резервной копии контейнера, смотрим их список:
. и для нужного выполняем команду:
docker save -o /backup/docker/container.tar
* в данном примере мы создаем архив контейнера в файл /backup/docker/container.tar.
Чтобы уменьшить размер, занимаемый созданным файлом, раархивиркем его командой:
* в итоге, мы получим файл container.tar.gz.
Восстановление
Сначала распаковываем архив:
После восстанавливаем контейнер:
docker load -i container.tar
Смотрим, что нужный нам контейнер появился: