−25%

no Windows com pagamento anual, até 31/10. Ver planos

EQVPS
Começar

Como rodar um script 24/7 no Windows Server: sobrevive a logoff, travamentos e reinicializações

Mantenha um bot ou script rodando dia e noite num VPS com Windows Server 2022 só com o Agendador de Tarefas: inicia no boot sem ninguém logado, volta em menos de um minuto após um travamento e nunca roda duas cópias. Matamos o processo e reiniciamos para conferir.

O jeito comum de rodar um bot num VPS Windows é iniciá-lo numa sessão RDP e fechar a janela. Funciona até uma atualização reiniciar o servidor às 3 da manhã e ninguém iniciá-lo de novo. O Agendador de Tarefas, presente em qualquer Windows Server, resolve isso sem software extra. A configuração abaixo:

  • inicia o script no boot, antes de alguém fazer login;
  • o reinicia em menos de um minuto se ele travar ou for morto;
  • nunca roda duas cópias ao mesmo tempo.

Testamos as três coisas na nossa imagem de Windows Server 2022: matamos o processo, reiniciamos o servidor e contamos as instâncias.

O script de exemplo

Um substituto do seu bot: escreve uma linha a cada 10 segundos, assim é fácil ver se ele está vivo.

New-Item -ItemType Directory -Force C:\bots | Out-Null
Set-Content C:\bots\heartbeat.ps1 -Encoding ascii -Value @'
while ($true) {
    Add-Content -Path C:\bots\heartbeat.log -Value ("{0:u} pid {1}" -f (Get-Date), $PID)
    Start-Sleep -Seconds 10
}
'@

Registre a tarefa

Rode num PowerShell elevado:

$action   = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument '-NoProfile -ExecutionPolicy Bypass -File C:\bots\heartbeat.ps1' -WorkingDirectory 'C:\bots'
$atBoot   = New-ScheduledTaskTrigger -AtStartup
$everyMin = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 1)
$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit ([TimeSpan]::Zero) -MultipleInstances IgnoreNew -StartWhenAvailable
Register-ScheduledTask -TaskName 'mybot' -Action $action -Trigger $atBoot, $everyMin -Settings $settings -User 'SYSTEM' -RunLevel Highest
Start-ScheduledTask -TaskName 'mybot'

O que cada parte faz:

  • -AtStartup inicia o bot quando o Windows sobe, sem usuário logado.
  • A repetição a cada minuto roda a tarefa de novo a cada minuto. Se o bot está vivo, nada acontece; se morreu, ele inicia de novo.
  • -MultipleInstances IgnoreNew torna a repetição segura: uma execução que encontra o bot já rodando é pulada.
  • -ExecutionTimeLimit 0 desliga o limite padrão de 72 horas, depois do qual o Agendador pararia o bot.
  • -User 'SYSTEM' roda sem senha e sem sessão. A conta SYSTEM tem todos os direitos no servidor, então rode assim só o seu próprio código.

Para Python, troque a ação:

$action = New-ScheduledTaskAction -Execute 'C:\Program Files\Python312\python.exe' -Argument 'C:\bots\bot.py' -WorkingDirectory 'C:\bots'

O que conferimos

Travamento. Matamos o processo do bot com Stop-Process -Force. 46 segundos depois o gatilho de cada minuto tinha iniciado um novo, e havia exatamente uma cópia.

Reinicialização. Reiniciamos o servidor e não fizemos login. 40 segundos após o boot o bot já escrevia no log, sem sessões de usuário no servidor.

O que não funcionou. Duas coisas parecem certas e não são:

  1. «Se a tarefa falhar, reiniciar a cada…» Ativamos, matamos o processo e a tarefa ficou minutos em Pronto. A opção reage a falhas ao iniciar a tarefa, não ao seu programa morrer depois.
  2. Um laço de invólucro (while ($true) { & bot; sleep 5 }). Ele reinicia um bot que caiu, mas se o próprio invólucro morre, o filho continua rodando e a próxima execução inicia um segundo bot. Ficamos com duas cópias, o que num bot do Telegram significa dois processos disputando as mesmas atualizações.

Como acompanhar

Get-ScheduledTask -TaskName mybot | Select-Object TaskName, State
Get-ScheduledTaskInfo -TaskName mybot | Select-Object LastRunTime, NextRunTime
Get-Content C:\bots\heartbeat.log -Tail 5

Para pará-lo numa manutenção, primeiro rode Disable-ScheduledTask mybot (senão o gatilho de cada minuto o inicia de novo) e depois pare o processo. Enable-ScheduledTask mybot traz tudo de volta.

Logs

A tarefa não captura a saída. Faça o bot gravar o próprio log, como no exemplo, ou redirecione a saída num pequeno iniciador .cmd e aponte o -Execute para esse arquivo.

Qual plano

Um bot em PowerShell ou Python usa pouca CPU, mas o próprio Windows ocupa de 1 a 1,3 GB de RAM em repouso na nossa imagem. O Windows-Small (4 vCPU, 4 GB de RAM, 50 GB, $11/mês) é o tamanho certo para um ou dois bots. Num plano NAT, conexões de saída (Telegram, APIs de exchanges, webhooks que você chama) funcionam normalmente. Se o bot precisa receber webhooks ou outro tráfego de entrada, escolha o Windows Small-IP ($28/mês) com IPv4 próprio.

Próximos passos: proteja o RDP e, se preferir gerenciar o bot por SSH, instale o OpenSSH. O pagamento é em USDT, USDC ou ETH, e o Windows é Server 2022 com a sua própria licença (BYOL). Todos os planos: Windows VPS.

Perguntas frequentes

Por que não deixar o script rodando na minha sessão RDP?

Funciona até algo encerrar a sessão: um logoff, uma reinicialização por atualização ou um travamento. Fechar a janela do RDP (desconectar) mantém a sessão viva, mas o logoff mata tudo o que está nela, e depois de reiniciar ninguém está logado para iniciar o script de novo. Uma tarefa agendada não depende de sessão.

O Agendador de Tarefas não tem a opção «reiniciar se falhar»?

Tem, mas não ajudou no nosso teste. Quando matamos o processo do script, a tarefa foi para «Pronto» e ficou lá. Essa opção reage quando a tarefa não consegue iniciar, não quando o seu programa morre depois. O que o traz de volta é o gatilho repetido deste guia.

Podem acabar rodando duas cópias do meu bot?

Com esta configuração, não. A tarefa roda o próprio bot (sem script de invólucro) e usa MultipleInstances IgnoreNew, então o gatilho de cada minuto não faz nada enquanto o bot está vivo. O que cria duplicatas é justamente um laço de invólucro: mate o invólucro, o processo filho continua rodando e um novo invólucro inicia outro. Vimos exatamente isso.

Funciona com Python ou Node.js?

Sim. Coloque o interpretador em -Execute e o script em -Argument, com caminhos completos, por exemplo -Execute 'C:\Program Files\Python312\python.exe' -Argument 'C:\bots\bot.py'. Instale o interpretador para todos os usuários para que a conta SYSTEM o encontre.

Comentários

Nenhum comentário ainda. Seja o primeiro.

Deixe um comentário

Os comentários são moderados antes de aparecerem.