Вы можете скопировать свой crontab в изображение, чтобы контейнер, запущенный из указанного образа, запустил задание.
См. « Запусти cron с Docker » от Жюльена Булая в его Ekito/docker-cron
:
Давайте создадим новый файл с именем " hello-cron
", чтобы описать нашу работу.
* * * * * echo "Hello world" >> /var/log/cron.log 2>&1
# An empty line is required at the end of this file for a valid cron file.
Следующий Dockerfile описывает все шаги для создания вашего образа
FROM ubuntu:latest
MAINTAINER docker@ekito.fr
RUN apt-get update && apt-get -y install cron
# Copy hello-cron file to the cron.d directory
COPY hello-cron /etc/cron.d/hello-cron
# Give execution rights on the cron job
RUN chmod 0644 /etc/cron.d/hello-cron
# Apply cron job
RUN crontab /etc/cron.d/hello-cron
# Create the log file to be able to run tail
RUN touch /var/log/cron.log
# Run the command on container startup
CMD cron && tail -f /var/log/cron.log
(см Gaafar «сек комментарий и Как сделать apt-get
установку менее шумным? :
apt-get -y install -qq --force-yes cron
может работать тоже)
Как отметил Натан Ллойд в комментариях :
Краткое замечание по поводу ошибки:
если вы добавляете файл сценария и указываете cron запустить его, запомните, что Cron молчит, если вы забудете .
RUN chmod 0744 /the_script
ИЛИ, убедитесь , что ваша работа сама переадресовать непосредственно на стандартный вывод / STDERR вместо лог - файл, как описано в hugoShaka «s ответ :
* * * * * root echo hello > /proc/1/fd/1 2>/proc/1/fd/2
Заменить последнюю строку Dockerfile на
CMD ["cron", "-f"]
Смотрите также (о том cron -f
, что означает cron "передний план") " Docker Ubuntu cron -f
не работает "
Постройте и запустите его:
sudo docker build --rm -t ekito/cron-example .
sudo docker run -t -i ekito/cron-example
Будьте терпеливы, подождите 2 минуты, и ваша командная строка должна отображать:
Hello world
Hello world
Эрик добавляет в комментариях :
Обратите внимание, что tail
может не отображаться правильный файл, если он создан во время сборки образа.
Если это так, вам нужно создать файл или коснуться его во время выполнения контейнера, чтобы хвост выбрал правильный файл.
См. « Вывод tail -f
в конце докера CMD
не отображается ».
RUN apt-get update && apt-get install cron
-y
установку cron, чтобы избежать выхода из сборки Dockercrontab -l
я получаю No crontab, установленный для root , также мой экран остается пустым. Однако, когда я проверяю '/etc/cron.d/', я вижу, что поле crontab есть (и что еще более удивительно), когда я проверяю/var/log/cron.log
, я вижу, что скрипт работает (к содержимому файла добавляетсяHello World
). Я потянув этот образ в моем Dockerfile:FROM phusion/baseimage:0.10.0
. Есть идеи по поводу несоответствия в поведении?Принятое решение может быть опасным в производственной среде .
Когда вы используете
CMD cron && tail -f /var/log/cron.log
процесс cron в основном форк для выполненияcron
в фоновом режиме, основной процесс завершается и позволяет вам выполнятьtailf
на переднем плане. Фоновый процесс cron может остановиться или потерпеть неудачу, вы не заметите, ваш контейнер по-прежнему будет работать без вывода сообщений, а инструмент оркестровки не перезапустит его.Используя базовые перенаправления оболочки, вы можете сделать что-то вроде этого:
И ваш CMD будет:
CMD ["cron", "-f"]
источник
cron -f
для "cron foreground". Я включил ваш ответ выше, для большей наглядности. +1Для тех, кто хочет использовать простое и легкое изображение:
Где cronjobs - это файл, содержащий ваши cronjobs, в этой форме:
источник
> /proc/1/fd/1 2> /proc/1/fd/2
перенаправление для доступа к выходу cronjobs непосредственно из журналов докера.-d 8
параметр, не является стандартным cron, это команда crond из busybox. Например, из Ubuntu, вы можете запустить это какbusybox crond -f -d 8
. Для более старых версий вы должны использовать-L /dev/stdout/
.docker run -v ${PWD}/cronjobs:/etc/crontabs/root alpine:3.6 crond -f -d 8
. @Groostav вы можете использовать аналогичные вещи в Docker Compose.CMD ["crond"
илиCMD ["cron"
?То, что предложил @VonC, приятно, но я предпочитаю выполнять все настройки cron в одной строке. Это позволит избежать кросс-платформенных проблем, таких как расположение cronjob, и вам не нужен отдельный файл cron.
После запуска вашего docker-контейнера вы можете убедиться, что служба cron работает:
Если вы предпочитаете использовать ENTRYPOINT вместо CMD, вы можете заменить CMD выше на
источник
RUN apt-get update && apt-get -y install cron
иначе он не сможет найти посылкуcron
RUN cat $APP_HOME/crons/* | crontab
как талисман :)cron
в сценарий точки входа кажется лучшим вариантом: ENTRYPOINT ["entrypoint.sh"]Есть еще один способ сделать это - использовать Tasker , средство запуска задач, которое поддерживает cron (планировщик).
Зачем ? Иногда для запуска задания cron вам нужно смешать ваш базовый образ (python, java, nodejs, ruby) с crond. Это означает, что другой образ для поддержания. Tasker избежать этого, отделив Crond и вы контейнер. Вы можете просто сфокусироваться на изображении, которое хотите выполнить, и настроить Tasker для его использования.
Здесь
docker-compose.yml
файл, который будет запускать некоторые задачи для васТам есть 3 задачи, все они будут запускаться каждую минуту (
every: minute
), и каждая из них будет выполнятьscript
код внутри образа, определенного вimage
разделе.Просто беги
docker-compose up
, и увидишь, как это работает. Вот репозиторий Tasker с полной документацией:http://github.com/opsxcq/tasker
источник
docker exec
на указанных контейнерах.Ответ VonC довольно тщательный. Кроме того, я хотел бы добавить одну вещь, которая помогла мне. Если вы просто хотите запустить задание cron без привязки файла, у вас возникнет соблазн просто удалить команду
&& tail -f /var/log/cron.log
из команды cron.Однако это приведет к выходу контейнера Docker вскоре после запуска, потому что, когда команда cron завершается, Docker считает, что последняя команда завершилась, и, следовательно, убивает контейнер. Этого можно избежать, запустив cron на переднем плане через
cron -f
.источник
Хотя это направлено на запуск заданий рядом с запущенным процессом в контейнере через
exec
интерфейс Docker , это может вас заинтересовать.Я написал демон, который наблюдает за контейнерами и планирует задания, определенные в их метаданных. Пример:
«Классическая», cron-подобная конфигурация также возможна.
Вот документы , вот хранилище изображений .
источник
docker exec <container_name> <some_command>
по расписанию.Я создал образ Docker на основе других ответов, которые можно использовать как
docker run -v "/path/to/cron:/etc/cron.d/crontab" gaafar/cron
где
/path/to/cron
: абсолютный путь к файлу crontab или вы можете использовать его в качестве базы в Dockerfile:Для справки, изображение здесь .
источник
Когда вы развертываете свой контейнер на другом хосте, просто обратите внимание, что он не запустит какие-либо процессы автоматически. Вы должны убедиться, что служба 'cron' работает внутри вашего контейнера. В нашем случае я использую Supervisord с другими сервисами для запуска сервиса cron.
источник
Определите cronjob в выделенном контейнере, который запускает команду через docker exec для вашего сервиса.
Это более высокая степень согласованности, и запущенный скрипт будет иметь доступ к переменным среды, которые вы определили для вашей службы.
источник
myservice unknown
ошибок.Если вы используете docker для окон, помните, что вам нужно изменить формат конца строки с CRLF на LF (то есть с dos на unix), если вы собираетесь импортировать файл crontab из windows в контейнер ubuntu. Если нет, ваша работа не будет работать. Вот рабочий пример:
На самом деле это заняло у меня несколько часов, поскольку отладка заданий cron в Docker-контейнерах - утомительная задача. Надеюсь, это поможет всем, кто не может заставить свой код работать!
источник
Из приведенных выше примеров я создал эту комбинацию:
Alpine Image & Edit с использованием Crontab в Nano (я ненавижу vi)
источник
Настроить cron параллельно с разовой работой
Создайте файл сценария, скажем, run.sh, с заданием, которое должно периодически выполняться.
Сохранить и выйти.
Используйте Entrypoint вместо CMD
Если у вас есть несколько заданий, которые нужно запустить во время контейнера докера, используйте файл точки входа, чтобы запустить их все.
Файл точки входа - это файл сценария, который вступает в действие при выполнении команды запуска Docker. Итак, все шаги, которые мы хотим выполнить, могут быть помещены в этот файл скрипта.
Например, у нас есть 2 задания для запуска:
Запустить один раз задание : echo «Docker-контейнер запущен»
Запустить периодическое задание : run.sh
Создать entrypoint.sh
Давайте разберемся crontab, который был установлен в файле
* * * * *
: Расписание Cron; работа должна выполняться каждую минуту. Вы можете обновить расписание на основе ваших требований./run.sh
: Путь к файлу скрипта, который должен периодически запускаться/var/log/cron.log
: Имя файла для сохранения вывода запланированного задания cron.2>&1
: Журналы ошибок (если таковые имеются) также будут перенаправлены в тот же выходной файл, который использовался выше.Примечание : не забудьте добавить дополнительную новую строку, так как это делает ее действительным cron.
Scheduler.txt
: полная установка cron будет перенаправлена в файл.Использование системных / пользовательских переменных среды в cron
Моя настоящая работа cron ожидала большинство аргументов, поскольку переменные окружения передавались команде запуска docker. Но с bash я не смог использовать ни одну из переменных среды, которая принадлежит системе или контейнеру Docker.
Затем это подошло к решению этой проблемы:
Наконец, вы
entrypoint.sh
должны выглядеть такПоследнее, но не менее важное: создайте Dockerfile
Вот и все. Создайте и запустите образ Docker!
источник
Задания Cron хранятся в / var / spool / cron / crontabs (общее место во всех известных мне дистрибутивах). Кстати, вы можете создать вкладку cron в bash, используя что-то вроде этого:
Это создаст временный файл с задачей cron, а затем запрограммирует его с помощью crontab. Последняя строка удаляет временный файл.
источник
cron
Демон обычно не работает в контейнере.crond
в дополнение к службе, которую вы используете в контейнере, обычно с менеджером службы, таким как s6. Вероятно, задайте это как вопрос, чтобы получить правильный ответПри работе с некоторыми обрезанными изображениями, которые ограничивают доступ root, мне пришлось добавить своего пользователя в sudoers и запустить как
sudo cron
Может быть, это помогает кому-то
источник
Итак, моя проблема была той же. Исправление состояло в том, чтобы изменить командный раздел в
docker-compose.yml
.Из
команда: crontab / etc / crontab && tail -f / etc / crontab
к
команда: crontab / etc / crontab
команда: tail -f / etc / crontab
Проблема была «&&» между командами. После удаления все было нормально.
источник
Самый надежный способ, который я нашел до сих пор, это запустить независимый контейнер cron - установить клиент Docker и связать, смонтировать докер Sock, чтобы вы могли общаться с сервером Docker на хосте.
Затем просто используйте env vars для каждого задания cron и скрипт точки входа для генерации / etc / crontab
Вот изображение, которое я создал, используя этот принцип и используя его в производстве в течение последних 3-4 лет.
https://www.vip-consult.solutions/post/better-docker-cron#content
источник
Попробуйте использовать часовой механизм для планирования задач. Следуйте инструкциям, приведенным в этой ссылке.
http://fuzzyblog.io/blog/rails/2017/05/11/adding-cron-to-a-dockerized-rails-application-using-clockwork.html
Вы можете вызвать задачу rake внутри файла lib / clock.rb, как показано ниже.
Создайте отдельный контейнер в файле docker-compose и выполните следующую команду внутри контейнера.
источник