Запуск Serverless Container по триггеру

Итак, у вас есть цель выполнять какую-то задачу внутри serverless контейнера по расписанию. К сожалению, вы не сможете просто взять положить в контейнер ваш код и надеяться что все заработает просто так.
Тут нужно уточнить детали реализации взаимодействия serverless контейнера и cron-триггера, который будет его запускать. Триггер запускает контейнер просто отправляя ему http-запрос в корень (path /
) и ожидая в конце выполнения ответа c HTTP кодом200
.
Если же вы в контейнере не реализуете HTTP-сервер, то триггер не может узнать о том, корректно ли завершилось выполнение контейнера. Это будет воспринято как ошибка и триггер попробует запустить контейнер снова. В итоге вы получите много запусков вашего кода, которых вы не ожидали, и большой счёт за их выполнение.
Поэтому правильно будет добавить в контейнер простой HTTP-сервер, который будет слушать на порту, переданному в переменной окружения PORT
, и по окончанию выполнения полезной работы сможет корректно ответить триггеру.
Сервер на Go
Давайте напишем простой сервер на go, и добавим его в наш контейнер.
При обработке запроса от триггера мы просто запускаем скрипт command.sh
в котором можно описать произвольные команды.
Dockerfile
Теперь надо упаковать это все в докер-контейнер.
Здесь мы используем подход многофазного построения контейнера. На первом шаге мы собираем наш сервер. Назовем этот контейнер build
.
На втором шаге просто копируем сервер в чистый образ ubuntu:22.04
. Туда же вы можете добавить все необходимое для запуска вашей задачи. А сам процесс запуска описать в command.sh
.
Таким образом вы сможете легко корректно обрабатывать вызовы триггера и не получать в логах контейнера сообщений типа:
{"errorMessage":"user container finished with error: exit status 1","errorType":"UserCodeError"}
Аналогично можно написать сервер которы будет обрабатывать сообщения от других типов триггеров, с той лишь разницей, что, вероятно, придется добавить код разбора сообщения, полученного от триггера.