Я пытаюсь развернуть бота Discord, который я написал на python, на виртуальную машину (с запущенным Portainer) на моем домашнем сервере. Однако я столкнулся с проблемой, когда Portainer правильно оценивает секрет токена бота. Я определил секрет с именем HU3BOT_DISCORD_TOKEN
и использую следующий файл компоновки:
version: "3.9"
services:
hu3bot:
image: drak3/hu3bot:latest
environment:
- DISCORD_TOKEN=/run/secrets/HU3BOT_DISCORD_TOKEN
- DISCORD_CHANNEL = "3d_printing"
- PRINTER_HOST=voron.srv
- CAM_PORT_MAIN=8081
- CAM_PORT_ALT=8080
- MOONRAKER_API_PORT=7125
- WEB_URL='https://fluidd.drak3.io'
secrets:
- HU3BOT_DISCORD_TOKEN
# the secret is a discord bot token
secrets:
HU3BOT_DISCORD_TOKEN:
external: true
Локально я могу запустить скрипт, используя файл .env
без проблем. Я могу сделать то же самое, что и локальный контейнер. Однако, когда я пытаюсь использовать секрет, который я определил, я не могу заставить его правильно оценить. Я добавил в свой код несколько операторов печати, и в зависимости от того, как я отформатирую строку DISCORD_TOKEN=/run/secrets/HU3BOT_DISCORD_TOKEN
, токен будет либо оцениваться как Null (None
типа <class 'NoneType'>
), либо как строка с содержимым /run/secrets/HU3BOT_DISCORD_TOKEN
.
Я пробовал все следующие комбинации форматирования, но все они будут либо именем секрета, либо Null:
DISCORD_TOKEN=/run/secrets/HU3BOT_DISCORD_TOKEN
DISCORD_TOKEN= /run/secrets/HU3BOT_DISCORD_TOKEN
DISCORD_TOKEN:/run/secrets/HU3BOT_DISCORD_TOKEN
DISCORD_TOKEN: /run/secrets/HU3BOT_DISCORD_TOKEN
"DISCORD_TOKEN=/run/secrets/HU3BOT_DISCORD_TOKEN"
"DISCORD_TOKEN= /run/secrets/HU3BOT_DISCORD_TOKEN"
"DISCORD_TOKEN:/run/secrets/HU3BOT_DISCORD_TOKEN"
"DISCORD_TOKEN: /run/secrets/HU3BOT_DISCORD_TOKEN"
Вдобавок ко всему, у меня также есть другой стек, который извлекает вебхук из секрета (например: WATCHTOWER_NOTIFICATION_SLACK_HOOK_URL=/run/secrets/DISCORD_WEBHOOK_WATCHTOWER
), который отлично работает.
Может ли содержание секрета иметь какое-либо отношение к этому? Честно говоря, я затрудняюсь объяснить это и буду очень признателен за любую помощь или предложения.
ОБНОВИТЬ:
Для тех, кто придет после меня, у кого будет похожая проблема, благодаря Крису Бекке я понял, что, должно быть, неправильно понял, как на самом деле работают секреты докеров. Раньше я думал, что строка /run/secrets/secret_name
может использоваться как буквальная замена самого секретного значения, и что, передавая их в переменные среды, это будет эквивалентно простому хранению необработанного секрета. Это недоразумение, скорее всего, связано с тем, что я использовал секреты только в файлах компоновки, используя изображения других людей. Я предполагаю, что у них был какой-то код, чтобы различать значение, являющееся переменной среды, и секретный путь докера. После добавления такого кода в мой бот значение оценивается, как и ожидалось. Это было полезным ответом для этого.
Установка переменной среды просто устанавливает для нее буквальное значение, которое вы предоставляете.
Правильная обработка секретов влечет за собой внедрение сценария для чтения секрета в переменную среды. Что-то вроде этого:
services:
some-service:
image: whatever
entrypoint:
- /bin/sh
- -c
- |
read -r DISCORD_TOKEN < /run/secrets/HU3BOT_DISCORD_TOKEN
exec $$0 "$$@"
command: previous command
Вам нужно найти в контейнерах предыдущие значения CMD и ENTRYPOINT и убедиться, что новые цепочки потоков связаны со старым потоком. Настройка entrypoint
автоматически удаляет все существующие CMD
, поэтому вам нужно полностью указать это, если они существовали.
Также стоит отметить, что многие образы Docker (Postgres и т. д.) поддерживают инициализацию переменных среды из файла путем обработки переменных с суффиксом _FILE.
например Образ Docker Postgres будет считывать файл, указанный в «POSTGRES_PASSWORD_FILE», в «POSTGRES_PASSWORD».
Если образ Hu3Bot был создан с учетом этого использования, то установка DISCORD_TOKEN_FILE
на секретный путь может сработать.
Спасибо за ответ. Хотя я не использовал именно это решение, ваш комментарий привел меня к тому, что я понял, что мне нужно рассматривать
/run/secrets/HU3BOT_DISCORD_TOKEN
как файл, а не сам секрет. Мое непонимание, скорее всего, связано с тем, что это мое первое изображение, которое я создал, которое нуждалось в секретах. Раньше я просто использовал чужие изображения и переходил по пути/run/secrets/name
. После добавления кода для получения значения из переменной среды или файла он ведет себя так, как ожидалось.