Guia para colocar o Wedding Finance Planner online de forma estável.
casamento.seunome.com)./api/cron/reminders./api/cron/cleanup-files (limpa anexos ĂłrfĂŁos/soft-deletados).# Ubuntu/Debian
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl git build-essential
# Node 20 via nvm (na conta de usuário não-root)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
source ~/.bashrc
nvm install 20
# PM2 global
npm install -g pm2
cd /var/www
sudo git clone https://github.com/guiloklex-hub/wedding-management-system.git wedding
sudo chown -R $USER:$USER wedding
cd wedding
.env para produção./setup.sh # cria o .env padrão
nano .env
Edite:
DATABASE_URL="file:/var/lib/wedding/dev.db" # fora do diretĂłrio do cĂłdigo
NEXTAUTH_URL="https://casamento.seudominio.com"
APP_URL="https://casamento.seudominio.com"
AUTH_TRUST_HOST="true"
ADMIN_PASSWORD="SENHA_FORTE_AQUI" # trocada no 1Âş login
CRON_SECRET="<gerado pelo setup>"
# SMTP_* opcional (ou via UI)
Garanta o diretĂłrio persistente:
sudo mkdir -p /var/lib/wedding
sudo chown $USER:$USER /var/lib/wedding
./setup.sh --prod --skip-seed # ou --reset-db se quiser zerar
Esse comando:
npm install (caso nĂŁo tenha rodado);prisma db push);npm run build;wedding-management-system.Para fazer o PM2 subir junto com o boot do sistema:
pm2 startup # gera o comando systemd
# rode o sudo gerado
pm2 save # salva o estado atual
cloudflared no servidor:
curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared.deb
sudo cloudflared service install <TOKEN_DO_TĂšNEL>
casamento.seudominio.com → http://localhost:3005.Vantagens:
server {
listen 443 ssl http2;
server_name casamento.seudominio.com;
ssl_certificate /etc/letsencrypt/live/casamento.seudominio.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/casamento.seudominio.com/privkey.pem;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
location / {
proxy_pass http://127.0.0.1:3005;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
client_max_body_size 25m; # uploads
}
server {
listen 80;
server_name casamento.seudominio.com;
return 301 https://$host$request_uri;
}
Gerar certificado:
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d casamento.seudominio.com
crontab -e
*/30 * * * * curl -fsS -H "Authorization: Bearer SEU_CRON_SECRET" http://localhost:3005/api/cron/reminders >> /var/log/wedding-cron.log 2>&1
sudo mkdir -p /var/backups/wedding
sudo chown $USER:$USER /var/backups/wedding
crontab -e
0 3 * * * /usr/bin/cp /var/lib/wedding/dev.db /var/backups/wedding/wedding-$(date +\%F).db && find /var/backups/wedding -name "wedding-*.db" -mtime +30 -delete
Remove definitivamente anexos soft-deletados há mais de 30 dias e arquivos órfãos em disco (sem registro correspondente). Sem ele, o diretório de uploads cresce indefinidamente — risco de encher o disco.
crontab -e
0 4 * * * curl -fsS -H "Authorization: Bearer SEU_CRON_SECRET" http://localhost:3005/api/cron/cleanup-files >> /var/log/wedding-cron.log 2>&1
Acesse https://casamento.seudominio.com/dashboard/settings, aba WhatsApp,
escaneie o QR Code. A sessĂŁo fica em .whatsapp-auth/ dentro do diretĂłrio
do projeto.
⚠️ Esse diretório precisa ser persistido entre deploys. Se você costuma
rm -rfo projeto antes de fazergit pull, mova-o para fora antes.
cd /var/www/wedding
git pull
./setup.sh --prod --skip-seed
pm2 reload wedding-management-system
PM2 reinicia o processo Node com graceful reload — zero downtime na maioria dos casos.
pm2 status # estado geral
pm2 logs wedding-management-system # logs em tempo real
pm2 monit # dashboard interativo no terminal
Para um stack mais robusto, considere:
/api/cron/reminders apenas para
verificar liveness (e ele também cuida dos lembretes).Em next.config.ts você pode adicionar:
async headers() {
return [
{
source: "/(.*)",
headers: [
{ key: "X-Frame-Options", value: "DENY" },
{ key: "X-Content-Type-Options", value: "nosniff" },
{ key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
{ key: "Permissions-Policy", value: "camera=(), microphone=(), geolocation=()" },
],
},
];
}
(Se você usar Cloudflare ou nginx, configure também lá — defesa em profundidade.)
Veja backup-restore.md.