Если у вас несколько Docker-хостов, рано или поздно встаёт вопрос: как управлять ими из одного места, не превращая это в зоопарк SSH-сессий и ручных команд. Portainer решает именно эту задачу — он даёт единый веб-интерфейс для управления всей контейнерной инфраструктурой.
В качестве операционной системы выбрана Ubuntu 24.04 LTS. Все примеры команд и конфигураций рассчитаны именно под неё. Для установки потребуется доступ к серверу с правами root и домен с настроенной DNS A-записью. Доменное имя можно зарегистрировать в разделе «Регистрация доменов».
В примерах ниже используются следующие значения: IP-адрес сервера — 82.146.46.206, доменное имя — portainer.firstvds.ru. В своей конфигурации замените их на собственные.
Если вы не хотите разворачивать Portainer вручную, можно заказать виртуальный сервер с уже предустановленным Portainer — готовые рецепты позволяют запустить окружение за несколько минут после создания VDS.
Что такое Portainer и как он устроен
Portainer — веб-платформа для управления контейнерной инфраструктурой через единый GUI и REST API. Она подключается к средам на базе Docker, Docker Swarm и Kubernetes и позволяет администрировать их из одного интерфейса. При этом Portainer не является оркестратором — он не управляет кластером и не распределяет нагрузку, а работает поверх этих платформ как инструмент управления.
Portainer используют для централизованного управления контейнерами, образами, сетями и томами через веб-интерфейс. Также через него можно разворачивать приложения и настраивать доступ пользователей. Расширенные функции, такие как гибкая аутентификация и RBAC, доступны в платной версии.
Как устроен Portainer
Portainer состоит из центрального сервера управления (Portainer Server) и подключаемых окружений. В роли окружений могут выступать отдельные Docker-хосты, а также кластеры на базе Docker, Docker Swarm и Kubernetes.
Portainer Server — основной компонент системы. Он предоставляет веб-интерфейс, API, хранит настройки и управляет подключёнными средами.
Подключение окружений к Portainer Server может выполняться несколькими способами:
- Docker API / Socket или через Agent — прямое подключение для локальных или доступных по сети Docker-хостов.
- Edge Agent Standard — для удалённых площадок и узлов за NAT, firewall или при нестабильном соединении.
Выбор способа зависит от сетевой доступности, требований безопасности и особенностей инфраструктуры.
Основное различие между Agent и Edge Agent Standard заключается в модели соединения с сервером Portainer:
- Agent — сервер сам инициирует соединение с агентом. Подходит для узлов с прямой сетевой доступностью.
- Edge Agent Standard — агент сам инициирует подключение к серверу по модели периодического опроса (polling). Поэтому лучше подходит для удалённых и изолированных окружений.
Установка Docker
Для установки Docker воспользуемся официальным репозиторием, так как он позволяет установить актуальные версии пакетов, а не более старые сборки из стандартных репозиториев Ubuntu.
Сначала обновим индекс пакетов и установим утилиты, которые понадобятся для подключения внешнего репозитория: ca-certificates — для проверки TLS-сертификатов, curl — для загрузки ключа подписи.
apt update
apt install -y ca-certificates curlДалее создадим каталог для хранения ключей репозиториев APT, загрузим официальный GPG-ключ Docker и настроим для него корректные права доступа. Этот ключ нужен для проверки подлинности пакетов из репозитория Docker.
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.ascПосле этого добавим официальный репозиторий Docker в список источников APT. В конфигурации автоматически используется кодовое имя текущего выпуска Ubuntu, чтобы репозиторий соответствовал установленной версии системы.
tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOFТеперь снова обновим индекс пакетов, чтобы APT получил информацию о пакетах из нового репозитория, и установим Docker Engine, CLI, containerd, а также плагины Buildx и Docker Compose.
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginУстановка Portainer Server
Portainer Server можно установить разными способами: например, запустить контейнер вручную через docker run, развернуть через Docker Compose или использовать Kubernetes.
В нашем случае выбран вариант с Docker Compose, так как он проще в сопровождении: все параметры запуска хранятся в одном YAML-файле, конфигурацию удобно изменять, а сам сервис — перезапускать и обновлять стандартными командами Compose.
Сначала создадим отдельную директорию для файлов Portainer.
mkdir -p /opt/portainerДалее создадим файл docker-compose.yml с описанием сервиса. В нём задаются образ Portainer CE, политика перезапуска, подключение к Docker socket, постоянное хранилище для данных и проброс необходимых портов.
cat > /opt/portainer/docker-compose.yml << EOL
services:
portainer:
container_name: portainer
image: portainer/portainer-ce:2.39.3
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
ports:
- "127.0.0.1:9443:9443"
- "82.146.46.206:8000:8000"
volumes:
portainer_data:
name: portainer_data
networks:
default:
name: portainer_network
EOLНастройка Nginx + HTTPS
Portainer предоставляет собственный веб-интерфейс по порту 9443, но для удобного доступа по доменному имени и с валидным TLS-сертификатом обычно перед ним ставят Nginx в роли reverse proxy. Для выпуска сертификата в этой инструкции выбран Let's Encrypt — бесплатный центр сертификации.
Перед началом настройки убедитесь, что доменное имя указывает на IP-адрес сервера. Это необходимо для того, чтобы Let's Encrypt смог проверить владение доменом и выпустить сертификат. В нашем примере домен portainer.firstvds.ru должен указывать на 82.146.46.206.
Проверить это можно командой:
dig +short portainer.firstvds.ruВ ответ должен отображаться IP-адрес вашего сервера.
Если домен ещё не настроен, создайте A-запись в панели управления DNS у регистратора или DNS-провайдера: в качестве имени укажите нужный поддомен, а в качестве значения — внешний IP-адрес сервера. Если у вас ещё нет домена, его можно зарегистрировать в разделе «Регистрация доменов».
Также нужно убедиться, что на сервере открыты порты 80/tcp и 443/tcp: они нужны для HTTP-проверки Let's Encrypt и HTTPS-доступа к веб-интерфейсу Portainer.
Проверить, слушает ли сервер нужные порты, можно после настройки сервисов командой:
ss -tulpn | grep -E ':80|:443'Приступим к настройке Nginx и выпуску TLS-сертификата.
Шаг 1. Устанавливаем Nginx и Certbot.
Установим Nginx, Certbot и модуль python3-certbot-nginx, который позволяет автоматически выпускать и подключать сертификаты для Nginx.
apt update
apt install -y nginx certbot python3-certbot-nginxДобавим Nginx в автозагрузку и сразу запустим службу:
systemctl enable --now nginxШаг 2. Получаем TLS-сертификат.
Выпустим сертификат для домена — в нашем случае portainer.firstvds.ru. Во время выполнения Certbot может запросить email для уведомлений и согласие с условиями использования.
certbot --nginx -d portainer.firstvds.ruЕсли сертификат будет выпущен успешно, Certbot создаст файлы сертификата в каталоге /etc/letsencrypt/live/portainer.firstvds.ru/.
Шаг 3. Создаём конфигурацию Nginx.
Создадим файл конфигурации, в котором настроим Nginx как reverse proxy для Portainer. В этой конфигурации HTTP-запросы на порт 80 будут автоматически перенаправляться на HTTPS, а сам Nginx будет проксировать HTTPS-трафик на локальный порт 9443, где работает Portainer.
Перед выполнением команды замените portainer.firstvds.ru на своё доменное имя.
cat > /etc/nginx/sites-available/portainer.firstvds.ru << 'EOL'
server {
listen 80;
server_name portainer.firstvds.ru;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
server_name portainer.firstvds.ru;
ssl_certificate /etc/letsencrypt/live/portainer.firstvds.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/portainer.firstvds.ru/privkey.pem;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
client_max_body_size 0;
location / {
proxy_pass https://127.0.0.1:9443;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_ssl_verify off;
}
}
EOLШаг 4. Активируем сайт и применяем конфигурацию.
После создания конфигурации нужно включить сайт, проверить синтаксис конфигурации Nginx и перезагрузить сервис.
ln -s /etc/nginx/sites-available/portainer.firstvds.ru /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginxНастройка firewall
После установки Portainer, Docker и Nginx стоит ограничить входящие и транзитные сетевые подключения на уровне файрвола. Это нужно для того, чтобы сервер принимал только необходимые соединения: например, SSH для администрирования, HTTP/HTTPS для веб-доступа и служебный трафик Docker. Такой подход уменьшает поверхность атаки — чем меньше открытых портов и разрешённых подключений, тем сложнее злоумышленнику найти уязвимость — и делает сетевую конфигурацию более предсказуемой.
В Ubuntu для базовой настройки файрвола часто используют утилиту ufw, однако в этой инструкции выбран nftables. Это современный встроенный механизм фильтрации трафика в Linux, который даёт больше гибкости и лучше подходит для тонкой настройки правил, особенно если сервер работает с Docker. Подробнее о работе с ним можно прочитать в отдельной статье про nftables.
В этой схеме нам нужно разрешить только тот трафик, который действительно используется:
- 22/tcp — для SSH-доступа к серверу;
- 80/tcp — для HTTP и прохождения проверки Let's Encrypt;
- 443/tcp — для HTTPS-доступа к веб-интерфейсу Portainer через Nginx;
- 8000/tcp — для служебного взаимодействия Portainer с Edge Agent Standard.
Итак, приступим к настройке фаервола.
Шаг 1. Отключаем UFW и устанавливаем nftables
Если на сервере включён ufw, его лучше отключить, чтобы не смешивать два разных механизма управления файрволом. После этого установим пакет nftables.
systemctl disable --now ufw
apt remove -y ufw
apt install -y nftablesШаг 2. Создаём конфигурацию правил
Ниже приведён пример конфигурации файла /etc/nftables.conf. Он нужен для того, чтобы явно описать, какой трафик серверу разрешён, а какой будет блокироваться.
В этой конфигурации по умолчанию запрещаются входящие и транзитные подключения, но при этом разрешаются уже установленные соединения, локальный трафик, доступ по SSH, а также HTTP/HTTPS для работы Nginx и веб-интерфейса Portainer. Отдельно учитывается сетевое взаимодействие Docker и Edge Agent Standard.
cat > /etc/nftables.conf << 'EOL'
#!/usr/sbin/nft -f
define EDGE_AGENT_STANDARD = { 127.0.0.1 }
table inet filter {
chain input {
type filter hook input priority filter + 1; policy drop;
ct state vmap { established : accept, related : accept, invalid : drop }
ip protocol icmp limit rate 4/second accept
ip6 nexthdr ipv6-icmp limit rate 4/second accept
ip protocol igmp limit rate 4/second accept
iif lo ct state new accept
tcp dport ssh ct state new accept
}
}
# Сначала удаляем старую таблицу, чтобы при повторной загрузке правил не было конфликтов/дубликатов.
delete table inet filter
# Основная конфигурация
table inet filter {
chain input {
type filter hook input priority filter + 1; policy drop;
ct state vmap { established : accept, related : accept, invalid : drop }
ip protocol icmp limit rate 4/second accept
ip6 nexthdr ipv6-icmp limit rate 4/second accept
ip protocol igmp limit rate 4/second accept
iif lo ct state new counter accept
# SSH
tcp dport ssh ct state new counter accept
# HTTP/HTTPS (UI + API + Edge Agent polling)
tcp dport { http, https } ct state new counter accept
}
chain forward {
type filter hook forward priority filter; policy drop;
ct state vmap { established : accept, related : accept, invalid : drop }
# Docker bridge-сети
iifname "docker0" ct state new counter accept
iifname "br-*" ct state new counter accept
# Edge Agent Standard tunnel
ip saddr $EDGE_AGENT_STANDARD ip protocol tcp ct original proto-dst 8000 ct state new counter accept
}
}
EOLДобавление новых Edge Agent: если Edge Agent Standard будет подключаться с других Docker-хостов, их IP-адреса нужно добавить в переменную EDGE_AGENT_STANDARD. Например:
define EDGE_AGENT_STANDARD = { 192.168.1.10, 192.168.1.11, 10.0.0.5 }После изменения файла примените конфигурацию: nft -f /etc/nftables.conf
Шаг 3. Включаем nftables и применяем правила
Теперь включим сервис nftables, чтобы правила загружались автоматически при старте системы, затем перезапустим Docker и применим конфигурацию вручную.
systemctl enable --now nftables
systemctl restart docker
nft -f /etc/nftables.confПерезапуск Docker нужен потому, что он сам добавляет в систему свои сетевые правила. Это важно учитывать при работе с файрволом.
Проверка: После применения конфигурации полезно убедиться, что правила действительно загружены:
nft list rulesetТакже можно проверить, что сервер слушает нужные порты:
ss -tulpn | grep -E ':22|:80|:443|:8000'Если всё настроено корректно, сервер будет принимать только нужные подключения, а остальные входящие соединения будут блокироваться правилами nftables.
Важно: systemctl restart nftables полностью перечитывает конфигурацию и удаляет динамические правила, которые были добавлены Docker. Из-за этого контейнеры могут потерять сетевой доступ. Поэтому безопаснее использовать такой порядок:
- Вносите изменения в
/etc/nftables.confи применяйте только черезnft -f /etc/nftables.conf; - Если всё же выполнили, сразу после этого перезапустить Docker командой
systemctl restart dockerдля восстановления правил Docker.
Запуск Portainer
После подготовки docker-compose.yml запустим Portainer Server. Для этого перейдите в каталог с конфигурацией и выполните запуск контейнера в фоновом режиме:
cd /opt/portainer
docker compose up -dПосле выполнения команды Docker Compose скачает образ portainer/portainer-ce, создаст необходимые объекты и запустит контейнер Portainer.
Важно: после первого запуска у вас будет 5 минут на создание административного пользователя через веб-интерфейс. Если за это время учётная запись не будет создана, контейнер нужно будет перезапустить.
Проверка: после запуска убедитесь, что сервис работает корректно. Сначала проверьте, что контейнер запущен:
docker ps
В выводе должен присутствовать контейнер portainer со статусом Up. Затем откройте в браузере адрес. В нашем случае это https://portainer.firstvds.ru.
Если всё настроено правильно, откроется стартовый интерфейс Portainer с валидным TLS-сертификатом.

Если в инфраструктуре используется Edge Agent Standard, подключение к серверу выполняется по двум портам:
- https://portainer.firstvds.ru — основной интерфейс и API через 443/tcp, который проксируется на 9443;
- portainer.firstvds.ru:8000 — служебный порт для туннеля Edge Agent.
Итак, мы провели ручную установку и базовую настройку Portainer Server: развернули сервис, настроили Nginx, HTTPS и файрвол, а также проверили, что веб-интерфейс доступен.
На этом базовая установка завершена — сервер Portainer с доступом по HTTPS готов к работе. Теперь вы можете использовать его как центральную точку управления Docker-окружением.
При этом многие возможности Portainer выходят за рамки этой инструкции. С его помощью можно также подключать удалённые Docker-хосты через Edge Agent, разворачивать приложения через Stacks, настраивать пользователей и права доступа, а также интегрировать внешнюю аутентификацию через Keycloak.