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

Если можно на любой, то давайте запустим Docker на микрокомпьютере Repka Pi российской разработки и производства, оснащенной ОЗУ объемом 2 Гб. Прочитав нашу статью, вы научитесь использовать Repka Pi для изучения всех основных возможностей Docker, а также создавать приложения Docker, работающие с оборудованием через GPIO и I2C.

Мы расскажем, как установить Docker на Repka Pi, как с помощью двух команд запустить WordPress, как работать из контейнера Docker с пинами GPIO микрокомпьютера, а также напишем программу, получающую данные с погодной станции BME280 через интерфейс I2C.

Зачем Docker нужен на микрокомпьютерах

Установка Docker на Repka Pi

Установка WordPress

Создаем контейнер для работы с GPIO

Контроль и освобождение ресурсов

Загрузка образа контейнера на Docker Hub

Контейнер для работы с I2C

Полезные ссылки

Итоги

Зачем Docker нужен на микрокомпьютерах

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

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

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

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

Если вы никогда не работали с Docker, то для глубокого изучения этой платформы имеет смысл почитать соответствующие статьи и книги, посмотреть видео учебных курсов. В нашей статье, однако, мы приведем самые необходимые сведения для того, чтобы вы смогли приступить к работе с Docker без предварительной подготовки.

Установка Docker на Repka Pi

Начнем с установки Docker на Repka Pi. Эта процедура очень проста и сводится к выдаче двух команд в консоли Repka OS:

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

Первая из этих команд скачивает официальный скрипт установки Docker, а вторая — запускает его на выполнение с привилегиями пользователя root.

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

sudo usermod -aG docker $USER

Вот и все, на этом установка Docker завершена!

Для проверки установки введите в консоли Repka OS следующую команду:

docker run hello-world

Эта команда запускает образ контейнера с именем hello-world, которая после старта контейнера выводит на консоль строку «Hello from Docker!».

При первом запуске команда загружает из репозитория образов Docker Hub образ hello-world и создает контейнер на базе этого образа. После запуска контейнер выводит на консоль упомянутый выше текст:

docker run hello-world

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
478afc919002: Pull complete
Digest: sha256:53641cd209a4fecfc68e21a99871ce8c6920b2e7502df0a20671c6fccc73a7c6
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (arm64v8)
 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

В тексте описан весь процесс загрузки и запуска контейнера.

Установка WordPress

Чтобы показать, как легко устанавливать программное обеспечение (ПО) с помощью Docker, создадим на базе Repka Pi сайт WordPress с базой данных MySQL.

Если не использовать Docker, то для установки WordPress придется выполнить довольно много действий. Эти действия описаны, например, в статье Настраиваем минимальный WEB-сервер на Repka Pi 3. NGINX+PHP-FPM+MySQL и ставим Wordpress.

Даже из названия этой статьи видно, что вам нужно создать на Repka Pi свой Web-сервер, установить Nginx, PHP-FRM, MySQL, а потом уже выполнить установку и настройку WordPress.

В то же время процедура запуска WordPress в контейнере Docker из готового образа сводится к трем простым командам в консоли.

Создание сети

Прежде всего нужно создать сеть для WordPress:

docker network create wordpress-network

Запуск контейнера MySQL

Далее запускаем контейнер MySQL (вместо «password» нужно указать другой пароль для базы данных):

docker run -d --name wordpress-db \
  --network wordpress-network \
  -e MYSQL_ROOT_PASSWORD=password \
  -e MYSQL_DATABASE=wordpress \
  mysql:latest

Запуск контейнера WordPress

Дожидаемся окончания запуска контейнера MySQL и запускаем контейнер WordPress (не забываем поменять пароль «password»):

docker run -d --name wordpress \
  --network wordpress-network \
  -p 8080:80 \
  -e WORDPRESS_DB_HOST=wordpress-db \
  -e WORDPRESS_DB_NAME=wordpress \
  -e WORDPRESS_DB_USER=root \
  -e WORDPRESS_DB_PASSWORD=password \
  wordpress:latest

Настройка WordPress в браузере

Теперь WordPress запущен, и можно настроить его при помощи браузера. Введите в адресной строке браузера такой URL:

http://192.168.0.45:8080/

Здесь вместо 192.168.0.45 укажите адрес IP вашего микрокомпьютера Repka Pi.

Если все было сделано правильно, на экране появится окно мастера установки WordPress (рис. 1).

Рис. 1. Мастер установки WordPress.
Рис. 1. Мастер установки WordPress.

Выберите нужный вам язык установки, а затем щелкните кнопку Continue. После этого появится форма. Заполните поля этой формы, как указано на рис. 2.

Рис. 2. Заполнение полей формы при установке WordPress.
Рис. 2. Заполнение полей формы при установке WordPress.

Указав необходимые данные и сохранив пароль в безопасном месте, щелкните кнопку Install WordPress, запустив процесс установки.

Через некоторое время вы увидите в окне браузера сообщение о завершении установки и ссылку Log In для входа в WordPress (рис. 3).

Рис. 3. Сообщение об успешной установке WordPress.
Рис. 3. Сообщение об успешной установке WordPress.

Щелкните эту ссылку. Появится стандартное приглашение для авторизации в WordPress, в котором нужно ввести имя пользователя и пароль. Если все было сделано правильно, появится окно Dashboard панели управления WordPress (рис. 4).

Рис. 4. Окно Dashboard панели управления WordPress.
Рис. 4. Окно Dashboard панели управления WordPress.

На этом установка WordPress окончена. Как видите, всего три команды, простая настройка — и уже можно работать.

В этом одно из преимуществ Docker — даже сложные программы и системы можно установить и использовать относительно просто. Все сложные настройки и установки выполняются автоматически в процессе инициализации и запуска контейнера.

Проверяем ресурсы

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

С помощью команды «docker images» можно получить список образов, загруженных на диск микрокомпьютера:

# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
wordpress     latest    eb34126fff1a   2 weeks ago     737MB
mysql         latest    e68e2614955c   2 months ago    638MB
hello-world   latest    ee301c921b8a   10 months ago   9.14kB

Сейчас, когда мы запустили hello-world  и WordPress, у нас на диске (FLASH-карте, вставленной в Repka Pi) находится три образа. Больше всего места занимает образ wordpress (737 Мбайт) и mysql (638 Мбайт).

На следующем шаге узнаем, сколько оперативной памяти занимает запущенный контейнер. Для этого воспользуемся командой «docker stats –no-stream» (рис. 5).

Рис. 5. Использование памяти запущенными контейнерами.
Рис. 5. Использование памяти запущенными контейнерами.

Как видите, больше всего оперативной памяти уходит на MySQL — целых 412 Мбайт, а на сам WordPress только 74 Мбайт. При этом пока WordPress работает вхолостую, не расходуя ресурсы процессора. База данных также пока не содержит никакого дополнительного контента, формирующего содержимое блога.

Запуск и останов контейнера WordPress

Если вы проделали перечисленные в этом разделе действия по установке WordPress, а затем перезагрузили ОС Repka Pi, то после перезагрузки контейнеры будут в остановленном состоянии.

Список всех контейнеров, в том числе остановленных, можно получить следующей командой:

# docker ps -a

Для запуска WordPress вам нужно выдать следующие команды и дождаться завершения их выполнения:

# docker start wordpress-db
wordpress-db
# docker start wordpress
wordpress

Чтобы остановить или перезапустить контейнеры, используйте команды «docker stop» и «docker restart», соответственно.

Создаем контейнер для работы с GPIO

Конечно, вы можете запускать на Repka Pi контейнеры с таким ПО, как WordPress, Apache, Nginx и тому подобные. Однако не будем забывать, что микрокомпьютеры обычно применяются для управления каким-либо оборудованием.

Давайте создадим контейнер для мигания светодиодом, подключенным к интерфейсу GPIO микрокомпьютера Repka Pi.

Готовим необходимые файлы

Чтобы создать контейнер, подготовьте файл с именем Dockerfile (листинг 1).

Листинг 1. Файл https://raw.githubusercontent.com/AlexandreFrolov/rover_connect2/main/docker_gpio/Dockerfile

FROM alpine:latest
ENV PYTHONUNBUFFERED=1
WORKDIR /app
RUN apk update && \
  apk add --no-cache \
  g++ gcc python3 py3-pip python3-dev git musl-dev libffi-dev openssl-dev sudo && \
  rm -rf /var/cache/apk/*  && \
  git clone https://gitflic.ru/project/repka_pi/repkapigpiofs.git && \
  cd repkapigpiofs && \
  python3 setup.py install

WORKDIR /app/repkapigpiofs/Demo
CMD ["python3", "blink_led.py"]

Строка FROM в этом файле указывает, что в качестве базового образа будет использован легковесный дистрибутив Alpine Linux. Этот компактный дистрибутив мы использовали для экономии ресурсов микрокомпьютера.

Строка ENV задает значение переменной среды PYTHONUNBUFFERED, равное единице. В этом случае буферизация вывода Python будет отключена и сообщения будут отображаться без задержки.

С помощью инструкции WORKDIR устанавливается рабочий каталог /app внутри контейнера для выполнения последующих инструкций.

Далее следует строка RUN, в которой устанавливаются ПО, необходимое для сборки и установки пакетов Python, а также пакет RepkaPi.GPIO, необходимый для работы с GPIO микрокомпьютера Repka Pi.

После установки пакета RepkaPi.GPIO с помощью строки WORKDIR назначается рабочий каталог /app/repkapigpiofs/Demo. Это необходимо для запуска программы blink_led.py, которая поставляется вместе с пакетом RepkaPi.GPIO и мигает светодиодом (листинг 2).

Листинг 2. Программа https://gitflic.ru/project/repka_pi/repkapigpiofs/blob?file=Demo%2Fblink_led.py&branch=master

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import RepkaPi.GPIO as GPIO
from time import sleep          # позволяет выставить задержку на время
GPIO.setboard(GPIO.REPKAPI3)    # Repka Pi 3
GPIO.setmode(GPIO.BOARD)        # выбираем тип обращения к GPIO по номеру PIN (BOARD)
led = 7                         # устанавливаем pin 7 для диода
GPIO.setup(led, GPIO.OUT)       # устанавливаем диод (LED) как output
try:
    print ("Нажмите CTRL+C для завершения")
    while True:
        GPIO.output(led, 1)     # выставляем pin led 1/HIGH/True
        sleep(0.1)              # задержка 0.1 секунда
        GPIO.output(led, 0)     # выставляем pin led 0/LOW/False
        sleep(0.1)              # задержка 0.1 секунда
        GPIO.output(led, 1)     # выставляем pin led 1/HIGH/True
        sleep(0.1)              # задержка 0.1 секунда
        GPIO.output(led, 0)     # выставляем pin led 0/LOW/False
        sleep(0.5)              # задержка 0.5 секунда
except KeyboardInterrupt:
    GPIO.output(led, 0)         # выставляем pin led 0/LOW/False
    GPIO.cleanup()              # убираем все настойки по GPIO
    print ("Завершено")

Программа запускается с помощью инструкции CMD.

В программе blink_led.py предполагается, что светодиод подключен к пину с номером 7. Мы подключили светодиод через резистор 240 Ом (рис. 6).

Рис. 6. Подключение светодиода к GPIO микрокомпьютера Repka Pi.
Рис. 6. Подключение светодиода к GPIO микрокомпьютера Repka Pi.

Создаем и запускаем контейнер

Скопируйте приведенный в листинге 1 файл с именем Dockerfile в каталог /root/rover_connect2/docker_gpio, а затем запустите из этого каталога команду сборки образа контейнера:

# docker build -t repka_pi_led_blink_app .

Когда сборка контейнера будет завершена, запустите контейнер в привилегированном режиме:

# docker run --privileged repka_pi_led_blink_app

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

Если все было сделано правильно, светодиод начнет мигать (двойное мигание с паузой), а на консоли появится сообщение:

Нажмите CTRL+C для завершения

Если нажать комбинацию клавиш Ctrl+C, контейнер завершит свою работу.

Автоматический перезапуск контейнера при перезагрузке ОС

Если вам нужно сделать так, чтобы после перезагрузки ОС контейнер запускался автоматически, добавьте при запуске параметр «--restart always»:

# docker run --privileged --restart always repka_pi_led_blink_app

Теперь, как только вы перезагрузите Repka OS, светодиод начнет мигать. С помощью команды «docker ps» вы можете убедиться, что контейнер работает:

# docker ps

Если ввести эту команду, в консоли появится список запущенных контейнеров (рис. 7).

Рис. 7. Список запущенных контейнеров.
Рис. 7. Список запущенных контейнеров.

Также можно посмотреть полный список контейнеров, запущенных или нет, добавив параметр -a:

# docker ps -a

Результат показан на рис. 8.

Рис. 8. Список всех контейнеров на узле.
Рис. 8. Список всех контейнеров на узле.

Остановленные контейнеры можно запустить командой «docker start», запущенные — остановить командой «docker stop» или перезапустить командой «docker restart». Этим командам в качестве параметра необходимо передать идентификатор ID контейнера.

Контроль и освобождение ресурсов

Если вы активно работаете с Docker, то через некоторое время может оказаться, что диск (FLASH-карта) микрокомпьютера переполнен.

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

На рис.  9 мы показали результат выполнения команды «docker images», позволяющей просмотреть список образов с датами создания и местом, которое они занимают на диске.

Рис. 9. Просмотр списка образов Docker.
Рис. 9. Просмотр списка образов Docker.

Как видите, старые версии образов Docker занимают очень много места. Это плохо, так как FLAS-карта микрокомпьютера может переполниться.

Простое решение для очистки ресурсов заключается в использовании такой команды:

# docker system prune

При запуске она выдаст запрос подтверждения для выполнения операции:

WARNING! This will remove:
  - all stopped containers
  - all networks not used by at least one container
  - all dangling images
  - unused build cache

Are you sure you want to continue? [y/N]

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

В нашем случае на диске было освобождено 1.116 Гбайт:

Deleted Containers:
85d5a9a69285c97844ce9eeac9935f47a17cf42854e7875d29affc3af03046e7
aa7a8d243d2c0603ccd7db73bac7a1520aecb8d499cbdba201b6d7118f924144
4fab3cdf356b085262d761250443039784b48611c29eed5a082f26575732d08b
58d1019f8b29317b10518e9b418bc12b13aa83634bf5ef67b57952673643d4a8

Deleted Images:
deleted: sha256:c992c6a90196f3b278062c28f5bde4b90f5b82135dd0eaf23632c35e33453fd8
deleted: sha256:307ec786b81385f122f870e5873abbe2352e2c34c6e0e6583131bc5864834653
deleted: sha256:b9270cdc47ebf1edc6e9d5123ed1dbc4d35bf1e1fcaad887da2ac10411bac1a9
deleted: sha256:68c17c522e7b07a35129606e0b36bfb6b9b11fb133018ea679a17c4cd7d43586

Deleted build cache objects:
orgr1mhfe2x9di9fygojdg3ki
l3n1v0danz8d4eu7zdyiqh4is
cv1f5wydtn65fxp0bn1x2nlar
...
yy8osva0rsurwqv9da8sha7gl
wscesa5tznsnink6bwno2a079
ep449trp31n1dbh0yptjbownv
lagk304pnqouqzhyi4dl45117
Total reclaimed space: 1.116GB

Чтобы удалить ненужный более образ, используйте команду «docker rmi», передав ей ID образа. Этот ID можно узнать командой «docker images».

В случае, когда образ не удаляется из-за его использования в других репозиториях, поможет флаг «-f».

Загрузка своего образа контейнера на Docker Hub

Когда мы устанавливали WordPress на Repka Pi с помощью Docker, то запускали соответствующий контейнер по имени:

docker run -d --name wordpress \
  --network wordpress-network \
  -p 8080:80 \
  -e WORDPRESS_DB_HOST=wordpress-db \
  -e WORDPRESS_DB_NAME=wordpress \
  -e WORDPRESS_DB_USER=root \
  -e WORDPRESS_DB_PASSWORD=password \
  wordpress:latest

Этот контейнер уже имеется в репозитории контейнеров Docker Hub, поэтому для его запуска достаточно одной команды. Предварительно нужно запустить еще контейнер MYSQL, так что мы ввели всего две команды.

А можно ли загрузить подготовленный нами контейнер для мигания светодиодом на Docker Hub, чтобы его тоже можно было запустить одной командой?

Давайте проделаем это.

Регистрация на Docker Hub

Для регистрации откройте сайт Docker Hub в браузере и щелкните ссылку Sign Up. Далее в форме регистрации введите свой адрес электронной почты, имя пользователя и пароль. Щелкните кнопку Sign Up, и разгадайте капчу.

Чтобы продолжить работу, введите выбранный вами логин и пароль.

Создание образа для загрузки на Docker Hub

Сделайте текущим каталог, в котором находится Dockerfile вашего образа. У нас это каталог /root/rover_connect2/docker_gpio.

Далее введите такую команду (вместо frolov777 укажите ваш логин):

# docker build -t frolov777/repka_pi_led_blink:latest .

Будет создан образ, пригодный для загрузки на Docker Hub (рис. 10).

Рис. 10. Подготовлен образ frolov777/repka_pi_led_blink для загрузки на Docker Hub.
Рис. 10. Подготовлен образ frolov777/repka_pi_led_blink для загрузки на Docker Hub.

Теперь нужно авторизоваться в Docker Hub:

# docker login

В ответ на приглашение введите логин и пароль, который вы использовали при регистрации на Docker Hub.

После успешной авторизации загрузите ваш образ:

# docker push frolov777/repka_pi_led_blink:latest

Когда загрузка завершится, откройте раздел Repositories сайта Docker Hub. После загрузки там появится образ repka_pi_led_blink (рис. 11).

Рис. 11. Образ repka_pi_led_blink на Docker Hub.
Рис. 11. Образ repka_pi_led_blink на Docker Hub.

Если по каким-то причинам нежелательно сохранять созданные вами образы в Docker Hub, вы можете создать свой собственный приватный репозиторий образов Docker на своих ресурсах. Описание этого процесса, однако, выходит за рамки данной статьи.

Запуск контейнера repka_pi_led_blink

Если вы уже загрузили свой образ repka_pi_led_blink на Docker Hub, то его можно запустить всего одной командой:

# docker run --privileged frolov777/repka_pi_led_blink:latest

Для запуска контейнера из своего репозитория замените в этой команде frolov777 на свой логин в Docker Hub.

Перед запуском убедитесь, что ранее запущенный одноименный контейнер остановлен. Для этого введите команду «docker ps» и остановите контейнер командой «docker stop», передав ей в качестве параметра идентификатор работающего контейнера.

Вы также можете запустить контейнер в таком режиме, когда он будет автоматически перезапущен при перезагрузке ОС:

# docker run --privileged --restart always frolov777/repka_pi_led_blink:latest

Запуск контейнера через Docker Compose

Если вы создаете приложения с несколькими контейнерами, то вам может пригодиться такой инструмент, как Docker Compose.

В нашей статье мы приведем простейший пример запуска контейнера repka_pi_led_blink в привилегированном режиме (листинг 3).

Листинг 3. Файл https://raw.githubusercontent.com/AlexandreFrolov/rover_connect2/main/docker_gpio/docker-compose.yml

services:
  repka_pi:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: repka_pi_led_blink
    privileged: true 

Для запуска контейнера сделайте текущим каталог /root/rover_connect2/docker_gpio, а затем введите такую команду:

# docker compose up -d

Детальное обсуждение Docker и Docker Compose заслуживает отдельных статей. Отметим только, что строка «privileged: true» позволяет запустить контейнер в привилегированном режиме, что необходимо для работы с GPIO с помощью упомянутого выше пакета RepkaPi.GPIO.

Контейнер для работы с I2C

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

Подключение погодной станции BME280

Мы подключим к Repka Pi погодную станцию, такую как BME280 и BMP280. Первая из них измеряет температуру, давление и влажность, вторая — только температуру и давление. 

Контакты VIN и GND погодной станции нужно подключить к источнику питания 3,3 В и к земле соответственно. Используйте для питания контакт Repka Pi 3 с физическим номером 17.

Выводы SDA и SLC нужно подключить к контактам 3 и 5 микрокомпьютера Repka Pi 3. На рис.  12 мы подключили к Repka Pi светодиод и погодную станцию.

Рис. 12. Подключение погодной станции BME280 и светодиода к Repka Pi.
Рис. 12. Подключение погодной станции BME280 и светодиода к Repka Pi.

Не забудьте установить для Repka Pi прошивку 2, 3, 4 или 5. Это можно сделать с помощью утилитыrepka-config.

Подготовка файлов для образа контейнера

Для создания образа контейнера нужно подготовить три файла в каталоге /root/rover_connect2/docker_gpio_i2c.

Файл Dockerfile показан в листинге 4.

Листинг 4. Файл https://raw.githubusercontent.com/AlexandreFrolov/rover_connect2/main/docker_gpio_i2c/Dockerfile

FROM alpine:latest
ENV PYTHONUNBUFFERED=1
WORKDIR /app
RUN apk update && \
  apk add --no-cache \
  g++ gcc python3 py3-pip python3-dev git musl-dev libffi-dev openssl-dev sudo && \
  rm -rf /var/cache/apk/*  
COPY . /app  
RUN python3 -m venv /venv
ENV PATH="/venv/bin:$PATH"
RUN pip install --no-cache-dir -r requirements.txt
CMD ["python3", "bme380.py"]

С помощью команды COPY копируются файлы, необходимые для сборки образа и работы контейнера.

Для установки необходимых пакетов Python здесь создается виртуальная среда, и в ней выполняется установка модулей, перечисленных в файле requirements.txt (листинг 5).

Листинг 5. Файл https://raw.githubusercontent.com/AlexandreFrolov/rover_connect2/main/docker_gpio_i2c/requirements.txt

smbus2
RPi.bme280

Виртуальная среда Python представляет собой изолированное окружение Python, позволяющая управлять зависимостями приложения независимо от системных библиотек и других приложений. Она создается с помощью модуля venv в каталоге /venv.

Команда ENV добавляет путь к исполняемым файлам виртуальной среды в переменную среды PATH в контейнере.

Расположенная следом команда RUN устанавливает зависимости приложения из файла requirements.txt в виртуальной среде с помощью pip.

Чтобы при сборке образа не увеличивать их размеры, указан флаг --no-cache-dir, отключающий кэширование загруженных пакетов.

При запуске контейнера управление получит программа bme380.py (листинг 5), указанная в команде CMD файла Dockerfile.

Листинг 5. Программа https://raw.githubusercontent.com/AlexandreFrolov/rover_connect2/main/docker_gpio_i2c/bme380.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import smbus2
import bme280
import json
import time

port = 1
address = 0x76
bus = smbus2.SMBus(port)

calibration_params = bme280.load_calibration_params(bus, address)
try:
    print ("Нажмите CTRL+C для завершения")
    while True:
      data = bme280.sample(bus, address, calibration_params)
      data_json = {
      "temperature": data.temperature,
      "pressure": data.pressure,
      "humidity": data.humidity
      }
      print(json.dumps(data_json))
      time.sleep(3)
except KeyboardInterrupt:
    print ("Завершено")

Программа bme380.py создает объект bus для работы с портом 1 шины I2C, а затем с помощью функции  bme280.load_calibration_params загружает параметры калибровки для BME280.

Далее программа считывает в цикле данные с погодной станции, используя загруженные параметры калибровки, преобразует их в формат JSON и выводит на консоль.

Сборка образа и запуск контейнера

Для сборки образа контейнера загрузите все приведенные выше файлы в каталог /root/rover_connect2/docker_gpio_i2c, а затем запустите такую команду:

# docker build -t repka_pi_bme380_app .

В результате будет собран образ repka_pi_bme380_app.

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

# docker run --privileged repka_pi_bme380_app

После запуска на консоль будут выводиться параметры измерения погоды (температура, давление и влажность) в цикле каждые три секунды:

{"temperature": 25.799632372666384, "pressure": 981.0515689236952, "humidity": 21.647666335065125}

{"temperature": 25.779157603910427, "pressure": 981.0714822308324, "humidity": 21.67252182050179}

{"temperature": 25.789394987706327, "pressure": 981.0084183200427, "humidity": 21.666076677684156}

{"temperature": 25.774038912449033, "pressure": 981.0366303135535, "humidity": 21.720609388546105}

{"temperature": 25.768920221278677, "pressure": 981.1079907685454, "humidity": 21.690930574980197}

Чтобы завершить работу контейнера, нажмите комбинацию клавиш Ctrl+С или используйте команду «docker stop».

Загрузка образа контейнера на Docker Hub

Сделайте текущим каталог /root/rover_connect2/docker_gpio_i2c, в котором находится Dockerfile образа.

Далее введите такую команду (вместо frolov777 укажите ваш логин):

# docker build -t frolov777/repka_pi_bme380_app:latest .

Будет создан образ, пригодный для загрузки на Docker Hub.

После этого авторизуйтесь в Docker Hub и загрузите ваш образ:

# docker login
# docker push frolov777/repka_pi_bme380_app:latest

Убедитесь, что теперь в вашем репозитории добавился образ frolov777/repka_pi_bme380_app (рис. 13).

Рис. 13. В репозиторий добавлен образ frolov777/repka_pi_bme380_app.
Рис. 13. В репозиторий добавлен образ frolov777/repka_pi_bme380_app.

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

# docker run --privileged frolov777/repka_pi_bme380_app:latest

Полезные ссылки

Руководства по Docker

Шпаргалка с командами Docker

Docker Swarm для самых маленьких

Docker-compose: идеальное рабочее окружение

How to install and use Portainer for easy Docker container management

Управляем контактами GPIO в Linux из Docker-контейнера библиотекой Libgpiod

Итоги

В результате работы над этой статьей вы научились устанавливать Docker на микрокомпьютер Repka Pi, запускать под его управлением WordPress, а также созданные вами контейнеры, предназначенные для работы с GPIO и I2C микрокомпьютера.

Вы создали программы, работающие в контейнерах Docker, и способные мигать светодиодом через GPIO, а также получать и выводить на консоль температуру, давление и влажность, полученные от погодной станции BME280, подключенной через I2C.

Созданные вами образы контейнеров вы загрузили в репозиторий Docker Hub, а таже научились запускать их оттуда при помощи одной команды. Вы также узнали, как запускать контейнеры, чтобы они автоматически перезапускались при перезагрузке ОС.

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

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

Комментарии (0)