Как создать образ Docker с помощью Dockerfile в Ubuntu 20.04 LTS

Время — лучший учитель! Жаль, что оно убивает своих учеников…

Что такое Docker

Docker – это платформа с открытым исходным кодом, которая позволяет оптимизировать управление разработкой, тестированием и размещением веб-приложений. В основе работы Docker лежит упаковка программ (вместе с окружением и зависимостями) в виртуальные блоки — контейнеры.

Контейнеры можно развёртывать, масштабировать и перемещать в разные среды (например, персональные компьютеры и дата-центры) без потери работоспособности кода. Также с помощью контейнера можно отделить инфраструктуру приложения от самого приложения и работать только с ней.

Контейнер можно быстро создать и так же быстро удалить. Чтобы создать контейнер, нужно активировать образ docker — шаблонный элемент. Образы запускаются из публичного репозитория Docker Hub. После запуска срабатывает разметка файловой системы, создаётся сетевой интерфейс и назначается IP-адрес. После этого контейнер готов к работе.

Что такое Docker

На одном хосте можно параллельно запускать около тысячи контейнеров. Чтобы управлять сразу несколькими контейнерами, из которых построен проект, можно установить пакетный менеджер Docker Compose.

Преимущества Docker:

Сохранение образа в архив

Для начала рассмотрим как можно выполнить сохранение образа контейнера из среды. Для выполнения данной операции используется команда docker save (man docker-save):

docker pull ubuntu: docker save -o ubuntu:

После выполнения данной команды образ со всеми слоями будет выгружен из пространства образов демона Docker в файловую систему в виде архива tar.

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

docker pull ubuntu: docker save -o ubuntu-16+ ubuntu: ubuntu:

Таким образом, вы можете за одну команду выгрузить все необходимые для распространения контейнеры в один tar-архив.

Команды Dockerfile

Dockerfile – это скрипт, который содержит в себе инструкции, которые будут использоваться для создания образа Docker с помощью команды «docker build». Для создания Dockerfile нужно знать некоторый его команды.

Инструкция FROM инициализирует новый этап сборки и должна располагаться в верхней части Dockerfile.

LABEL

С помощью этой инструкции вы можете добавить дополнительную информацию о вашем образе Docker, такую ​​как версия, описание и т.д.

Эта инструкция используется для выполнения команды в процессе сборки образа Docker. Вы можете установить дополнительные пакеты, необходимые для ваших образов Docker.

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

Инструкция ENV используется для определения переменной среды, которая может использоваться на этапе сборки.

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

EXPOSE

Эта инструкция используется для предоставления порта контейнера на определенных сетевых портах во время выполнения. По умолчанию используется протокол TCP, но вы можете указать, будет ли он TCP или UDP.

Читайте также:  Как в Windows 10 запустить Kali Linux с графической оболочкой

Инструкция ARG используется для определения переменной, которую пользователь может передать сборщику образа. Вы можете использовать эту инструкцию в docker ‘build command’ во время сборки, используя опцию ‘–build-arg variable = value’. Также вы можете использовать несколько ARG в Dockerfile.

ENTRYPOINT

Инструкция ENTRYPOINT используется для определения первой команды и команды по умолчанию, которая будет выполняться при запуске контейнера. Определите команду для запуска приложения с помощью инструкции ENTRYPOINT.

WORKDIR

Инструкция WORKDIR используется для определения рабочего каталога по умолчанию вашего образа Docker. Инструкции RUN, CMD, ENTRYPOINT и ADD следуют за инструкцией WORKDIR. Вы можете добавить несколько инструкций WORKDIR в ваш Dockerfile. Если она не существует, она будет создана автоматически.

Инструкция USER используется для определения пользователя или gid по умолчанию при запуске образа. RUN, CMD и ENTRYPOINT следуют за инструкциям USER в Dockerfile.

VOLUME

Инструкция VOLUME используется для создания точки монтирования между контейнером и базовым хостом.

PostreSQL в контейнере

Одна из причин, почему Java-разработчику полезен Docker, это то, что можно не устанавливать различное дополнительное ПО. Например, базы данных различных версий. Ведь потом их придется удалять, остаются артефакты. Все это нежелательно, да и долго. С Docker , чтобы испытать работу приложения с базой данных PostgreSQL 12 версии, можно не устанавливать ее на компьютер, а поднять в Docker-контейнере.

Для этого из командной строки запустим контейнер с базой:

docker run —name some-postgres —volume db-data:/var/lib/postgresql/data -e POSTGRES_PASSWORD=qqq -e POSTGRES_DB=vv -p 5434:5432 postgres:12-alpine

Теперь с базой можно соединиться по такому url:

jdbc:postgresql://localhost:5434/vv

Что и удается:

Вкладка Databases в Intellij Idea Ultimate

Разберем строку выше. Она поднимает контейнер из образа PostgreSQL:

docker run :12-alpine

Параметры команды

postgres:12-alpine – это имя образа. Готовые образы лежат на Docker Hub, там есть разные версии базы. При запуске контейнера образ сначала загружается оттуда, если его нет на компьютере локально.

–name some-postgres – задает имя контейнера. Все контейнеры, которые есть локально, можно просмотреть с помощью команды docker ps –all.

-e POSTGRES_PASSWORD=qqq -e POSTGRES_DB=vv – переменные среды, задаются параметром -e. Эти параметры задают название базы, которая будет создана по умолчанию (vv) и пароль доступа для пользователя postgres (это имя тоже можно переписать с помощью переменной среды POSTGRES_USER, но мы не будем).

db-data – название volume, то есть того места на нашем диске, где реально будет храниться база из контейнера. Если не задавать volume, то при каждом новом запуске контейнера будет создаваться новый volume, и данные в базе для нас окажутся как бы не сохраненные. А с volume они будут сохраняться. Через двоеточие указан путь внутри контейнера, которому соответствует volume.

-p 5434:5432 – указан порт на локальной машине 5434, которому соответствует порт внутри контейнера 5432. То есть выставляем наружу  порт контейнера 5432, чтобы присоединяться к базе снаружи через порт нашего локального компьютера 5434 (выбран другой порт (не 5432) чтобы не было конфликтов с локально установленной базой, если она есть).

Читайте также:  Браузер грузит процессор: Яндекс, Chrome, Mozilla, Opera (как решить)

Таким образом, мы соединились с базой со вкладки Databases редактора Intellij Idea. Так же можно соединяться и из приложения, не устанавливая базу на компьютер, а запуская любую ее версию в контейнере.

Шаг — Использование команды Docker без sudo (опционально)

По умолчанию, запуск команды docker требует привилегий пользователя root или пользователя группы docker, которая автоматически создается при установке Docker. При попытке запуска команды docker пользователем без привилегий sudo или пользователем, не входящим в группу docker, выводные данные будут выглядеть следующим образом:

Outputdocker: Cannot connect to the Docker daemon. Is the docker daemon running on this host?. See ‘docker run —help’.

Чтобы не вводить sudo каждый раз при запуске команды docker, добавьте имя своего пользователя в группу docker:

  • sudo usermod -aG docker ${USER}

Для применения этих изменений в составе группы необходимо разлогиниться и снова залогиниться на сервере или задать следующую команду:

  • su — ${USER}

Для продолжения работы необходимо ввести пароль пользователя.

Убедиться, что пользователь добавлен в группу docker можно следующим образом:

  • id -nG

Outputsammy sudo docker

Если вы хотите добавить произвольного пользователя в группу docker, можно указать конкретное имя пользователя:

  • sudo usermod -aG docker username

Далее в этой статье предполагается, что вы используете команду docker как пользователь, находящийся в группе docker. Если вы не хотите добавлять своего пользователя в группу docker, в начало команд необходимо добавлять sudo.

Теперь рассмотрим команду docker.

Хранилище реестра

По умолчанию, данные реестра сохраняются с использованием томов (docker volume) на хосте. Если необходимо хранить данные в определенной локации файловой системы, то нужно использовать привязку/монтирование. Монтирование имеет большую связь со структурой файловой системы хоста, но имеет лучшие показатели скорости работы во многих случаях.

$ docker run -d \ -p 5000:5000 \ —restart=always \ —name registry \ -v /mnt/registry:/var/lib/registry \ registry:2

если использовать различные драверы, то данные реестра можно сохранить в S3, Google Cloud, OSS, Azure…

Установка и управление Portainer

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

  1. Web-панель. Управление осуществляется в окне браузера с помощью web-интерфейса.
  2. Управление сервисами. Portainer позволяет в графической оболочке указать реестр, с которого будет загружен контейнер, название образа, даст возможность пробросить необходимые порты, настроить сеть, указать рабочие директории, подключить диски.
  3. Управление контейнерами и сбор статистики. Вы сможете анализировать логи каждого отдельного контейнера, собирать статистику по используемым ресурсам, работать в контейнере подключившись к нему через bash в интерактивном окне.
  4. Кластеризация. Portainer поддерживает кластеризацию Docker Swarm.

Установить его не сложно, так как Portainer сам представлен в виде контейнера.

Первым делом создадим каталог, где будут размещены данные:

[email protected]:~# mkdir /root/portainer/data

Установка и управление Portainer

Запустим контейнер следующей командой:

Читайте также:  Анимация на Андроид – как отключить для повышения быстродействия

[email protected]:~# docker run —name portainer —restart always -d -p 9000:9000 -v /root/portainer/data:/data -v /var/run/:/var/run/ portainer/portainer

Так же мы можем установить Portainer через уже знакомый нам Docker-compose. Содержание файла будет следующее:

portainer:

image: portainer/portainer

container_name: portainer

hostname: portainer

restart: always

command: —no-auth —no-analytics

volumes:

— /var/run/:/var/run/

ports:

Установка и управление Portainer

— «9000:9000»

По окончании установки, web-интерфейс Portainer будет доступен по ссылке: https://ваш_ip_адрес:9000

Первым делом вы увидите окно регистрации, с предложением ввести пароль администратора. Введите сложный пароль и подтвердите его.

Перед вами появится с окно с выбором окружения, Local или Remote. Так как Docker у нас установлен локально, выбираем Local и подключаемся нажатием Connect. После чего вы увидите рабочее окружение Portainer.

На первый взгляд UI Portainer может показаться перегруженным и запутанным, но это только на первый взгляд. Меню и функционал интуитивно понятен. Предлагаем вам самостоятельно пройтись по всевозможным меню и вкладкам.

На следующем скриншоте, в разделе Containers мы можем увидеть все контейнеры, которые мы создали ранее в этой статье:

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

Сборка Docker контейнера

Использовать готовые контейнеры просто и удобно, в случае с базой данных мы можем перейти на GitHub и посмотреть как его собрали. Хотя для контейнеров без dockerfile в описании мы не можем знать наверняка что внутри.

Итак, тот минимум что нам понадобится

  1. Установщик 1С.
  2. SQL native client
  3. dockerfile
  4. Скрипт powershell для запуска службы 1с. Я использовал из репозитория Microsoft
  5. Скрипт powershell для установки и настройки. Я назвал его

С первыми двумя все понятно. Перейдем к построению dockerfile.

Заключение

В этой статье мы рассмотрели, как создать контейнер для веб-приложения Django с Postgres. Мы также создали готовый к работе файл Docker Compose, который добавляет Gunicorn и Nginx в нашу конфигурацию для обработки статических и мультимедийных файлов. Теперь вы можете проверить производственную настройку локально.

С точки зрения фактического развертывания в производственной среде, вы, вероятно, захотите использовать:

  1. Полностью управляемый сервис базы данных— такой как RDS или Cloud SQL — вместо того, чтобы управлять своим собственным экземпляром Postgres в контейнере.
  2. Пользователь без полномочий root для db и nginx сервисов

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

Спасибо за чтение

Источники используемые для этой статьи

  • William Vincent — How to use Django, PostgreSQL, and Docker
  • Michael Herman — Dockerizing Django with Postgres, Gunicorn, and Nginx

Была ли вам полезна эта статья? [20 / 4.7]Spread the love