Portainer — удобная веб-панель для управления Docker. Через неё можно просматривать контейнеры, создавать Compose-стеки, смотреть логи, управлять сетями, образами и томами без постоянной работы через терминал.
В этой инструкции установим Portainer Community Edition на Ubuntu с помощью Docker Compose.
Будем использовать понятную структуру:
/opt/portainer/
├── compose.yaml
└── data/
Все настройки Portainer будут находиться в каталоге data, поэтому их будет удобно включить в резервную копию.
Для установки потребуется уже работающий Docker Engine с Docker Compose. Portainer рекомендует использовать актуальную поддерживаемую версию Docker и отдельно предупреждает, что установка Docker через Snap в Ubuntu может приводить к проблемам совместимости.
Проверяем Docker
Перед началом убедимся, что Docker установлен:
docker --version
Проверяем Docker Compose:
docker compose version
И состояние Docker:
systemctl status docker
В нормальном состоянии должно быть:
active (running)
Если Docker ещё не установлен, сначала воспользуйтесь нашей инструкцией по установке Docker на Ubuntu.
Создаём каталог Portainer
Создадим отдельный каталог:
sudo mkdir -p /opt/portainer/data
Переходим в него:
cd /opt/portainer
Проверяем:
pwd
Должно быть:
/opt/portainer
Создаём Docker Compose файл
Открываем новый файл:
sudo nano /opt/portainer/compose.yaml
Добавляем:
services:
portainer:
image: portainer/portainer-ce:lts
container_name: portainer
restart: unless-stopped
ports:
- "9443:9443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./data:/data
Сохраняем файл:
Ctrl + O
Enter
Ctrl + X
Для образа мы используем:
portainer/portainer-ce:lts
Это официальный LTS-образ Portainer Community Edition. В официальной документации Portainer для Compose также используется тег portainer/portainer-ce:lts.
Почему мы не открываем порт 8000
В официальном примере Portainer можно встретить два порта:
ports:
- "9443:9443"
- "8000:8000"
Порт 9443 используется для веб-интерфейса Portainer.
Порт 8000 предназначен прежде всего для работы с Edge Agents и для обычного локального Docker-сервера не требуется. Portainer прямо указывает, что этот порт является необязательным.
Поэтому в нашей базовой установке мы его не публикуем.
Проверяем Compose-файл
Перед первым запуском полезно проверить конфигурацию:
docker compose config
Если ошибок нет, Docker покажет итоговую конфигурацию.
Запускаем Portainer
Находясь в:
/opt/portainer
выполняем:
docker compose up -d
Docker скачает образ Portainer и запустит контейнер.
Проверяем:
docker compose ps
Также можно использовать:
docker ps
В списке должен появиться контейнер:
portainer
со статусом примерно:
Up
Смотрим журнал запуска
Если хотим убедиться, что ошибок нет:
docker logs portainer
Последние 50 строк:
docker logs --tail=50 portainer
Следить за журналом в реальном времени:
docker logs -f portainer
Выход:
Ctrl + C
Контейнер при этом продолжит работать.
Открываем Portainer
Если Portainer установлен на домашнем сервере, определяем его IP:
hostname -I
Например:
192.168.1.100
Открываем в браузере:
https://192.168.1.100:9443
Если браузер открыт непосредственно на сервере:
https://localhost:9443
Portainer по умолчанию использует HTTPS на порту 9443 и при первой установке генерирует собственный self-signed SSL-сертификат.
Поэтому браузер может показать предупреждение о недоверенном сертификате.
Это ожидаемо.
Позже Portainer можно разместить за reverse proxy, Cloudflare Tunnel или другим защищённым способом доступа.
Первоначальная настройка
При первом открытии появится страница первоначальной настройки Portainer.
Необходимо создать администратора.
Указываем имя пользователя, например:
admin
и обязательно задаём длинный уникальный пароль.
После входа Portainer обнаружит локальный Docker Engine, поскольку в контейнер подключён:
/var/run/docker.sock
Именно через Docker Socket Portainer получает возможность управлять локальными контейнерами.
Что означает Docker Socket
В Compose-файле есть строка:
- /var/run/docker.sock:/var/run/docker.sock
Она предоставляет Portainer доступ к Docker Engine хоста.
Благодаря этому Portainer может:
запускать контейнеры
останавливать контейнеры
удалять контейнеры
создавать сети
создавать volumes
загружать images
разворачивать Stacks
Но это одновременно означает, что Portainer получает очень высокий уровень доступа к серверу.
Поэтому административный интерфейс Portainer не следует оставлять открытым в интернет без дополнительной защиты.
Где хранятся данные Portainer
В нашем Compose указано:
- ./data:/data
Поскольку Compose находится в:
/opt/portainer
данные сохраняются здесь:
/opt/portainer/data
Получается:
/opt/portainer/
│
├── compose.yaml
│
└── data/
└── данные Portainer
Контейнер можно удалить и создать заново, а конфигурация сохранится в каталоге data.
Это удобно и для резервного копирования.
Проверяем созданные файлы
После первого запуска:
sudo ls -lah /opt/portainer/data
Каталог уже не должен быть пустым.
Автоматический запуск после перезагрузки
В Compose мы указали:
restart: unless-stopped
Это означает, что после перезагрузки сервера Portainer будет автоматически запущен Docker.
Проверить политику можно:
docker inspect portainer \
--format '{{.HostConfig.RestartPolicy.Name}}'
Должно быть:
unless-stopped
Официальный пример Portainer использует restart: always; для AppsHome мы используем unless-stopped, потому что если администратор специально остановил контейнер, Docker не будет запускать его снова автоматически до следующего ручного запуска.
Как остановить Portainer
Переходим:
cd /opt/portainer
Останавливаем:
docker compose stop
Запускаем снова:
docker compose start
Перезапускаем:
docker compose restart
Как полностью убрать контейнер
cd /opt/portainer
docker compose down
Это удалит контейнер и созданную Compose-сеть, но каталог:
/opt/portainer/data
останется.
Поэтому после:
docker compose up -d
Portainer снова получит прежние настройки.
Обновление Portainer
Так как используется LTS-образ:
portainer/portainer-ce:lts
обновление выполняется очень просто.
Переходим:
cd /opt/portainer
Скачиваем актуальный LTS-образ:
docker compose pull
Пересоздаём контейнер:
docker compose up -d
Проверяем:
docker compose ps
Старый образ можно оставить на некоторое время для подстраховки.
Посмотреть образы:
docker images
Неиспользуемые образы позже можно удалить:
docker image prune
Перед обновлением желательно сделать резервную копию
Самая важная директория:
/opt/portainer/data
Простой backup можно сделать так:
cd /opt
sudo tar -czf \
portainer-backup-$(date +%F).tar.gz \
portainer/
Получим, например:
portainer-backup-2026-08-07.tar.gz
При серьёзных обновлениях резервная копия особенно полезна.
Более безопасный вариант для VPS
Если сервер доступен напрямую из интернета, мы не рекомендуем оставлять:
ports:
- "9443:9443"
потому что в таком случае Docker публикует Portainer на сетевых интерфейсах сервера.
Если Portainer будет открываться только через локальный reverse proxy или Tunnel, можно привязать его к localhost:
ports:
- "127.0.0.1:9443:9443"
Тогда:
Internet
X
│
127.0.0.1:9443
│
Portainer
и непосредственно через публичный IP порт 9443 доступен не будет.
Например, доступ можно организовать через:
Cloudflare Tunnel
Tailscale
VPN
reverse proxy
Для административной панели такой вариант значительно предпочтительнее.
Compose для защищённого варианта
Если сервер — VPS и Portainer будет находиться за Tunnel или reverse proxy, наш Compose будет выглядеть так:
services:
portainer:
image: portainer/portainer-ce:lts
container_name: portainer
restart: unless-stopped
ports:
- "127.0.0.1:9443:9443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./data:/data
После изменения:
cd /opt/portainer
docker compose up -d
Проверить публикацию порта:
docker ps
Должно быть примерно:
127.0.0.1:9443->9443/tcp
а не:
0.0.0.0:9443->9443/tcp
Если Portainer используется вместе с Cloudflare Tunnel в Docker
Есть ещё более аккуратный вариант: вообще не публиковать порт Portainer на хосте, а подключить контейнер Portainer и cloudflared к общей Docker-сети.
Получается:
Internet
│
Cloudflare Access
│
Cloudflare Tunnel
│
cloudflared
│
Docker network
│
portainer:9443
В этом случае секция:
ports:
Portainer вообще не нужна.
Это хороший вариант для VPS или домашнего сервера, если удалённый доступ уже построен через Cloudflare Tunnel.
Такую конфигурацию лучше разобрать отдельно, потому что она требует общей Docker-сети между Portainer и cloudflared.
Проверяем работу Docker через Portainer
После входа откройте локальное Docker-окружение.
В разделе:
Containers
должен быть виден как минимум сам:
portainer
Если на сервере уже работают другие контейнеры, они также появятся в списке.
Можно открыть контейнер и посмотреть:
Status
Image
IP
Ports
Volumes
Networks
Logs
Console
Stats
Если все контейнеры сервера отображаются, Portainer настроен правильно.
Что такое Stacks
Одним из самых полезных разделов Portainer является:
Stacks
Stack позволяет вставить обычный Docker Compose-файл непосредственно в веб-интерфейс.
Например:
services:
nginx:
image: nginx:alpine
restart: unless-stopped
После:
Deploy the stack
Portainer создаст контейнер.
Это удобно, но на AppsHome мы всё равно рекомендуем понимать сам Docker Compose и по возможности сохранять копии Compose-конфигураций отдельно.
Portainer должен помогать управлять Docker, а не становиться единственным местом, где хранится информация о вашей инфраструктуре.
Рекомендуемая структура AppsHome
Для небольшого Docker-сервера мы рекомендуем примерно такую структуру:
/opt/
├── portainer/
│ ├── compose.yaml
│ └── data/
│
├── uptime-kuma/
│ ├── compose.yaml
│ └── data/
│
├── vaultwarden/
│ ├── compose.yaml
│ └── data/
│
└── paperless/
├── compose.yaml
└── data/
Таким образом каждый сервис имеет собственный каталог, а при резервном копировании сразу понятно, где находятся его данные.
Итог
После выполнения инструкции у нас работает:
Ubuntu
│
Docker Engine
│
Docker Compose
│
Portainer CE
│
https://SERVER-IP:9443
Portainer запускается автоматически вместе с Docker, а постоянные данные находятся в:
/opt/portainer/data
Для домашней сети этого уже достаточно.
Для сервера, доступного из интернета, следующим шагом стоит закрыть прямой доступ к 9443 и использовать Cloudflare Access, Tailscale, VPN или другой защищённый способ подключения.
