Clonar qualquer repositório do GitHub e hospedar em VPS

Guia completo do começo ao fim: conectar por SSH, instalar tudo, clonar o repositório (público ou privado), configurar variáveis de ambiente, build, PM2, Nginx, domínio, certificado SSL grátis, firewall, atualização normal, atualização forçada e diagnóstico de erros. Funciona para qualquer app Node/React/Next/TanStack.

Convenções usadas neste guia
Substitua sempre os valores em MAIÚSCULAS:
USUARIO/REPO = repositório do GitHub · MEUAPP = nome do projeto e do processo PM2 · PORTA = porta interna (3000, 3001…) · MEUDOMINIO.COM.BR = seu domínio · SEU@EMAIL.COM = e-mail para o certificado.
Passo 20

Atualização automática (comando único + cron)

Aqui você cria um script que faz tudo sozinho: git pull, npm install, build e restart do PM2. Depois, se quiser, agenda no cron para rodar automaticamente todo dia.

Preencha esses 3 valores antes de copiar os comandos
  • USUARIO = seu usuário do GitHub
  • REPO = nome do repositório no GitHub
  • MEUAPP = nome da pasta e do processo PM2

Exemplo: se o repositório for https://github.com/jogosdaunidade/relatorio-estadual.git, substitua USUARIO/REPO por jogosdaunidade/relatorio-estadual e MEUAPP por relatorio-estadual.

1. Criar o script de atualização automática

cat > /usr/local/bin/auto-update-MEUAPP <<'EOF'
#!/usr/bin/env bash
set -euo pipefail

APP_DIR="/var/www/MEUAPP"
APP_NAME="MEUAPP"
BRANCH="main"
LOG="/var/log/auto-update-$APP_NAME.log"

exec >> "$LOG" 2>&1
echo "===== $(date '+%F %T') iniciando atualização ====="

cd "$APP_DIR"
git fetch origin "$BRANCH"

LOCAL=$(git rev-parse HEAD)
REMOTE=$(git rev-parse "origin/$BRANCH")

if [ "$LOCAL" = "$REMOTE" ]; then
  echo "Nada novo no GitHub. Nada a fazer."
  exit 0
fi

echo ">> Novidades encontradas. Atualizando..."
git pull origin "$BRANCH"
npm install --no-audit --no-fund
NITRO_PRESET=node-server npm run build
pm2 restart "$APP_NAME" --update-env
pm2 save
echo ">> Atualização concluída com sucesso."
EOF
chmod +x /usr/local/bin/auto-update-MEUAPP

Troque MEUAPP pela pasta e pelo nome do processo no PM2. Se o projeto não for TanStack/Nitro, use apenas npm run build.

2. Rodar manualmente (comando único)

auto-update-MEUAPP

Versão em uma linha só, sem criar script:

cd /var/www/MEUAPP && git pull origin main && npm install --no-audit --no-fund && NITRO_PRESET=node-server npm run build && pm2 restart MEUAPP --update-env && pm2 save

Troque MEUAPP e main pelos seus valores reais.

3. Agendar no cron (opcional)

crontab -e

Adicione UMA das linhas abaixo no final do arquivo e salve:

# todo dia às 03:00 da manhã
0 3 * * * /usr/local/bin/auto-update-MEUAPP

# a cada 30 minutos
*/30 * * * * /usr/local/bin/auto-update-MEUAPP

# a cada hora cheia
0 * * * * /usr/local/bin/auto-update-MEUAPP

Troque MEUAPP pelo nome do processo PM2.

Conferir se o agendamento foi salvo e acompanhar o log:

crontab -l
tail -f /var/log/auto-update-MEUAPP.log

Para desativar o agendamento depois:

crontab -e   # apague a linha do auto-update e salve
Cuidados com o cron
O script só reconstrói quando existe commit novo no GitHub, então rodar de hora em hora não pesa na VPS. Ainda assim, evite intervalos menores que 15 minutos: o build consome CPU e RAM e pode derrubar o app em VPS pequena. Se o repositório for privado, configure antes o PAT ou a deploy key (Passo 7), senão o cron trava pedindo usuário e senha.

Resumo rápido (do zero ao ar)

ssh root@IP_DA_VPS
apt update && apt upgrade -y && apt install -y git nginx ufw
curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt install -y nodejs
npm i -g pm2
cd /var/www && git clone https://github.com/USUARIO/REPO.git MEUAPP && cd MEUAPP
nano .env
npm install && npm run build
PORT=PORTA pm2 start ".output/server/index.mjs" --name MEUAPP && pm2 save && pm2 startup
nano /etc/nginx/sites-available/MEUAPP
ln -s /etc/nginx/sites-available/MEUAPP /etc/nginx/sites-enabled/ && nginx -t && systemctl reload nginx
certbot --nginx -d MEUDOMINIO.COM.BR --agree-tos -m SEU@EMAIL.COM --redirect
ufw allow 'Nginx Full' && ufw allow OpenSSH && ufw --force enable