Docker на Raspberry Pi: Запускаем контейнеры на ARM64

Подробное руководство по установке Docker и Docker Compose на Raspberry Pi (ARM64). Запускаем контейнеры, настраиваем Portainer, разбираем типичные ошибки. DIY для умного дома.
Привет всем, кто любит возиться с одноплатниками! Сегодня мы погрузимся в мир контейнеризации на Raspberry Pi. Если вы, как и я, используете «малинку» в качестве домашнего сервера для умного дома, медиацентра или лабораторного стенда, то Docker станет вашим лучшим другом. Он позволяет запускать изолированные приложения-контейнеры, которые не конфликтуют между собой и с основной системой. А с приходом моделей на 64-битных ARM-процессорах (Raspberry Pi 3B+, 4, 5, Zero 2 W) возможности стали ещё шире.
В этой статье я на личном опыте расскажу, как установить Docker на Raspberry Pi OS (64-bit), настроить его для комфортной работы и запустить первые контейнеры. Мы разберём типичные ошибки и я покажу, как проверить, что всё работает как часы.
Зачем Docker на Raspberry Pi?
Прежде чем перейти к командам, давайте обозначим «зачем». Raspberry Pi — устройство с ограниченными ресурсами. Docker помогает эти ресурсы экономить:
* Изоляция: Сервисы в контейнерах живут отдельно. Сломался один — остальные работают.
* Повторяемость: Написал конфигурацию (docker-compose.yml) один раз — запускай где угодно. Больше нет магии «на моей малинке это работало».
* Лёгкость развёртывания: Запуск сложного стека (например, Pi-hole + Unbound или Home Assistant) сводится к нескольким командам.
* Экономия ресурсов: Контейнеры используют ядро хоста, что легче виртуальных машин.
Если вы выбирали ОС для своего проекта, возможно, моя статья «Raspberry Pi OS vs Ubuntu vs DietPi: Выбор ОС для домашнего сервера» поможет вам понять, на чём лучше крутить Docker.
Подготовка системы
Первым делом убедимся, что у нас актуальная 64-битная система. Это важно, потому что многие современные образы контейнеров оптимизированы именно под arm64.
# Проверяем архитектуру процессора
uname -m
Если вы видите aarch64 — вы на правильном пути. Если armv7l — у вас 32-битная ОС. Для Docker на ARM64 лучше выполнить чистую установку Raspberry Pi OS (64-bit) с официального сайта.
Обновляем список пакетов и саму систему:
sudo apt update && sudo apt upgrade -y
Эта базовая команда должна стать привычкой перед любой крупной установкой.
Установка Docker и Docker Compose
Важный момент: Не устанавливайте Docker из стандартных репозиториев apt — там часто старая версия. Мы воспользуемся официальным скриптом или репозиторием Docker.
Способ 1: Установка с помощью официального скрипта (быстро и просто)
# Скачиваем и запускаем скрипт установки от Docker
curl -fsSL https://get.docker.com -o get-docker.sh
# Внимательно смотрим, что делает скрипт, перед запуском
sudo sh get-docker.sh
Скрипт автоматически определит архитектуру aarch64 и установит всё необходимое.
Способ 2: Установка из репозитория Docker (более контролируемый)
# Устанавливаем необходимые утилиты
sudo apt install -y ca-certificates curl gnupg
# Добавляем GPG-ключ репозитория Docker
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/raspbian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Добавляем репозиторий в источники APT
echo
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/raspbian
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" |
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Обновляем APT и устанавливаем Docker
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
После установки любым способом обязательно добавим своего пользователя в группу docker, чтобы не писать sudo перед каждой командой.
# Добавляем текущего пользователя в группу docker
sudo usermod -aG docker $USER
# Применяем изменения группы (нужно выйти и зайти заново, либо выполнить)
newgrp docker
Типичная ошибка: Пропустить этот шаг и потом мучиться с правами. Если команды docker не работают без sudo, проверьте членство в группе командой groups.
Установка Docker Compose (отдельно)
Начиная с Docker Engine 23.0+, плагин docker-compose часто уже включён. Но многие (включая меня) предпочитают standalone-версию. Для arm64 скачиваем бинарник напрямую.
# Определяем актуальную версию (на примере v2.24.5) и скачиваем
DOCKER_COMPOSE_VERSION="v2.24.5"
sudo curl -L "https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# Даём права на выполнение
sudo chmod +x /usr/local/bin/docker-compose
# Проверяем установку
docker-compose --version
Первые шаги: проверка и настройка
Установили? Отлично! Давайте проверим.
# Проверяем версию Docker
docker --version
# Запускаем тестовый контейнер Hello World для ARM
docker run --rm hello-world
Если вы увидели приветственное сообщение от Docker — установка прошла успешно!
Теперь немного настроим Docker для долгой и счастливой жизни на SD-карте.
Меняем расположение данных Docker (опционально, но рекомендуется)
По умолчанию Docker хранит все образы, контейнеры и тома в /var/lib/docker. Если ваша система стоит на SD-карте, это может привести к её быстрому износу из-за постоянной записи логов. Лучше перенести эти данные на внешний SSD или хотя бы на RAM-диск для логов.
Вариант 1: Перенос на внешний диск (например, смонтированный в /mnt/ssd).
- Останавливаем Docker:
sudo systemctl stop docker - Редактируем конфиг:
sudo nano /etc/docker/daemon.json - Добавляем (если файла нет — создаём):
{
"data-root": "/mnt/ssd/docker-data"
}
- Копируем старые данные (если они есть):
sudo cp -rp /var/lib/docker /mnt/ssd/docker-data - Запускаем Docker:
sudo systemctl start docker
Вариант 2: Хранение логов в памяти (уменьшает запись на SD-карту).
В тот же файл /etc/docker/daemon.json можно добавить:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
Это ограничит размер лог-файлов 10 мегабайтами и будет хранить только 3 последних файла.
После любых изменений в daemon.json перезагружаем демон:
sudo systemctl restart docker
Запускаем первый полезный контейнер: Portainer
Управлять контейнерами через CLI — это круто, но иногда хочется наглядности. Portainer — это веб-интерфейс для управления Docker. Идеальный кандидат для первого «боевого» контейнера.
# Создаём volume для хранения данных Portainer
docker volume create portainer_data
# Запускаем контейнер Portainer CE
docker run -d
--name portainer
--restart unless-stopped
-p 9000:9000
-v /var/run/docker.sock:/var/run/docker.sock:ro
-v portainer_dаta:/data
portainer/portainer-ce:latest
Разберём ключи:
* -d — запуск в фоне (демон).
* --restart unless-stopped — политика перезапуска: Docker будет автоматически стартовать контейнер при перезагрузке системы.
* -p 9000:9000 — проброс порта: локальный порт 9000 связывается с портом 9000 внутри контейнера.
* -v /var/run/docker.sock:/var/run/docker.sock:ro — критически важный момент! Это монтирование сокета Docker позволяет Portainer управлять хост-системой. Флаг :ro (read-only) повышает безопасность.
* -v portainer_dаta:/data — монтирование тома для сохранения данных Portainer.
Проверка результата
Откройте в браузере http://IP_вашей_RaspberryPi:9000. Вы должны увидеть страницу первоначальной настройки Portainer. Поздравляю, ваш первый сервис в Docker работает!
Пишем docker-compose.yml: запускаем стек сервисов
Настоящая магия начинается с docker-compose.yml. В одном файле мы описываем целый набор взаимосвязанных контейнеров. Давайте создадим простой стек для мониторинга самого Docker.
Создадим папку и файл:
mkdir ~/docker-monitoring && cd ~/docker-monitoring
nano docker-compose.yml
Вставим следующую конфигурацию:
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
restart: unless-stopped
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prom_dаta:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
ports:
- "9090:9090"
networks:
- monitoring
node-exporter:
image: prom/node-exporter:latest
container_name: node-exporter
restart: unless-stopped
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--path.rootfs=/rootfs'
ports:
- "9100:9100"
networks:
- monitoring
grafana:
image: grafana/grafana:latest
container_name: grafana
restart: unless-stopped
ports:
- "3000:3000"
volumes:
- graf_dаta:/var/lib/grafana
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin123 # Смените на свой пароль!
networks:
- monitoring
volumes:
prom_dаta:
graf_dаta:
networks:
monitoring:
driver: bridge
Теперь нужно создать конфиг для Prometheus:
nano prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node-exporter'
static_configs:
- targets: ['node-exporter:9100']
Запускаем весь стек одной командой:
docker-compose up -d
Флаг -d запускает контейнеры в фоне. Управление: docker-compose logs для просмотра логов, docker-compose down для остановки и удаления.
Что мы получили?
* Prometheus (метрики) на порту 9090.
* Node-exporter (метрики системы) на порту 9100.
* Grafana (дашборды) на порту 3000 (логин: admin, пароль: admin123).
Это отличная основа для мониторинга не только Docker, но и всей системы. Например, можно подключить метрики от MQTT брокера Mosquitto или вашей домашней метеостанции.
Типичные ошибки и их решение
-
no matching manifest for linux/arm/v7 in the manifest list entries- Проблема: Вы пытаетесь запустить образ, который не собран для архитектуры вашего Pi.
- Решение: Ищите образы с поддержкой
arm64(илиaarch64). Часто у популярных проектов есть мультиархитектурные образы (например,linux/amd64, linux/arm64). Проверить можно на Docker Hub или с помощьюdocker manifest inspect имя_образа.
-
Контейнер запускается и сразу останавливается.
- Проблема: Чаще всего нет команды, которая держала бы процесс на переднем плане.
- Решение: Смотрите логи:
docker logs <имя_контейнера>. Убедитесь, что в Dockerfile или команде запуска указан долгоживущий процесс.
-
Ошибка прав доступа при монтировании volume.
- Проблема: Процесс в контейнере (часто работающий от имени пользователя с UID 1000) не может писать в смонтированную из хоста папку.
- Решение: Либо настройте правильные права на папку хоста (
chown -R 1000:1000 ./папка), либо задайтеuser:вdocker-compose.yml, либо запускайте контейнер от root (небезопасно).
-
Нехватка памяти (OOM Killer).
- Проблема: Raspberry Pi, особенно модели с 1-2 ГБ ОЗУ, могут «захлебнуться».
- Решение: В
docker-compose.ymlзадавайте лимиты:yaml services: my_service: mem_limit: 512m # Лимит в 512 МБ mem_reservation: 256m # Гарантированные 256 МБТакже используйте легковесные образы (Alpine Linux) и следите за общим потреблением черезhtopилиdocker stats.
Тестирование и проверка работоспособности
После запуска любого контейнера выполните несколько простых проверок:
# 1. Проверьте статус контейнеров (должны быть в состоянии "Up")
docker ps
# 2. Посмотрите логи на предмет ошибок (без флага -f будет вывод и выход)
docker logs --tail 50 <имя_контейнера>
# 3. Проверьте использование ресурсов
docker stats --no-stream
# 4. Зайдите внутрь работающего контейнера, если нужно (например, для отладки)
docker exec -it <имя_контейнера> /bin/sh
# 5. Проверьте, слушается ли порт на хосте
sudo netstat -tulpn | grep :<порт>
# или
curl -I http://localhost:<порт>
Заключение
Docker на Raspberry Pi открывает огромные возможности для домашних проектов. От развёртывания сложной инфраструктуры умного дома (Home Assistant, Mosquitto) до собственных веб-сервисов и инструментов мониторинга. Главное — начинать с простого, всегда читать логи и не бояться экспериментировать.
Следующим шагом может стать настройка автоматического обновления контейнеров с помощью watchtower или перенос ваших собственных скриптов (например, для умной теплицы или мониторинга качества воздуха) в Docker-образы для большей надёжности и портативности.
Удачи в контейнеризации! Не забывайте делать бэкапы своих docker-compose.yml файлов и томов с данными.
Понравилась статья?
Поставьте лайк и сохраните полезный материал в закладки.
Raspberry Pi как домашний сервер: что на нём можно запустить в 2024
Продлеваем жизнь SD-карте в Raspberry Pi: полное руководство по выживанию
Headless Raspberry Pi: Настройка без монитора через SSH — Полное руководство
Pi-hole на Raspberry Pi: Как я избавил всю домашнюю сеть от рекламы раз и навсегда
Raspberry Pi 4 vs Pi 5: стоит ли обновляться для DIY-проектов?
Raspberry Pi в роли VPN-сервера: настраиваем WireGuard для всей домашней сети