VPS e variáveis
Um projeto blog roda num processo só: o painel fica em /painel e o site publicado em /. Os dados ficam em storage/ (banco SQLite, backups, mídias e a cópia de trabalho dos builds), fora do git.
Esta página segue o passo a passo do README.md que o slash create gera no projeto. Crie o projeto antes com slash create <pasta> --template blog (veja Modelos do blog). O slash create também deixa na pasta deploy/ os três arquivos de exemplo usados aqui. Eles não ficam ativos na sua máquina: você os copia para a VPS e preenche.
Requisitos
Seção intitulada “Requisitos”- Um servidor Linux com systemd.
- Bun 1.4.3, a versão que o README do projeto fixa no instalador.
- Caddy, para o HTTPS.
- GNU tar. O painel chama o
tardo sistema com opções do GNU (--quoting-style), e outrotar, como o do BSD, não serve. unzipecurl. O instalador do Bun usa os dois.- Um disco com espaço para o banco, os backups e a cópia de trabalho dos builds. A pasta
storage/precisa estar no mesmo disco do projeto (veja Vários projetos, mídia e atualização).
Usuário do serviço e Bun
Seção intitulada “Usuário do serviço e Bun”Cada projeto roda com um usuário de sistema próprio, slash-<projeto>. <projeto> é o nome da pasta do projeto, sem acento, em minúsculas e com hífens no lugar dos outros caracteres. Nos comandos e nos exemplos desta página, projeto aparece literal; no seu projeto, a pasta deploy/ já traz o nome trocado. Se o nome passar de 26 caracteres, o usuário sai cortado e com um hash no fim, como explica Vários projetos, mídia e atualização.
Crie o usuário e instale o Bun para ele:
sudo useradd --system --create-home slash-<projeto>
sudo -u slash-<projeto> -H sh -c 'curl -fsSL https://bun.sh/install | bash -s "bun-v1.4.3"'
O PATH do sudo e o do systemd não trazem o Bun. Por isso, todo comando desta página chama /home/slash-<projeto>/.bun/bin/bun pelo caminho completo.
Copie a pasta do projeto para /srv/<projeto>, sem node_modules, dist e storage. Dê a pasta ao usuário do serviço e instale as dependências como ele:
sudo chown -R slash-<projeto>:slash-<projeto> /srv/<projeto>
sudo -u slash-<projeto> -H sh -c 'cd /srv/<projeto> && /home/slash-<projeto>/.bun/bin/bun install'
O banco, a cópia de trabalho dos builds e o dist/ são criados nessa pasta, pelo próprio usuário do serviço.
Variáveis de ambiente
Seção intitulada “Variáveis de ambiente”Crie /etc/slash-<projeto>.env com dono root e permissão 600. O arquivo de exemplo é este:
deploy/slash-projeto.env.example
# Copie para /etc/slash-<projeto>.env (dono root, permissão 600) e preencha.
# Um valor com espaço vai entre aspas, como o MAIL_FROM.
PORT=4330
PUBLIC_URL=https://seu-dominio.com.br
PANEL_SECRET=troque-por-openssl-rand-hex-32
TRUST_PROXY=1
RESEND_API_KEY=re_troque
MAIL_FROM="Painel <painel@seu-dominio.com.br>"
Um valor com espaço vai entre aspas, como o MAIL_FROM. Estas são as variáveis que o painel lê, com a regra de cada uma:
| Variável | Obrigatória | Padrão | Validação | Mensagem |
|---|---|---|---|---|
PORT | Sim | — | use um inteiro de 1 a 65535. | PORT: defina a porta do painel (um número de 1 a 65535). |
PUBLIC_URL | Sim | — | defina o endereço público, como https://painel.exemplo.com (sem caminho nem credenciais; http só para localhost). | PUBLIC_URL: defina o endereço público, como https://painel.exemplo.com (sem caminho nem credenciais; http só para localhost). |
PANEL_SECRET | Sim | — | use pelo menos 32 caracteres (gere com: openssl rand -hex 32). | PANEL_SECRET: use pelo menos 32 caracteres (gere com: openssl rand -hex 32). |
TRUST_PROXY | Sim | — | use 1 (atrás do Caddy, o proxy da VPS) ou 0 (sem proxy na frente). | TRUST_PROXY: use 1 (atrás do Caddy, o proxy da VPS) ou 0 (sem proxy na frente). |
HOST | Não | 127.0.0.1 | use um endereço IP ou nome de máquina (padrão 127.0.0.1). | HOST: use um endereço IP ou nome de máquina (padrão 127.0.0.1). |
DATABASE_URL | Não | sqlite://<projeto>/storage/db.sqlite | — | — |
RESEND_API_KEY | Sim | — | — | RESEND_API_KEY: defina a chave do Resend (em produção o e-mail nunca vai ao console). |
MAIL_FROM | Sim | — | defina o remetente, como Painel <painel@exemplo.com>. | MAIL_FROM: defina o remetente, como Painel <painel@exemplo.com>. |
Avisos de produção
- TRUST_PROXY=1 com HOST=0.0.0.0: o servidor aceita conexões de fora do proxy, e quem as faz escolhe o próprio X-Forwarded-For (os limites por endereço deixam de valer). Com o Caddy na mesma máquina, deixe o HOST em 127.0.0.1; senão use TRUST_PROXY=0 ou feche a porta para o resto da rede.
- TRUST_PROXY=0: o servidor escuta só em 127.0.0.1, então todo acesso chega de 127.0.0.1. Se houver um proxy (Caddy) na frente, use TRUST_PROXY=1; sem proxy, ignore este aviso.
Algumas observações:
PANEL_SECRETdeve ficar fixo. Trocá-lo invalida os formulários abertos, quebra os links de descadastro dos e-mails já enviados da newsletter e muda os hashes de IP dos bloqueios.PUBLIC_URLé a origem dos links dos e-mails, como a confirmação de inscrição e a redefinição de senha.DATABASE_URLé opcional. Sem ela, o banco fica emstorage/db.sqlite.- Atrás do Caddy, use
TRUST_PROXY=1. Sem proxy na frente, use0. - Em produção, o processo não sobe sem
RESEND_API_KEY,MAIL_FROMválido,PANEL_SECRETcom 32 caracteres ou mais e as demais variáveis obrigatórias. A mensagem de erro lista tudo que falta de uma vez, emConfiguração de produção inválida. Corrija:. HOSTvem com127.0.0.1por padrão. O servidor escuta só na própria máquina, e é o Caddy que recebe a conexão de fora.
A descrição completa de cada variável está na página de referência das variáveis, em Variáveis de ambiente.
Serviço systemd
Seção intitulada “Serviço systemd”O arquivo de exemplo do serviço é este:
deploy/slash-projeto.service.example
# Copie para /etc/systemd/system/slash-projeto.service na VPS. Crie o usuário do serviço e dê a pasta a ele:
# useradd --system --create-home slash-projeto
# chown -R slash-projeto:slash-projeto /srv/projeto
# Copie o arquivo de ambiente (deploy/slash-projeto.env.example) para /etc/slash-projeto.env e depois:
# systemctl daemon-reload && systemctl enable --now slash-projeto
[Unit]
Description=slash-projeto (painel e site)
After=network-online.target
Wants=network-online.target
[Service]
User=slash-projeto
WorkingDirectory=/srv/projeto
# O systemd não lê o perfil do usuário: sem o PATH abaixo, `bun run start` e o build do publicador (que chama `bun`) não acham o bun.
Environment=PATH=/home/slash-projeto/.bun/bin:/usr/local/bin:/usr/bin:/bin
Environment=NODE_ENV=production
EnvironmentFile=/etc/slash-projeto.env
# Ajuste o caminho do bun instalado para o usuário do serviço.
ExecStart=/home/slash-projeto/.bun/bin/bun run start
Restart=on-failure
# O build roda em subprocesso de até 5 minutos; 1 GB cobre o painel e o build.
MemoryMax=1G
NoNewPrivileges=true
# O serviço lê o sistema em modo somente leitura; /srv/projeto segue gravável para o banco, os builds e o site.
ProtectSystem=full
PrivateTmp=true
[Install]
WantedBy=multi-user.target
Copie-o para /etc/systemd/system/slash-<projeto>.service. Confira o caminho do bun em ExecStart= e em PATH=, e depois rode:
sudo systemctl daemon-reload && sudo systemctl enable --now slash-<projeto>
O serviço roda bun run start, que no projeto blog executa bun src/server.ts com NODE_ENV=production. O limite de memória é de 1 GB por serviço, que cobre o painel e o build do site.
Caddy e HTTPS
Seção intitulada “Caddy e HTTPS”O arquivo de exemplo do Caddy é este:
deploy/Caddyfile.example
# Copie para /etc/caddy/Caddyfile na VPS e troque o domínio.
# Um bloco por site: outro projeto na mesma VPS entra como outro bloco, com outra porta.
# O Caddy obtém e renova o HTTPS sozinho; a porta é a PORT do arquivo de ambiente do serviço.
seu-dominio.com.br {
reverse_proxy 127.0.0.1:4330
}
Copie-o para /etc/caddy/Caddyfile, troque o domínio e recarregue o Caddy:
sudo systemctl reload caddy
O Caddy obtém e renova o certificado sozinho. A porta em reverse_proxy tem de ser a mesma PORT do arquivo de ambiente.
Próximo passo
Seção intitulada “Próximo passo”Com o serviço no ar, crie o primeiro administrador e faça a primeira publicação em Primeiro admin e publicação.