Docs/ Operações/ Tarefas cron

Tarefas cron

Execute um comando ou uma requisição HTTP conforme um agendamento. Leia “Onde o comando é executado” antes da sua primeira tarefa: uma tarefa agendada não é executada dentro do contêiner em execução do seu aplicativo, mas em um contêiner descartável que recebe as mesmas variáveis.

Criando um Cron Job

As tarefas agendadas são gerenciadas na página Tarefas agendadas do painel, ou com sh0 cron. Uma tarefa normalmente está vinculada a uma aplicação.

  1. Abra Tarefas agendadas na barra lateral e clique em Criar tarefa.
  2. Nome -- um rótulo, por exemplo nightly-report.
  3. Aplicação -- a aplicação à qual a tarefa pertence. Sem aplicação, apenas comandos HTTP são aceitos (veja abaixo).
  4. Agendamento -- uma expressão cron de 5 campos, avaliada em UTC.
  5. Comando -- uma requisição HTTP (curl, wget ou apenas uma URL), ou um programa a executar num contêiner.
  6. Opcional: uma Imagem do contêiner (vazia = a imagem da aplicação) e um Tempo limite (segundos), 300 por padrão. Depois, crie a tarefa.

O mesmo pela CLI, num servidor onde estes comandos foram executados:

Terminal
$ sh0 cron create --app my-api --name nightly-report \
    --schedule "0 3 * * *" \
    --command "curl -s -X POST https://api.example.com/internal/report"
Cron job 'nightly-report' created (id: 72173a56-1962-47dc-88e5-2a276ef3bfcc)

$ sh0 cron trigger 72173a56-1962-47dc-88e5-2a276ef3bfcc
Cron job 'nightly-report' triggered.

$ sh0 cron runs 72173a56-1962-47dc-88e5-2a276ef3bfcc
RUN ID                                STATUS      EXIT    DURATION    STARTED
----------------------------------------------------------------------------------------------------
9e329bc7-01c5-41ec-9eb5-5ab745fde533  success     0       295ms       2026-10-02 02:33:23

Onde o comando é executado

O sh0 escolhe o modo de execução a partir do comando e das configurações da tarefa, nesta ordem:

  • Requisição HTTP -- um comando que começa com curl ou wget, ou uma URL sozinha, não é executado por um shell: o sh0 envia a requisição ele mesmo, a partir do servidor, com limite de 30 segundos. -X, -H e -d são respeitados. Um status de resposta de 400 ou mais marca a execução como falha. Para uma tarefa vinculada a um aplicativo, um nome interno do seu projeto (my-api.internal, ou my-api sozinho) é resolvido para esse serviço.
  • Imagem do aplicativo -- qualquer outro comando é executado em um contêiner novo e descartável iniciado a partir da imagem atual do aplicativo, com um usuário não root, na rede do sh0 e na rede do seu projeto. Não é o seu contêiner em execução: os arquivos gravados pelo aplicativo em tempo de execução não estão lá, e o contêiner é removido após a execução.
  • Imagem explícita -- se Imagem do contêiner estiver preenchida, o contêiner descartável parte dessa imagem.
  • Sem aplicação nem imagem -- um comando que não seja HTTP é recusado no momento da execução. O sh0 nunca executa um comando agendado no host.
Note
Desde a 1.10.3: O contêiner recebe as variáveis do seu aplicativo. Uma tarefa vinculada a um aplicativo recebe as variáveis de execução dele e as do seu projeto, prevalecendo o valor do aplicativo, exatamente como os contêineres do próprio aplicativo. Variáveis de build não são repassadas. A saída de uma tarefa fica guardada no histórico: um comando que imprime um segredo o deixa lá, legível por qualquer pessoa com acesso de desenvolvedor ao aplicativo.

Medido em um aplicativo Node.js com GREETING definido no aplicativo e REGION no projeto: a tarefa env mostra as duas, ao lado das variáveis embutidas na imagem.

env -- app image (Node.js 22)
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=0.0.0.0
REGION=eu431
GREETING=hello431
NODE_VERSION=22.23.3
YARN_VERSION=1.22.22
PORT=3000
HOME=/home/node

GREETING e REGION estão presentes. A linha HOME=/home/node mostra o usuário não root.

Regras do comando

Um comando é um único programa com os seus argumentos. O sh0 verifica-o na criação da tarefa:

  • Sem shell. Os caracteres ; | & > < e a crase, $( e as quebras de linha são recusados. Não há pipes, encadeamentos && nem expansão de variáveis.
  • As aspas só contam nas requisições HTTP. Num contêiner, o comando é dividido nos espaços: sh -c "echo hi" não faz o que um shell faria. Nas requisições HTTP as aspas são respeitadas, por isso -H "Authorization: Bearer …" funciona.
  • Os redirecionamentos são removidos em vez de recusados: > /dev/null, 2>/dev/null, &> /dev/null e 2>&1 são retirados antes da verificação, de modo que uma linha copiada de um crontab é aceita.
  • No máximo 4096 caracteres.
Terminal
$ sh0 cron create --app my-api --name cleanup --schedule "0 3 * * *" --command "env | grep X"
Error: Invalid command: Command contains forbidden character '|'. Use simple commands without shell operators. (VALIDATION_ERROR)

Tarefas que precisam do banco de dados ou de segredos

Uma tarefa vinculada a um aplicativo vê as variáveis dele e resolve os nomes internos do seu projeto, então um comando como python manage.py cleanup lê a mesma DATABASE_URL e alcança o mesmo db.internal. Quando o trabalho pertence ao aplicativo em execução, restam outras duas opções:

  • Um endpoint HTTP. Exponha a tarefa como uma rota do seu aplicativo, protegida por um token, e deixe a tarefa agendada chamá-la pelo nome interno. O trabalho é executado dentro do aplicativo em execução, com a conexão ao banco e os segredos dele.
  • Ou agende dentro da aplicação, com o agendador do seu framework (por exemplo Celery beat, node-cron ou o agendador do Laravel), quando a tarefa não deve ser acessível por HTTP de forma alguma.
Command
curl -s -X POST -H "Authorization: Bearer <token>" http://my-api.internal:3000/internal/cleanup
Note
O sh0 envia a requisição a partir do servidor e resolve my-api.internal (ou my-api) apenas entre os serviços em execução do projeto da tarefa. Um nome que não corresponde a nenhum serviço em execução falha com uma mensagem explícita; um aplicativo fora de qualquer projeto, ou em um nó remoto, deve ser chamado pela URL pública. O token fica em claro no comando da tarefa, visível para quem puder ler a tarefa: não lhe dê nenhum outro uso.

Sintaxe de Expressão Cron

O sh0 usa expressões cron padrão de 5 campos. Cada campo representa uma unidade de tempo:

Cron expression format
┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12)
│ │ │ │ ┌───────────── day of week (0-6, Sunday = 0)
│ │ │ │ │
* * * * *
SímboloSignificadoExemplo
*Todo valor* * * * * = a cada minuto
,Lista de valores0 8,12,18 * * * = 8h, 12h, 18h
-Intervalo0 9-17 * * * = a cada hora das 9h às 17h
/Passo*/15 * * * * = a cada 15 minutos

Padrões Comuns

Frequently used cron schedules
# Every minute
* * * * *

# Every 5 minutes
*/5 * * * *

# Every hour at minute 0
0 * * * *

# Every day at midnight
0 0 * * *

# Every day at 3:30 AM
30 3 * * *

# Every Monday at 9:00 AM
0 9 * * 1

# First day of every month at midnight
0 0 1 * *

# Every weekday (Mon-Fri) at 6:00 AM
0 6 * * 1-5
Note
Os agendamentos são avaliados em UTC, qualquer que seja o fuso horário do servidor. 0 3 * * * roda às 03:00 UTC. O agendador procura tarefas pendentes a cada 60 segundos, então uma execução pode começar até um minuto depois do horário.

Histórico de Execução e Logs

Cada execução é registrada com o status (success, failed ou timeout), código de saída, duração, horários de início e fim, e saída. No painel, abra Histórico de execuções numa tarefa e exiba a saída de uma execução. Pela CLI: sh0 cron runs <id>.

Note
O sh0 guarda as últimas 100 execuções de cada tarefa e apaga as mais antigas. A saída padrão e a saída de erro são guardadas, cada uma, até 64 KB.

Habilitando e Desabilitando Jobs

  • Desativar interrompe as execuções agendadas sem apagar a tarefa nem o histórico; Ativar retoma-as.
  • Executar agora (ou sh0 cron trigger <id>) inicia uma execução imediatamente, qualquer que seja o agendamento.
  • Excluir uma tarefa (sh0 cron delete <id>) também exclui o histórico.

Tempos limite, sobreposição e limites

  • Tempo limite -- 300 segundos por padrão (--timeout na CLI). Uma execução que o ultrapassa é registrada com o status timeout e a mensagem “Job timed out after Ns”.
  • Sobreposição -- enquanto uma execução de uma tarefa está em andamento, o agendador não inicia outra. A ocorrência ignorada não fica registrada no histórico.
  • 50 tarefas por aplicação.
  • Sem novas tentativas nem notificações de falha. Uma execução com falha não é repetida e não envia alerta: consulte o histórico, ou faça o endpoint chamado pela tarefa relatar as próprias falhas.