Você pode copiar seu crontab em uma imagem, para que o contêiner lançado a partir dessa imagem execute o trabalho.
Consulte " Executar um trabalho cron com o Docker " de Julien Boulay no seguinte Ekito/docker-cron
:
Vamos criar um novo arquivo chamado " hello-cron
" para descrever nosso trabalho.
* * * * * 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.
O Dockerfile a seguir descreve todas as etapas para criar sua imagem
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
(veja Gaafar 's comentário e Como eu faço apt-get
instalar menos ruidoso? :
apt-get -y install -qq --force-yes cron
pode trabalhar também)
Como observado por Nathan Lloyd nos comentários :
Nota rápida sobre uma pegadinha:
Se você estiver adicionando um arquivo de script e instruindo o cron a executá-lo, lembre-se de que o Cron falha silenciosamente, se você esquecer .
RUN chmod 0744 /the_script
OR, verifique se o trabalho em si redirecionar diretamente para stdout / stderr em vez de um arquivo de log, conforme descrito na hugoShaka 's resposta :
* * * * * root echo hello > /proc/1/fd/1 2>/proc/1/fd/2
Substitua a última linha do Dockerfile por
CMD ["cron", "-f"]
Veja também (about cron -f
, ou seja, cron "foreground") " docker ubuntu cron -f
não está funcionando "
Crie e execute:
sudo docker build --rm -t ekito/cron-example .
sudo docker run -t -i ekito/cron-example
Seja paciente, aguarde 2 minutos e sua linha de comando deve exibir:
Hello world
Hello world
Eric acrescenta nos comentários :
Observe que tail
talvez não seja exibido o arquivo correto se ele for criado durante a criação da imagem.
Se for esse o caso, você precisará criar ou tocar no arquivo durante o tempo de execução do contêiner para que o tail selecione o arquivo correto.
Consulte "A saída de tail -f
no final de uma janela de encaixe CMD
não está aparecendo ".
RUN apt-get update && apt-get install cron
-y
à instalação do cron para evitar a saída do docker buildcrontab -l
, não recebo o crontab instalado para root , também, minha tela permanece em branco. No entanto, quando eu checo '/etc/cron.d/', vejo que o crontab fiel está lá (e, ainda mais surpreendente), quando checo/var/log/cron.log
, vejo que o script está em execução (o conteúdo do arquivo está sendo anexadoHello World
). Eu estou puxando esta imagem na minha Dockerfile:FROM phusion/baseimage:0.10.0
. Alguma idéia sobre a discrepância de comportamento?A solução adotada pode ser perigosa em um ambiente de produção .
Quando você usa
CMD cron && tail -f /var/log/cron.log
o processo cron basicamente bifurca-se para executarcron
em segundo plano, o processo principal sai e permite executartailf
em primeiro plano. O processo cron em segundo plano pode parar ou falhar e você não notará, seu contêiner continuará sendo executado silenciosamente e sua ferramenta de orquestração não o reiniciará.Usando redirecionamentos básicos do shell, você pode fazer algo assim:
E seu CMD será:
CMD ["cron", "-f"]
fonte
cron -f
é para "cron foreground". Eu incluí sua resposta na minha acima, para mais visibilidade. +1Para quem deseja usar uma imagem simples e leve:
Onde cronjobs é o arquivo que contém seus cronjobs, neste formato:
fonte
> /proc/1/fd/1 2> /proc/1/fd/2
redirecionamento para acessar a saída dos cronjobs diretamente dos logs da janela de encaixe.-d 8
parâmetro não é o cron padrão, é o comando crond do busybox. Por exemplo, no ubuntu, você pode executar isso comobusybox crond -f -d 8
. Para versões mais antigas, você precisa usar-L /dev/stdout/
.docker run -v ${PWD}/cronjobs:/etc/crontabs/root alpine:3.6 crond -f -d 8
. @Groostav, você pode usar uma coisa semelhante no Docker Compose.CMD ["crond"
ouCMD ["cron"
?O que o @VonC sugeriu é bom, mas eu prefiro fazer toda a configuração de tarefas cron em uma linha. Isso evitaria problemas de plataforma cruzada, como o local do cronjob, e você não precisa de um arquivo cron separado.
Depois de executar o contêiner do docker, verifique se o serviço cron está funcionando:
Se você preferir ter ENTRYPOINT em vez de CMD, poderá substituir o CMD acima por
fonte
RUN apt-get update && apt-get -y install cron
ou então não será capaz de encontrar o pacotecron
RUN cat $APP_HOME/crons/* | crontab
como um encanto :)cron
a um script de ponto de entrada parece ser a melhor opção: ENTRYPOINT ["entrypoint.sh"]Há outra maneira de fazer isso: usar o Tasker , um executor de tarefas que possui suporte ao cron (um agendador).
Por quê ? Às vezes, para executar um trabalho cron, você precisa misturar sua imagem base (python, java, nodejs, ruby) com a base. Isso significa outra imagem para manter. Tasker evite isso dissociando a crond e o contêiner. Você pode se concentrar apenas na imagem que deseja executar seus comandos e configurar o Tasker para usá-la.
Aqui está um
docker-compose.yml
arquivo, que executará algumas tarefas para vocêExistem 3 tarefas lá, todas elas serão executadas a cada minuto (
every: minute
) e cada uma delas executará oscript
código, dentro da imagem definida emimage
seção.Apenas corra
docker-compose up
e veja-o funcionando. Aqui está o repositório Tasker com a documentação completa:http://github.com/opsxcq/tasker
fonte
docker exec
em contêineres especificados.A resposta de VonC é bastante completa. Além disso, gostaria de acrescentar uma coisa que me ajudou. Se você quiser apenas executar um trabalho cron sem seguir um arquivo, ficará tentado a remover o
&& tail -f /var/log/cron.log
comando cron.No entanto, isso fará com que o contêiner do Docker saia logo após a execução, porque quando o comando cron é concluído, o Docker acha que o último comando foi encerrado e, portanto, mata o contêiner. Isso pode ser evitado executando cron em primeiro plano via
cron -f
.fonte
Embora isso pretenda executar tarefas ao lado de um processo em execução em um contêiner via
exec
interface do Docker , isso pode ser do seu interesse.Eu escrevi um daemon que observa contêineres e agenda trabalhos, definidos em seus metadados, neles. Exemplo:
Também é possível uma configuração 'clássica', semelhante ao cron.
Aqui estão os documentos , o repositório de imagens .
fonte
docker exec <container_name> <some_command>
por agendamento.Criei uma imagem do Docker com base nas outras respostas, que podem ser usadas como
docker run -v "/path/to/cron:/etc/cron.d/crontab" gaafar/cron
where
/path/to/cron
: caminho absoluto para o arquivo crontab ou você pode usá-lo como base em um Dockerfile:Para referência, a imagem está aqui .
fonte
Ao implantar seu contêiner em outro host, observe que ele não iniciará nenhum processo automaticamente. Você precisa garantir que o serviço 'cron' esteja sendo executado dentro do seu contêiner. No nosso caso, estou usando o Supervisord com outros serviços para iniciar o serviço cron.
fonte
Defina o cronjob em um contêiner dedicado que executa o comando via docker exec no seu serviço.
Isso é maior coesão e o script em execução terá acesso às variáveis de ambiente que você definiu para o seu serviço.
fonte
myservice unknown
erros.Se você estiver usando o Docker para Windows, lembre-se de que você precisa alterar o formato de final de linha de CRLF para LF (ou seja, do DOS para o Unix) se pretender importar o arquivo crontab do Windows para o contêiner ubuntu. Caso contrário, seu cron-job não funcionará. Aqui está um exemplo de trabalho:
Na verdade, isso me levou horas para descobrir, pois a depuração de tarefas cron em contêineres de docker é uma tarefa tediosa. Espero que ajude outras pessoas que não conseguem obter o código para o trabalho!
fonte
Dos exemplos acima, criei esta combinação:
Imagem e edição alpina usando o Crontab no Nano (eu odeio vi)
fonte
Configurar um cron em paralelo a um trabalho único
Crie um arquivo de script, digamos run.sh, com o trabalho que deve ser executado periodicamente.
Salvar e sair.
Usar ponto de entrada em vez de CMD
Se você tiver vários trabalhos para iniciar durante a contêiner do docker, use o arquivo do ponto de entrada para executá-los todos.
O arquivo do ponto de entrada é um arquivo de script que entra em ação quando um comando de execução do docker é emitido. Portanto, todas as etapas que queremos executar podem ser colocadas nesse arquivo de script.
Por exemplo, temos 2 trabalhos a serem executados:
Executar uma tarefa : echo “O contêiner do Docker foi iniciado”
Executar trabalho periódico : run.sh
Criar entrypoint.sh
Vamos entender o crontab que foi configurado no arquivo
* * * * *
: Cron horário; o trabalho deve ser executado a cada minuto. Você pode atualizar a programação com base em seus requisitos./run.sh
: O caminho para o arquivo de script que deve ser executado periodicamente/var/log/cron.log
: O nome do arquivo para salvar a saída do trabalho cron agendado.2>&1
: Os logs de erro (se houver) também serão redirecionados para o mesmo arquivo de saída usado acima.Nota : Não esqueça de adicionar uma nova linha extra, pois ela é um cron válido.
Scheduler.txt
: a configuração completa do cron será redirecionada para um arquivo.Usando variáveis de ambiente específicas do sistema / usuário no cron
Meu trabalho cron real estava esperando a maioria dos argumentos, conforme as variáveis de ambiente passavam para o comando docker run. Mas, com o bash, não pude usar nenhuma das variáveis de ambiente que pertencem ao sistema ou ao contêiner do docker.
Em seguida, isso surgiu como uma solução alternativa para esse problema:
Por fim, você
entrypoint.sh
deve parecerPor último, mas não menos importante: criar um arquivo Docker
É isso aí. Crie e execute a imagem do Docker!
fonte
Trabalhos Cron são armazenados em / var / spool / cron / crontabs (local comum em todas as distros que eu conheço). BTW, você pode criar uma guia cron no bash usando algo assim:
Isso criará um arquivo temporário com a tarefa cron e, em seguida, programe-o usando o crontab. A última linha remove o arquivo temporário.
fonte
cron
daemon normalmente não é executado em um contêiner.crond
além do serviço que está executando no contêiner, normalmente com um gerente de serviço como o s6. Provavelmente perguntar isso como uma questão de obter uma resposta adequadaAo executar em algumas imagens reduzidas que restringem o acesso root, tive que adicionar meu usuário aos sudoers e executar como
sudo cron
Talvez isso ajude alguém
fonte
Então, meu problema era o mesmo. A correção foi alterar a seção de comando no
docker-compose.yml
.De
comando: crontab / etc / crontab && tail -f / etc / crontab
Para
comando: crontab / etc / crontab
comando: tail -f / etc / crontab
O problema foi o '&&' entre os comandos. Depois de excluir isso, tudo estava bem.
fonte
A maneira mais robusta que encontrei até agora é executar um contêiner cron independente - instale o cliente docker e monte a meia docker para que você possa conversar com o servidor docker no host.
Em seguida, basta usar env vars para cada tarefa cron e um script de ponto de entrada para gerar o / etc / crontab
Aqui está uma imagem que eu criei usando esse princípio e usando-o em produção nos últimos 3-4 anos.
https://www.vip-consult.solutions/post/better-docker-cron#content
fonte
Tente usar a gema do relógio para agendar tarefas. Siga as etapas fornecidas neste link.
http://fuzzyblog.io/blog/rails/2017/05/11/adding-cron-to-a-dockerized-rails-application-using-clockwork.html
Você pode chamar a tarefa rake dentro do arquivo lib / clock.rb como abaixo.
Crie um contêiner separado no arquivo docker-compose e execute o comando abaixo dentro do contêiner.
fonte