mikrotik-wiki.ru
Главная
Загрузка...

Docker-контейнеры на MikroTik RouterOS 7 — продвинутые сценарии

RouterOS 7.xКонтейнеры11 мин30 мар. 2026 г.
TelegramVK

Базовый запуск контейнера на MikroTik — лишь начало. В реальных проектах нужны изолированные сети, проброс портов, монтирование томов, переменные окружения и грамотное управление ресурсами. В этом руководстве разберём продвинутые сценарии использования контейнеров на RouterOS 7.20+: от тонкой настройки networking до мониторинга потребления CPU и RAM, работы с NFS-хранилищами и обновления образов без потери данных.

Описание

Зачем продвинутые сценарии

Контейнеры на маршрутизаторе решают конкретные задачи: DNS-фильтрация, reverse proxy, мониторинг, лёгкие веб-сервисы. Однако стандартная настройка «один контейнер — один veth — один bridge» быстро упирается в ограничения:

  • несколько контейнеров конкурируют за ресурсы — нужен контроль RAM и CPU;
  • контейнер теряет данные при перезагрузке — нужны persistent-тома;
  • сервис должен быть доступен из WAN — нужен NAT и firewall;
  • образ устарел — нужна процедура обновления без даунтайма;
  • логи и метрики — нужен мониторинг состояния.

Требования

ТребованиеМинимумРекомендуется
RouterOS7.4+7.20+
АрхитектураARM64 или x86ARM64 (RB5009, CCR2004) или x86 (CHR)
Оперативная память256 МБ свободной1 ГБ+ свободной
Хранилище512 МБ на USB или встроенный NAND4 ГБ+ USB/NVMe
УстройстваRB5009, CCR2004, CCR2116, CHRRB5009UPr+S+, CCR2116-12G-4S+

Внимание: устройства с 64–128 МБ RAM (hAP lite, hEX lite, mAP lite) не подходят для контейнеров. Даже если RouterOS позволит включить container mode, стабильная работа невозможна.

Архитектурные ограничения

Контейнеры на RouterOS — это не полноценный Docker Engine. Важно понимать границы:

ФункцияDocker EngineRouterOS Containers
docker-composeДаНет
Multi-container networkingДаОграниченно (вручную через bridge)
GPUДаНет
VolumesПолная поддержкаBind mounts через /container/mounts
Health checksДаНет (скрипты вручную)
Auto-restartДа (restart policies)start-on-boot=yes
RegistryНесколько одновременноОдин активный
Image layers cacheДаОграниченно

Когда использовать контейнеры на роутере, а когда — отдельный сервер

Контейнер на роутере подходит, если:

  • сервис лёгкий (DNS-фильтр, DDNS-клиент, простой веб-сервер);
  • нет отдельного сервера или Mini-PC;
  • нужен сервис, тесно связанный с сетью (Proxy, DoH resolver);
  • один-два контейнера с суммарным потреблением до 512 МБ RAM.

Отдельный сервер предпочтительнее, если:

  • нужна база данных, Nextcloud, Plex, Home Assistant;
  • нужно больше 2–3 контейнеров;
  • сервис потребляет более 512 МБ RAM;
  • нужны docker-compose, оркестрация, CI/CD.

Настройка

Шаг 1: Включение container mode

Если container mode ещё не активирован:

[admin@MikroTik] >
/system/device-mode/update container=yes

Маршрутизатор потребует физическое подтверждение — нажмите кнопку reset на устройстве или выполните перезагрузку. Для CHR физическое подтверждение не требуется.

[admin@MikroTik] >
# Проверяем после перезагрузки
/system/device-mode/print

В выводе должно быть container: yes.

Шаг 2: Подготовка хранилища

USB-накопитель

Рекомендуемый вариант — внешний USB-накопитель с файловой системой ext4:

[admin@MikroTik] >
# Просмотр доступных дисков
/disk/print

# Форматирование USB (уничтожит все данные!)
/disk/format-drive usb1 file-system=ext4 label=containers

# Настройка директории для контейнеров
/container/config/set ram-high=768M tmpdir=usb1/tmp

Параметр ram-high задаёт мягкий лимит RAM для всех контейнеров. При превышении система начинает агрессивно освобождать память. Жёсткого лимита (OOM kill) по умолчанию нет — его можно задать через ram-high на уровне отдельного контейнера.

NFS-хранилище

Для более серьёзных сценариев можно подключить NFS-шару с NAS:

[admin@MikroTik] >
# Создание точки монтирования для NFS
/container/mounts/add name=nfs-data src=/mnt/nfs/containers dst=/data

При этом NFS-шара должна быть предварительно смонтирована на уровне системы (через SMB/CIFS или NFS — зависит от модели и прошивки). На практике проще использовать локальный USB-накопитель, а NFS — для бэкапа данных контейнеров.

Шаг 3: Создание сетевой инфраструктуры для контейнеров

Правильная сетевая архитектура — ключ к стабильной работе нескольких контейнеров. Создадим выделенную подсеть.

Создание bridge для контейнеров

[admin@MikroTik] >
# Отдельный bridge для контейнерной подсети
/interface/bridge/add name=bridge-containers comment="Container network"

# IP-адрес на bridge — шлюз для контейнеров
/ip/address/add address=172.17.0.1/24 interface=bridge-containers comment="Container gateway"

Создание veth-интерфейсов

Каждый контейнер получает свой виртуальный Ethernet-интерфейс (veth). Один конец veth подключается к контейнеру, другой — к bridge:

[admin@MikroTik] >
# veth для первого контейнера (например, Nginx)
/interface/veth/add name=veth-nginx address=172.17.0.10/24 gateway=172.17.0.1 comment="Nginx container"

# veth для второго контейнера (например, скрипт)
/interface/veth/add name=veth-script address=172.17.0.11/24 gateway=172.17.0.1 comment="Custom script"

# veth для третьего контейнера
/interface/veth/add name=veth-monitor address=172.17.0.12/24 gateway=172.17.0.1 comment="Monitoring"

Добавление veth в bridge

[admin@MikroTik] >
/interface/bridge/port/add bridge=bridge-containers interface=veth-nginx
/interface/bridge/port/add bridge=bridge-containers interface=veth-script
/interface/bridge/port/add bridge=bridge-containers interface=veth-monitor

NAT для доступа контейнеров в интернет

Контейнерам нужен доступ наружу — для скачивания обновлений, списков фильтров и т.д.:

[admin@MikroTik] >
# Masquerade для контейнерной подсети
/ip/firewall/nat/add chain=srcnat action=masquerade src-address=172.17.0.0/24 out-interface-list=WAN comment="Container NAT"

Проброс портов из WAN в контейнер

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

[admin@MikroTik] >
# Проброс порта 8080 из WAN в Nginx-контейнер
/ip/firewall/nat/add chain=dstnat action=dst-nat to-addresses=172.17.0.10 to-ports=80 protocol=tcp dst-port=8080 in-interface-list=WAN comment="Forward 8080 to Nginx"

DNS для контейнеров

Контейнерам нужен DNS. Можно указать DNS-серверы в переменных окружения контейнера или настроить MikroTik как DNS-resolver для контейнерной подсети:

[admin@MikroTik] >
# Разрешаем DNS-запросы из контейнерной подсети
/ip/dns/set allow-remote-requests=yes

Шаг 4: Переменные окружения

Многие контейнеры настраиваются через environment variables. В RouterOS для этого есть отдельная сущность:

[admin@MikroTik] >
# Создание набора переменных для Nginx
/container/envs/add name=nginx-env key=TZ value="Europe/Moscow"
/container/envs/add name=nginx-env key=NGINX_HOST value="router.local"
/container/envs/add name=nginx-env key=NGINX_PORT value="80"

Все переменные с одинаковым name объединяются в один набор и передаются контейнеру при создании.

Шаг 5: Точки монтирования (mounts)

Bind mounts позволяют контейнеру читать и писать файлы на хост-системе:

[admin@MikroTik] >
# Монтирование директории для конфигурации Nginx
/container/mounts/add name=nginx-config src=usb1/nginx/conf dst=/etc/nginx/conf.d

# Монтирование директории для статических файлов
/container/mounts/add name=nginx-html src=usb1/nginx/html dst=/usr/share/nginx/html

# Монтирование для логов
/container/mounts/add name=nginx-logs src=usb1/nginx/logs dst=/var/log/nginx

Параметры:

  • src — путь на маршрутизаторе (относительно корня файловой системы);
  • dst — путь внутри контейнера.

Создайте директории на USB заранее:

[admin@MikroTik] >
/file/mkdir usb1/nginx
/file/mkdir usb1/nginx/conf
/file/mkdir usb1/nginx/html
/file/mkdir usb1/nginx/logs

Шаг 6: Создание и запуск контейнеров

Пример 1: Nginx веб-сервер

[admin@MikroTik] >
# Настройка registry (Docker Hub по умолчанию)
/container/config/set registry-url=https://registry-1.docker.io tmpdir=usb1/tmp

# Создание контейнера Nginx
/container/add remote-image=library/nginx:alpine interface=veth-nginx root-dir=usb1/nginx-root envlist=nginx-env mounts=nginx-config,nginx-html,nginx-logs start-on-boot=yes hostname=nginx logging=yes comment="Nginx web server"

Параметры команды /container/add:

ПараметрОписание
remote-imageОбраз из Docker Hub (формат: library/имя:тег)
interfaceveth-интерфейс для контейнера
root-dirДиректория для корневой ФС контейнера
envlistНабор переменных окружения
mountsСписок точек монтирования через запятую
start-on-bootАвтозапуск при загрузке маршрутизатора
hostnameИмя хоста внутри контейнера
loggingЗапись логов контейнера в лог RouterOS

Скачивание образа может занять несколько минут в зависимости от скорости интернета. Следите за статусом:

[admin@MikroTik] >
/container/print

Статусы контейнера:

  • extracting — распаковка образа;
  • stopped — готов к запуску;
  • running — работает;
  • error — ошибка (смотрите лог).
[admin@MikroTik] >
# Запуск контейнера (после скачивания)
/container/start 0

Пример 2: Пользовательский скрипт на Python

Создадим контейнер для запуска собственного Python-скрипта, который, например, отправляет уведомления в Telegram:

[admin@MikroTik] >
# Переменные окружения
/container/envs/add name=script-env key=TZ value="Europe/Moscow"
/container/envs/add name=script-env key=BOT_TOKEN value="123456:ABC-DEF"
/container/envs/add name=script-env key=CHAT_ID value="-100123456789"

# Монтирование директории со скриптами
/container/mounts/add name=script-data src=usb1/scripts dst=/app/data

# Создание контейнера
/container/add remote-image=library/python:3.12-alpine interface=veth-script root-dir=usb1/python-root envlist=script-env mounts=script-data start-on-boot=yes hostname=script cmd="python /app/data/main.py" logging=yes comment="Custom Python script"

Параметр cmd переопределяет команду запуска контейнера. Скрипт main.py должен лежать в usb1/scripts/ на маршрутизаторе.

Шаг 7: Управление контейнерами

Полный набор команд управления:

[admin@MikroTik] >
# Список всех контейнеров
/container/print

# Подробная информация о контейнере
/container/print detail where name~"nginx"

# Запуск контейнера по номеру
/container/start 0

# Остановка контейнера
/container/stop 0

# Удаление контейнера (должен быть остановлен)
/container/remove 0

# Просмотр логов контейнера
/log/print where topics~"container"

# Выполнение команды внутри контейнера (shell)
/container/shell 0

При использовании /container/shell вы попадаете внутрь контейнера. Для выхода нажмите Ctrl+D или введите exit.

Шаг 8: Мониторинг ресурсов

Общие ресурсы системы

[admin@MikroTik] >
# Текущая загрузка CPU и RAM
/system/resource/print

# Мониторинг в реальном времени (обновление каждую секунду)
/system/resource/monitor

Ресурсы контейнеров

[admin@MikroTik] >
# Просмотр потребления RAM контейнерами
/container/print detail

В выводе обратите внимание на поля:

  • status — текущий статус;
  • arch — архитектура образа.

Скрипт для мониторинга

Создадим скрипт, который проверяет доступность контейнера и перезапускает его при падении:

[admin@MikroTik] >
/system/script/add name=container-watchdog source={
    :local containerName "nginx"
    :local containerID 0
    :local status [/container/get $containerID status]
    :if ($status != "running") do={
        :log warning ("Container $containerName is $status, restarting...")
        /container/start $containerID
        :delay 5s
        :local newStatus [/container/get $containerID status]
        :if ($newStatus = "running") do={
            :log info ("Container $containerName restarted successfully")
        } else={
            :log error ("Container $containerName failed to restart: $newStatus")
        }
    }
}

# Запуск скрипта по расписанию каждые 5 минут
/system/scheduler/add name=container-watchdog interval=5m on-event="/system/script/run container-watchdog"

Шаг 9: Обновление образов

RouterOS не поддерживает автоматическое обновление контейнеров. Процедура обновления вручную:

[admin@MikroTik] >
# 1. Остановка контейнера
/container/stop 0

# 2. Удаление контейнера (данные в mounts сохранятся!)
/container/remove 0

# 3. Создание контейнера с тем же образом (скачается latest)
/container/add remote-image=library/nginx:alpine interface=veth-nginx root-dir=usb1/nginx-root envlist=nginx-env mounts=nginx-config,nginx-html,nginx-logs start-on-boot=yes hostname=nginx logging=yes

# 4. Ожидание скачивания и запуск
# Проверяем статус
/container/print

# 5. Запуск
/container/start 0

Ключевой момент: данные в точках монтирования (mounts) сохраняются при удалении контейнера. Удаляется только корневая ФС контейнера (root-dir). Поэтому конфигурации и данные нужно хранить именно в mounts.

Шаг 10: Несколько контейнеров — лучшие практики

При запуске 2–3 контейнеров одновременно:

[admin@MikroTik] >
# Ограничение RAM для каждого контейнера
/container/config/set ram-high=1024M

# Убедитесь, что каждый контейнер использует свой:
# - veth-интерфейс с уникальным IP
# - root-dir (отдельная директория)
# - набор mounts (не пересекаются)

# Проверка всей контейнерной инфраструктуры
/interface/veth/print
/interface/bridge/port/print where bridge=bridge-containers
/container/envs/print
/container/mounts/print
/container/print

Проверка

Проверка сетевой связности

[admin@MikroTik] >
# Ping контейнера с маршрутизатора
/ping 172.17.0.10 count=4

# Ping интернета из контейнера (через shell)
/container/shell 0
# Внутри контейнера:
# ping 8.8.8.8
# exit

# Проверка NAT-правил
/ip/firewall/nat/print where comment~"Container"

# Проверка проброса портов
/ip/firewall/nat/print where comment~"Nginx"

Проверка работы контейнера

[admin@MikroTik] >
# Статус всех контейнеров
/container/print

# Логи контейнера
/log/print where topics~"container"

# Проверка veth-интерфейсов
/interface/veth/print
/interface/print where type=veth

# Проверка bridge-портов
/interface/bridge/port/print where bridge=bridge-containers

Проверка веб-сервера (Nginx)

[admin@MikroTik] >
# HTTP-запрос к контейнеру с маршрутизатора
/tool/fetch url="http://172.17.0.10" mode=http dst-path=test.html

# Просмотр результата
/file/print where name=test.html

Проверка потребления ресурсов

[admin@MikroTik] >
# Общие ресурсы
/system/resource/print

# Свободное место на USB
/disk/print

# Список файлов контейнера
/file/print where name~"usb1/nginx"

Типичные ошибки

Ошибка 1: «container: no» после перезагрузки

Симптом: после перезагрузки container mode не активирован.

Причина: не было физического подтверждения (нажатие кнопки reset).

Решение:

[admin@MikroTik] >
# Повторно активируем
/system/device-mode/update container=yes
# Нажмите кнопку reset на устройстве в течение 60 секунд

На CHR физическое подтверждение не требуется — достаточно перезагрузки.

Ошибка 2: Контейнер не скачивается — «error» в статусе

Симптом: после /container/add статус навсегда extracting или сразу error.

Причина: нет доступа к Docker Hub, неправильный registry URL, нет DNS.

Решение:

[admin@MikroTik] >
# Проверяем DNS
/ip/dns/print
/ping registry-1.docker.io count=4

# Проверяем registry URL
/container/config/print
# registry-url должен быть https://registry-1.docker.io

# Исправляем при необходимости
/container/config/set registry-url=https://registry-1.docker.io

# Проверяем NAT (маршрутизатор сам должен иметь доступ в интернет)
/ping 8.8.8.8 count=4

Ошибка 3: Несовпадение архитектуры образа

Симптом: контейнер скачивается, но не запускается — error в статусе.

Причина: образ собран для другой архитектуры (например, amd64 на ARM-устройстве).

Решение:

[admin@MikroTik] >
# Проверяем архитектуру устройства
/system/resource/print
# Ищем поле architecture-name: arm64 / x86 / arm

# Используйте образ, соответствующий архитектуре
# Для ARM64 устройств: образ должен поддерживать arm64/aarch64
# Многие популярные образы (nginx:alpine, pihole) — мультиархитектурные

Ошибка 4: «not enough disk space»

Симптом: ошибка при скачивании образа.

Причина: недостаточно места на диске (встроенный NAND или USB).

Решение:

[admin@MikroTik] >
# Проверяем место
/system/resource/print
/disk/print

# Очищаем старые контейнеры
/container/stop 0
/container/remove 0

# Удаляем директорию старого контейнера
/file/remove usb1/old-container-root

Ошибка 5: Контейнер не получает сетевой доступ

Симптом: контейнер запущен, но не может выйти в интернет и не пингуется.

Причина: veth не добавлен в bridge, отсутствует NAT-правило, неправильная адресация.

Решение:

[admin@MikroTik] >
# Проверяем veth
/interface/veth/print
# Убедитесь, что address и gateway заданы корректно

# Проверяем bridge
/interface/bridge/port/print where bridge=bridge-containers
# veth должен быть в списке портов

# Проверяем IP на bridge
/ip/address/print where interface=bridge-containers
# Должен быть 172.17.0.1/24

# Проверяем NAT
/ip/firewall/nat/print where comment~"Container"
# Должно быть правило masquerade для 172.17.0.0/24

Ошибка 6: Контейнер не стартует после перезагрузки

Симптом: при start-on-boot=yes контейнер не запускается автоматически.

Причина: USB-накопитель монтируется позже, чем стартуют контейнеры.

Решение:

[admin@MikroTik] >
# Добавьте задержку запуска через scheduler
/system/scheduler/add name=delayed-container-start on-event="/container/start 0" start-time=startup interval=0 comment="Start container after boot"

Альтернативный вариант — использовать скрипт с проверкой доступности диска:

[admin@MikroTik] >
/system/script/add name=start-containers-delayed source={
    :delay 30s
    :if ([/disk/find where label="containers"] != "") do={
        :foreach id in=[/container/find where status!=running] do={
            /container/start $id
            :delay 5s
        }
        :log info "All containers started"
    } else={
        :log error "USB disk not ready, containers not started"
    }
}

/system/scheduler/add name=start-containers on-event="/system/script/run start-containers-delayed" start-time=startup interval=0

Ошибка 7: Конфликт портов между контейнерами

Симптом: два контейнера пытаются слушать один и тот же порт.

Причина: контейнеры используют разные IP (veth), поэтому конфликта внутри нет. Но если два dst-nat правила пробрасывают один и тот же внешний порт — будет конфликт.

Решение:

[admin@MikroTik] >
# Проверяем NAT-правила
/ip/firewall/nat/print where chain=dstnat

# Используйте разные внешние порты:
# Nginx: WAN:8080 -> 172.17.0.10:80
# Другой сервис: WAN:8081 -> 172.17.0.11:80

Рекомендации по безопасности

Контейнеры на маршрутизаторе представляют дополнительный вектор атаки. Соблюдайте правила:

[admin@MikroTik] >
# 1. Ограничьте доступ к контейнерам из WAN — только нужные порты
/ip/firewall/filter/add chain=forward action=drop in-interface-list=WAN dst-address=172.17.0.0/24 comment="Block direct WAN access to containers"

# Разрешите только конкретные порты ДО этого правила:
/ip/firewall/filter/add chain=forward action=accept in-interface-list=WAN dst-address=172.17.0.10 dst-port=80 protocol=tcp comment="Allow HTTP to Nginx container"

# 2. Ограничьте доступ контейнеров к управлению маршрутизатором
/ip/firewall/filter/add chain=input action=drop src-address=172.17.0.0/24 dst-port=80,443,8291,22,23,8728,8729 protocol=tcp comment="Block container access to management"

# 3. Регулярно обновляйте образы контейнеров
# Используйте процедуру из Шага 9

Всегда используйте конкретные теги образов (например, nginx:1.27-alpine) вместо latest, чтобы контролировать версии и избежать неожиданных обновлений при пересоздании контейнера.

[admin@MikroTik] >
/system/device-mode/update container=yes
# Проверяем после перезагрузки
/system/device-mode/print
# Просмотр доступных дисков
/disk/print

# Форматирование USB (уничтожит все данные!)
/disk/format-drive usb1 file-system=ext4 label=containers

# Настройка директории для контейнеров
/container/config/set ram-high=768M tmpdir=usb1/tmp
# Создание точки монтирования для NFS
/container/mounts/add name=nfs-data src=/mnt/nfs/containers dst=/data
# Отдельный bridge для контейнерной подсети
/interface/bridge/add name=bridge-containers comment="Container network"

# IP-адрес на bridge — шлюз для контейнеров
/ip/address/add address=172.17.0.1/24 interface=bridge-containers comment="Container gateway"
# veth для первого контейнера (например, Nginx)
/interface/veth/add name=veth-nginx address=172.17.0.10/24 gateway=172.17.0.1 comment="Nginx container"

# veth для второго контейнера (например, скрипт)
/interface/veth/add name=veth-script address=172.17.0.11/24 gateway=172.17.0.1 comment="Custom script"

# veth для третьего контейнера
/interface/veth/add name=veth-monitor address=172.17.0.12/24 gateway=172.17.0.1 comment="Monitoring"
/interface/bridge/port/add bridge=bridge-containers interface=veth-nginx
/interface/bridge/port/add bridge=bridge-containers interface=veth-script
/interface/bridge/port/add bridge=bridge-containers interface=veth-monitor
# Masquerade для контейнерной подсети
/ip/firewall/nat/add chain=srcnat action=masquerade src-address=172.17.0.0/24 out-interface-list=WAN comment="Container NAT"
# Проброс порта 8080 из WAN в Nginx-контейнер
/ip/firewall/nat/add chain=dstnat action=dst-nat to-addresses=172.17.0.10 to-ports=80 protocol=tcp dst-port=8080 in-interface-list=WAN comment="Forward 8080 to Nginx"
# Разрешаем DNS-запросы из контейнерной подсети
/ip/dns/set allow-remote-requests=yes
# Создание набора переменных для Nginx
/container/envs/add name=nginx-env key=TZ value="Europe/Moscow"
/container/envs/add name=nginx-env key=NGINX_HOST value="router.local"
/container/envs/add name=nginx-env key=NGINX_PORT value="80"
# Монтирование директории для конфигурации Nginx
/container/mounts/add name=nginx-config src=usb1/nginx/conf dst=/etc/nginx/conf.d

# Монтирование директории для статических файлов
/container/mounts/add name=nginx-html src=usb1/nginx/html dst=/usr/share/nginx/html

# Монтирование для логов
/container/mounts/add name=nginx-logs src=usb1/nginx/logs dst=/var/log/nginx
/file/mkdir usb1/nginx
/file/mkdir usb1/nginx/conf
/file/mkdir usb1/nginx/html
/file/mkdir usb1/nginx/logs
# Настройка registry (Docker Hub по умолчанию)
/container/config/set registry-url=https://registry-1.docker.io tmpdir=usb1/tmp

# Создание контейнера Nginx
/container/add remote-image=library/nginx:alpine interface=veth-nginx root-dir=usb1/nginx-root envlist=nginx-env mounts=nginx-config,nginx-html,nginx-logs start-on-boot=yes hostname=nginx logging=yes comment="Nginx web server"
/container/print
# Запуск контейнера (после скачивания)
/container/start 0
# Переменные окружения
/container/envs/add name=script-env key=TZ value="Europe/Moscow"
/container/envs/add name=script-env key=BOT_TOKEN value="123456:ABC-DEF"
/container/envs/add name=script-env key=CHAT_ID value="-100123456789"

# Монтирование директории со скриптами
/container/mounts/add name=script-data src=usb1/scripts dst=/app/data

# Создание контейнера
/container/add remote-image=library/python:3.12-alpine interface=veth-script root-dir=usb1/python-root envlist=script-env mounts=script-data start-on-boot=yes hostname=script cmd="python /app/data/main.py" logging=yes comment="Custom Python script"
# Список всех контейнеров
/container/print

# Подробная информация о контейнере
/container/print detail where name~"nginx"

# Запуск контейнера по номеру
/container/start 0

# Остановка контейнера
/container/stop 0

# Удаление контейнера (должен быть остановлен)
/container/remove 0

# Просмотр логов контейнера
/log/print where topics~"container"

# Выполнение команды внутри контейнера (shell)
/container/shell 0
# Текущая загрузка CPU и RAM
/system/resource/print

# Мониторинг в реальном времени (обновление каждую секунду)
/system/resource/monitor
# Просмотр потребления RAM контейнерами
/container/print detail
/system/script/add name=container-watchdog source={
    :local containerName "nginx"
    :local containerID 0
    :local status [/container/get $containerID status]
    :if ($status != "running") do={
        :log warning ("Container $containerName is $status, restarting...")
        /container/start $containerID
        :delay 5s
        :local newStatus [/container/get $containerID status]
        :if ($newStatus = "running") do={
            :log info ("Container $containerName restarted successfully")
        } else={
            :log error ("Container $containerName failed to restart: $newStatus")
        }
    }
}

# Запуск скрипта по расписанию каждые 5 минут
/system/scheduler/add name=container-watchdog interval=5m on-event="/system/script/run container-watchdog"
# 1. Остановка контейнера
/container/stop 0

# 2. Удаление контейнера (данные в mounts сохранятся!)
/container/remove 0

# 3. Создание контейнера с тем же образом (скачается latest)
/container/add remote-image=library/nginx:alpine interface=veth-nginx root-dir=usb1/nginx-root envlist=nginx-env mounts=nginx-config,nginx-html,nginx-logs start-on-boot=yes hostname=nginx logging=yes

# 4. Ожидание скачивания и запуск
# Проверяем статус
/container/print

# 5. Запуск
/container/start 0
# Ограничение RAM для каждого контейнера
/container/config/set ram-high=1024M

# Убедитесь, что каждый контейнер использует свой:
# - veth-интерфейс с уникальным IP
# - root-dir (отдельная директория)
# - набор mounts (не пересекаются)

# Проверка всей контейнерной инфраструктуры
/interface/veth/print
/interface/bridge/port/print where bridge=bridge-containers
/container/envs/print
/container/mounts/print
/container/print
# Ping контейнера с маршрутизатора
/ping 172.17.0.10 count=4

# Ping интернета из контейнера (через shell)
/container/shell 0
# Внутри контейнера:
# ping 8.8.8.8
# exit

# Проверка NAT-правил
/ip/firewall/nat/print where comment~"Container"

# Проверка проброса портов
/ip/firewall/nat/print where comment~"Nginx"
# Статус всех контейнеров
/container/print

# Логи контейнера
/log/print where topics~"container"

# Проверка veth-интерфейсов
/interface/veth/print
/interface/print where type=veth

# Проверка bridge-портов
/interface/bridge/port/print where bridge=bridge-containers
# HTTP-запрос к контейнеру с маршрутизатора
/tool/fetch url="http://172.17.0.10" mode=http dst-path=test.html

# Просмотр результата
/file/print where name=test.html
# Общие ресурсы
/system/resource/print

# Свободное место на USB
/disk/print

# Список файлов контейнера
/file/print where name~"usb1/nginx"
# Повторно активируем
/system/device-mode/update container=yes
# Нажмите кнопку reset на устройстве в течение 60 секунд
# Проверяем DNS
/ip/dns/print
/ping registry-1.docker.io count=4

# Проверяем registry URL
/container/config/print
# registry-url должен быть https://registry-1.docker.io

# Исправляем при необходимости
/container/config/set registry-url=https://registry-1.docker.io

# Проверяем NAT (маршрутизатор сам должен иметь доступ в интернет)
/ping 8.8.8.8 count=4
# Проверяем архитектуру устройства
/system/resource/print
# Ищем поле architecture-name: arm64 / x86 / arm

# Используйте образ, соответствующий архитектуре
# Для ARM64 устройств: образ должен поддерживать arm64/aarch64
# Многие популярные образы (nginx:alpine, pihole) — мультиархитектурные
# Проверяем место
/system/resource/print
/disk/print

# Очищаем старые контейнеры
/container/stop 0
/container/remove 0

# Удаляем директорию старого контейнера
/file/remove usb1/old-container-root
# Проверяем veth
/interface/veth/print
# Убедитесь, что address и gateway заданы корректно

# Проверяем bridge
/interface/bridge/port/print where bridge=bridge-containers
# veth должен быть в списке портов

# Проверяем IP на bridge
/ip/address/print where interface=bridge-containers
# Должен быть 172.17.0.1/24

# Проверяем NAT
/ip/firewall/nat/print where comment~"Container"
# Должно быть правило masquerade для 172.17.0.0/24
# Добавьте задержку запуска через scheduler
/system/scheduler/add name=delayed-container-start on-event="/container/start 0" start-time=startup interval=0 comment="Start container after boot"
/system/script/add name=start-containers-delayed source={
    :delay 30s
    :if ([/disk/find where label="containers"] != "") do={
        :foreach id in=[/container/find where status!=running] do={
            /container/start $id
            :delay 5s
        }
        :log info "All containers started"
    } else={
        :log error "USB disk not ready, containers not started"
    }
}

/system/scheduler/add name=start-containers on-event="/system/script/run start-containers-delayed" start-time=startup interval=0
# Проверяем NAT-правила
/ip/firewall/nat/print where chain=dstnat

# Используйте разные внешние порты:
# Nginx: WAN:8080 -> 172.17.0.10:80
# Другой сервис: WAN:8081 -> 172.17.0.11:80
# 1. Ограничьте доступ к контейнерам из WAN — только нужные порты
/ip/firewall/filter/add chain=forward action=drop in-interface-list=WAN dst-address=172.17.0.0/24 comment="Block direct WAN access to containers"

# Разрешите только конкретные порты ДО этого правила:
/ip/firewall/filter/add chain=forward action=accept in-interface-list=WAN dst-address=172.17.0.10 dst-port=80 protocol=tcp comment="Allow HTTP to Nginx container"

# 2. Ограничьте доступ контейнеров к управлению маршрутизатором
/ip/firewall/filter/add chain=input action=drop src-address=172.17.0.0/24 dst-port=80,443,8291,22,23,8728,8729 protocol=tcp comment="Block container access to management"

# 3. Регулярно обновляйте образы контейнеров
# Используйте процедуру из Шага 9
Контейнеры / Docker-контейнеры на MikroTik RouterOS 7 — продвинутые сценарии