Инфраструктуру, которую нельзя передать сменщику без недели обучения командам Docker, дешёвой не назовёшь. Терминал остаётся главным инструментом администратора, но у графической панели есть своя честная работа: показать коллеге состояние сервера без курса молодого бойца, глянуть логи с телефона, отдать деплой человеку, который compose-файлы не читает. Portainer CE закрывает именно эту нишу: бесплатная панель ставится одним контейнером, говорит с Docker через его API и умеет всё, от контейнеров и образов до stacks с правами доступа. Ниже полный путь: установка, первый вход, пользователи и команды, стеки из редактора и из репозитория, обновление без потерь.

Зачем панели место рядом с терминалом

Панель не заменяет командную строку и не пытается: всё, что умеет Portainer, можно сделать в терминале, просто медленнее и с большим числом открытых вкладок. Её сила в другом. Дежурный без глубокого опыта Docker видит статусы контейнеров цветом, читает журналы кнопкой и перезапускает упавшее без страха сломать строку запуска. Владелец сервера получает единый экран здоровья: память, процессор, место на диске и список живых контейнеров одним взглядом.

Второй сценарий практичнее, чем кажется: передача дел. Когда доступ к серверу нужен не одному человеку, а смене или небольшой команде, панель с ролями и правами оказывается безопаснее общей SSH-учётки: у каждого свой логин, у каждого своя зона видимости, и действия людей видны в общем журнале событий.

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

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

Установка одним контейнером с томом состояния

Панель сама является контейнером, и ставится она по канонам Docker: именованный том под состояние и проброшенный порт под интерфейс. Рабочий compose-файл умещается в десяток строк.

services:
  portainer:
    image: portainer/portainer-ce:lts
    ports:
      - "9443:9443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data
    restart: always

volumes:
  portainer_data:

Три решения в файле заслуживают пояснений. Порт 9443 обслуживает защищённый интерфейс: панель сразу работает по HTTPS с самоподписанным сертификатом, и браузер встретит предупреждение, которое для первого входа просто принимается. Том portainer_data хранит пользователей, настройки и содержимое stacks, и именно он делает панель переносимой. Сокет Docker подключается с полными правами, потому что управление контейнерами и есть работа панели.

docker compose up -d
docker compose ps

Через несколько секунд после старта панель готова принимать первого администратора. Образ весит под пару сотен мегабайт, качается из публичного реестра за минуту-другую, и первый запуск проходит тихо: контейнер поднимается, инициализирует том и открывает порт. Если что-то идёт не так, журнал читается штатной командой logs к службе панели. Тег lts вместо latest выбирает проверенную линию выпусков: обновления приходят реже, зато каждая версия обкатана, и для инструмента, через который управляется весь сервер, это разумный консерватизм.

Первый вход и окно создания администратора

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

Дальше система просит создать администратора: имя, пароль дважды. Здесь прячется деталь, которая регулярно оборачивается вопросами на форумах: у первой настройки есть окно примерно в пять минут. Если администратор за это время не создан, панель завершает работу из соображений безопасности, и контейнер приходится перезапускать, чтобы окно открылось снова. Механика защищает от ситуации, когда панель висит в сети без хозяина, и суровость у неё честная.

После создания учётки панель спрашивает про окружение, и для локального сервера выбор прост: строка Local со значком Docker. Кнопка подключения завершает установку, и на экране появляется сводка: количество контейнеров, образов, томов и сетей, графики памяти и процессора хоста. С этого момента вся жизнь сервера видна без единой команды. Главная страница с графиками становится утренним экраном дежурного, а язык интерфейса при желании меняется в настройках.

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

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

Пользователи и команды с ролями в среде

Разграничение доступа строится на трёх понятиях: пользователи, команды и окружения. Пользователь входит по своему логину и паролю, команда собирает людей по проекту или зоне ответственности, окружение это подключённый Docker-хост, для одиночного сервера он одно.

Роли в бесплатной редакции делятся на две большие группы. Администратор видит всё и управляет настройками самой панели: пользователи, команды, образы, стеки, любые контейнеры. Обычный участник, в терминах панели standard user, получает только то, что ему явно выделено: конкретные окружения и стеки, а разделы глобального администрирования для него не существуют вовсе, не закрыты, а именно отсутствуют.

Практика раскладывается в три шага. Заводится пользователь без галочки администратора. Создаётся команда, например дежурные или разработчики проекта, и в неё добавляются люди. Команде назначается доступ к окружению с ролевой рамкой: от полного контроля, где можно создавать и удалять, до эксплуатации, где перезапускать можно, а разрушать нельзя, и просмотра, где всё читаемо и ничего не нажимается.

Внешняя авторизация через корпоративный каталог тоже поддерживается, но для команды из трёх человек собственные пароли панели честнее и проще. Общее правило то же, что в любой системе доступа: администратором делает себя и одного заместителя, остальным выдаётся минимально достаточная роль, и лишние учётки не заводятся "на всякий случай", потому что всякий случай в списках доступа не кончается ничем хорошим.

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

Stacks из редактора и из репозитория кода

Раздел stacks главный для повседневной работы. Стек это compose-файл, который живёт прямо в панели: создаётся в веб-редакторе, правится мышью и разворачивается кнопкой Deploy the stack. Для проекта из приложения и базы это значит, что весь набор описывается в одном окне без файлов на диске.

У стека есть собственная страница со статусами сервисов, журналом событий и отдельной вкладкой переменных окружения: пароли и режимы редактируются табличкой, без риска задеть основной текст-compose. Имя стека становится префиксом контейнеров и томов, и в общих списках всё читается группами.

Второй способ собрать стек: из репозитория кода. Панель подключается к хранилищу, читает compose-файл из выбранной ветки и разворачивает его, а обновление сводится к кнопке повторного развёртывания с подтягиванием свежих изменений. Для команды это меняет дисциплину: правки конфигурации проходят через ревью в репозитории, а на сервер попадает только то, что кто-то второй уже увидел глазами. Автоматическое подтягивание по расписанию остаётся уделом платной редакции, в бесплатной обновление делается осознанным нажатием, и для небольшой команды это скорее плюс: контроль дешевле автоматики.

Честная оговорка про стеки в панели: конфигурация хранится в томе portainer_data, и её судьба равна судьбе тома. Пока том цел и копируется по расписанию, целы и стеки, поэтому бэкап этого тома входит в регламент сервера без всяких исключений. Лимиты памяти и процессора задаются в стеке той же секцией deploy, что и в файле на диске: ресурсная рамка экономит сервер надёжнее любых уговоров, а вкладка переменных держит пароли вне основного текста.

Ограничение доступа к окружениям и шаблоны

Настройка доступа, описанная выше, раздаётся именно через окружения, и в маленьких командах этого достаточно. Дальше схема растёт вместе с парком: на каждом новом хосте поднимается лёгкий агент, хост подключается к панели как отдельное окружение, и доступ к нему выдаётся той же команде с той же ролью. Один экран показывает несколько серверов, и переключение между ними щелчком по строке слева.

Шаблоны закрывают потребность в быстром старте: библиотека готовых наборов, от баз до систем управления контентом, разворачивается в пару кликов с параметрами на одной странице. Вспомогательный сервис, который нужен был "ещё вчера", поднимается быстрее, чем пишется его compose-файл, и в этом смысле шаблоны экономят не время, а решения: параметры уже подобраны, остаётся проверить их под свои объёмы.

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

Событийный журнал в панели полезен именно в раздаче доступа: кто перезапустил контейнер, кто пересобрал стек и когда, всё пишется само. Для разборов "кто трогал в пятницу" это дешевле любых расспросов, а для команды приучает к мысли, что действия в интерфейсе не анонимны.

Обновление с сохранением тома и безопасность панели

Обновление панели укладывается в короткий список шагов:

  1. Остановить стек панели командой compose down в её каталоге;
  2. Подтянуть свежий образ командой compose pull;
  3. Поднять стек заново командой compose up с ключом detached;
  4. Войти и убедиться, что пользователи, стеки и настройки на месте.

Пользователи, команды, стеки и подключённые окружения живут в томе portainer_data, и обновление их не трогает: новый контейнер поднимается со старым томом и узнаёт своих. Перед обновлением не лишней будет копия тома, делается она одноразовым контейнером с tar по знакомой схеме.

docker run --rm -v portainer_portainer_data:/data -v /opt/backup:/backup alpine tar czf /backup/portainer.tgz -C /data .

Имя тома в команде подставляется из вывода docker volume ls, префикс добавляет compose-проект панели. Восстановление из такой копии проверяется раз в квартал.

Тема безопасности закрывается четырьмя правилами. Сокет Docker в панели равноценен правам root на хосте, поэтому пароль администратора делают длинным, а список админов коротким. Порт 9443 не открывают на весь мир: либо правила фаервола по адресам, либо панель за reverse proxy с доменом и настоящим сертификатом. Учётку с правами полного контроля не выдают никому "временно". И смена пароля администратора раз в сезон стоит в том же регламенте, что и обновление самой панели.

По сути, Portainer CE снимает с Docker барьер входа для всей команды, не отбирая у админа терминал: панель ускоряет обычное, ревью в репозитории дисциплинирует конфигурации, а роли удерживают людей в их зонах. Один контейнер, один том и вечер настройки, и сервер становится понятен не только тому, кто его собирал. Следующий логичный шаг: reverse proxy перед панелью и настоящий сертификат, после которых вход идёт по привычному домену без порта и предупреждений.