- README: o que a aplicação faz, migrations, BP_WEB_PORT e testes com
go.sum/package-lock.json (sem go mod tidy)
- ARQUITETURA: esquema real (00001 a 00003), rotas que faltavam, Compose
e imagens atuais, cadeia de proxies, retenção, situação dos testes,
decisões 30 a 33 e estado da implementação
- DEPLOY: cópia por tar, BP_WEB_PORT em todas as etapas e atualização
para a versão com exclusão de contas
- MANUAL: papéis do owner e navegação por ano nos feriados
- openapi.yaml: DELETE /accounts/{id} e regras da conta restrita
- Dockerfiles: comentários sobre go.sum e package-lock.json
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
613 lines
21 KiB
Markdown
613 lines
21 KiB
Markdown
# Guia de deploy — Bot de Pontos v2
|
|
|
|
Passo a passo para colocar o Bot de Pontos no ar no servidor de produção:
|
|
|
|
- **Servidor:** máquina física com **Debian 12**, fora do Proxmox, rodando Docker.
|
|
- **Acesso ao painel:** pelo **Nginx Proxy Manager (NPM)** que já existe em outra máquina da rede, com **certificado interno**.
|
|
- **Endereço do painel:** `https://botpontos.lan` (troque pelo nome que você usar).
|
|
|
|
> O backend compila e passa nos testes, e o painel passa na checagem de tipos. A etapa 6 repete essa validação no próprio servidor antes de subir tudo. Se algo falhar, guarde a saída do comando para correção.
|
|
>
|
|
> A porta do painel no servidor é **3000** por padrão. Se ela já estiver em uso, defina `BP_WEB_PORT` no `.env` (etapa 5.1) e use essa porta onde este guia diz 3000 (etapas 7, 8 e 9).
|
|
|
|
## Visão geral
|
|
|
|
```text
|
|
Navegador ──HTTPS──► NPM (outra máquina) ──HTTP :3000──► Servidor Debian (Docker)
|
|
├── web (Next.js, porta 3000)
|
|
├── api (Go, só rede interna)
|
|
├── worker (Go: bot + lembretes)
|
|
├── postgres (só rede interna)
|
|
└── backup (pg_dump diário)
|
|
```
|
|
|
|
| Etapa | O quê | Onde |
|
|
| --- | --- | --- |
|
|
| 1 | Reunir informações e credenciais | — |
|
|
| 2 | Preparar o Debian (IP fixo, NTP, atualizações) | servidor |
|
|
| 3 | Instalar o Docker | servidor |
|
|
| 4 | Copiar o projeto | Windows → servidor |
|
|
| 5 | Criar `.env` e segredos | servidor |
|
|
| 6 | Validar o código (testes) | servidor |
|
|
| 7 | Subir os containers | servidor |
|
|
| 8 | Firewall da porta do painel | servidor |
|
|
| 9 | DNS, certificado e Proxy Host | rede / NPM |
|
|
| 10 | Primeiro acesso e primeiro admin | navegador / Telegram |
|
|
| 11 | Backup fora da máquina | servidor |
|
|
| 12 | Conferência final | — |
|
|
|
|
Os comandos no servidor são executados como `root` (ou com `sudo`).
|
|
|
|
---
|
|
|
|
## 1. Reunir informações e credenciais
|
|
|
|
Tenha em mãos antes de começar:
|
|
|
|
| Item | Exemplo | Como obter |
|
|
| --- | --- | --- |
|
|
| IP fixo do servidor | `192.168.18.50` | reserva DHCP no roteador ou IP estático (etapa 2) |
|
|
| IP do NPM | `192.168.18.10` | máquina onde o NPM roda |
|
|
| Nome do painel | `botpontos.lan` | escolha um nome interno |
|
|
| Token do bot | `123456:ABC...` | no Telegram, fale com **@BotFather** → `/newbot` |
|
|
| Chave da feriadosapi.com | — | conta em feriadosapi.com (opcional: sem ela vale segunda a sexta) |
|
|
| Certificado interno | `.crt` + `.key` | emitido pela CA interna da rede para `botpontos.lan` (com o nome no **SAN**) |
|
|
| Credenciais PontoMais | e-mail e senha de cada usuário | cada usuário |
|
|
|
|
No @BotFather, depois de criar o bot, é recomendado:
|
|
|
|
- `/setjoingroups` → **Disable** (o bot só atende conversas privadas);
|
|
- `/setcommands` com a lista abaixo, para aparecer o menu de comandos:
|
|
|
|
```text
|
|
status - situação do cadastro e dos lembretes
|
|
entrada2 - retorno previsto do almoço
|
|
saida2 - saída prevista
|
|
ativarponto - ligar os lembretes
|
|
desativarponto - pausar os lembretes
|
|
cadastrar - solicitar acesso
|
|
ajuda - lista de comandos
|
|
```
|
|
|
|
---
|
|
|
|
## 2. Preparar o Debian
|
|
|
|
### 2.1 Atualizar o sistema
|
|
|
|
```bash
|
|
apt update && apt full-upgrade -y
|
|
```
|
|
|
|
### 2.2 IP fixo
|
|
|
|
O jeito mais simples é uma **reserva DHCP** no roteador para o MAC do servidor. Se preferir IP estático, edite `/etc/network/interfaces` (ajuste interface, IP e gateway):
|
|
|
|
```text
|
|
auto enp1s0
|
|
iface enp1s0 inet static
|
|
address 192.168.18.50/24
|
|
gateway 192.168.18.1
|
|
dns-nameservers 192.168.18.1
|
|
```
|
|
|
|
Confira:
|
|
|
|
```bash
|
|
ip -4 addr show
|
|
```
|
|
|
|
### 2.3 Relógio (NTP) — obrigatório
|
|
|
|
Os lembretes dependem da hora certa.
|
|
|
|
```bash
|
|
apt install -y systemd-timesyncd
|
|
```
|
|
|
|
```bash
|
|
timedatectl set-ntp true
|
|
```
|
|
|
|
```bash
|
|
timedatectl
|
|
```
|
|
|
|
A saída precisa mostrar `System clock synchronized: yes`. O fuso do sistema não importa (a aplicação grava em UTC e calcula no fuso de cada usuário), mas `America/Sao_Paulo` facilita a leitura dos logs:
|
|
|
|
```bash
|
|
timedatectl set-timezone America/Sao_Paulo
|
|
```
|
|
|
|
### 2.4 Ferramentas
|
|
|
|
```bash
|
|
apt install -y ca-certificates curl openssl iptables
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Instalar o Docker
|
|
|
|
Use o repositório oficial da Docker (o pacote `docker.io` do Debian costuma estar defasado).
|
|
|
|
```bash
|
|
install -m 0755 -d /etc/apt/keyrings
|
|
```
|
|
|
|
```bash
|
|
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
|
|
```
|
|
|
|
```bash
|
|
chmod a+r /etc/apt/keyrings/docker.asc
|
|
```
|
|
|
|
```bash
|
|
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" > /etc/apt/sources.list.d/docker.list
|
|
```
|
|
|
|
```bash
|
|
apt update && apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
|
```
|
|
|
|
Ligue o Docker na inicialização e confira:
|
|
|
|
```bash
|
|
systemctl enable --now docker
|
|
```
|
|
|
|
```bash
|
|
docker compose version
|
|
```
|
|
|
|
---
|
|
|
|
## 4. Copiar o projeto
|
|
|
|
O projeto vai para `/opt/botpontos`.
|
|
|
|
No servidor:
|
|
|
|
```bash
|
|
mkdir -p /opt/botpontos
|
|
```
|
|
|
|
No **Windows**, no PowerShell, dentro da pasta que contém `bot-pontos-v2` (ex.: `E:\Bruno\GIT`), gere um pacote sem os arquivos locais. O `tar` já vem no Windows 10/11:
|
|
|
|
```powershell
|
|
tar -czf bot-pontos-v2.tgz --exclude=node_modules --exclude=.next --exclude=.git --exclude=.env --exclude=backups --exclude=tsconfig.tsbuildinfo bot-pontos-v2
|
|
```
|
|
|
|
Envie para o servidor (troque usuário e IP):
|
|
|
|
```powershell
|
|
scp .\bot-pontos-v2.tgz usuario@192.168.18.50:/tmp/
|
|
```
|
|
|
|
> O pacote não leva `.env`, `backups/`, `node_modules`, `.next` nem o histórico do Git. A pasta `secrets/` deve ter só o `README.md`: os segredos são criados direto no servidor (etapa 5).
|
|
|
|
De volta ao servidor, extraia no lugar final:
|
|
|
|
```bash
|
|
tar -xzf /tmp/bot-pontos-v2.tgz -C /opt/botpontos --strip-components=1 && rm /tmp/bot-pontos-v2.tgz
|
|
```
|
|
|
|
```bash
|
|
cd /opt/botpontos && ls
|
|
```
|
|
|
|
Deve aparecer `backend`, `web`, `docs`, `docker-compose.yml`, `.env.example` etc.
|
|
|
|
Os scripts precisam de quebra de linha Linux (LF). Confira e, se aparecer `CRLF`, converta:
|
|
|
|
```bash
|
|
file postgres/init/01-create-app-role.sh scripts/backup-loop.sh
|
|
```
|
|
|
|
```bash
|
|
sed -i 's/\r$//' postgres/init/01-create-app-role.sh scripts/backup-loop.sh
|
|
```
|
|
|
|
---
|
|
|
|
## 5. Criar `.env` e segredos
|
|
|
|
Todos os comandos desta etapa rodam em `/opt/botpontos`.
|
|
|
|
### 5.1 `.env`
|
|
|
|
```bash
|
|
cp .env.example .env && nano .env
|
|
```
|
|
|
|
Ajuste:
|
|
|
|
```env
|
|
BP_HOST_LAN_IP=192.168.18.50 # IP fixo do servidor
|
|
BP_WEB_PORT=3000 # porta do painel no servidor; troque se a 3000 estiver em uso
|
|
BP_PUBLIC_URL=https://botpontos.lan # exatamente o endereço que o navegador usa
|
|
BP_NPM_IP=192.168.18.10 # IP do Nginx Proxy Manager
|
|
BP_COOKIE_SECURE=true
|
|
BP_LOG_LEVEL=info
|
|
BP_DEFAULT_TIMEZONE=America/Sao_Paulo
|
|
BP_HOLIDAY_LOCATION=3106200 # código IBGE da cidade dos feriados (3106200 = Belo Horizonte)
|
|
BP_ENCRYPTION_KEY_VERSION=1
|
|
```
|
|
|
|
Para saber se a 3000 já está ocupada no servidor:
|
|
|
|
```bash
|
|
ss -ltn 'sport = :3000'
|
|
```
|
|
|
|
Se aparecer alguma linha além do cabeçalho, escolha outra porta (ex.: `BP_WEB_PORT=3010`).
|
|
|
|
### 5.2 Segredos
|
|
|
|
```bash
|
|
mkdir -p secrets
|
|
```
|
|
|
|
```bash
|
|
openssl rand -base64 32 | tr -d '\n' > secrets/pg_password
|
|
```
|
|
|
|
```bash
|
|
openssl rand -base64 32 | tr -d '\n' > secrets/pg_app_password
|
|
```
|
|
|
|
```bash
|
|
openssl rand -base64 48 | tr -d '\n' > secrets/encryption_key
|
|
```
|
|
|
|
Token do bot (cole o seu entre as aspas simples):
|
|
|
|
```bash
|
|
printf '%s' 'COLE_O_TOKEN_DO_BOTFATHER' > secrets/telegram_token
|
|
```
|
|
|
|
Chave da feriadosapi.com (enviada como `Authorization: Bearer`), ou arquivo vazio se não tiver. A cidade dos feriados é o código IBGE em `BP_HOLIDAY_LOCATION` no `.env` (padrão `3106200`, Belo Horizonte):
|
|
|
|
```bash
|
|
printf '%s' 'COLE_A_CHAVE' > secrets/holiday_api_key
|
|
```
|
|
|
|
```bash
|
|
: > secrets/holiday_api_key
|
|
```
|
|
|
|
Permissões (a pasta protege; os arquivos precisam ser legíveis pelos containers):
|
|
|
|
```bash
|
|
chmod 700 secrets && chmod 644 secrets/*
|
|
```
|
|
|
|
### 5.3 Guardar a chave de criptografia fora do servidor
|
|
|
|
**Sem a `encryption_key`, as senhas da PontoMais gravadas não podem ser recuperadas.** Copie o conteúdo para o seu cofre de senhas agora:
|
|
|
|
```bash
|
|
cat secrets/encryption_key
|
|
```
|
|
|
|
---
|
|
|
|
## 6. Validar o código (testes)
|
|
|
|
Rode a validação no servidor antes de subir, para confirmar que o código copiado compila nesta máquina. Esses comandos usam containers temporários e não instalam Go nem Node na máquina.
|
|
|
|
Backend — roda `go vet` e os testes com as versões fixadas no `go.sum`:
|
|
|
|
```bash
|
|
docker run --rm -v "$PWD/backend:/src" -w /src golang:1.25-alpine sh -c "go vet ./... && go test ./..."
|
|
```
|
|
|
|
Painel — instala as versões do `package-lock.json` e checa os tipos:
|
|
|
|
```bash
|
|
docker run --rm -v "$PWD/web:/app" -w /app node:22-alpine sh -c "npm ci && npx tsc --noEmit"
|
|
```
|
|
|
|
- Tudo passou: siga para a etapa 7.
|
|
- Algo falhou: **pare aqui**, salve a saída completa e traga para correção.
|
|
|
|
> Os arquivos `go.sum` e `package-lock.json` fazem parte do projeto e fixam as versões das dependências. Não rode `go mod tidy` no servidor: com Go 1.25 ele tenta baixar versões novas que exigem Go 1.26 e o build quebra.
|
|
|
|
---
|
|
|
|
## 7. Subir os containers
|
|
|
|
```bash
|
|
docker compose up -d --build
|
|
```
|
|
|
|
O primeiro build leva alguns minutos. Depois confira:
|
|
|
|
```bash
|
|
docker compose ps -a
|
|
```
|
|
|
|
Resultado esperado:
|
|
|
|
| Serviço | Estado |
|
|
| --- | --- |
|
|
| `postgres` | `running (healthy)` |
|
|
| `migrate` | `exited (0)` |
|
|
| `api` | `running (healthy)` |
|
|
| `worker` | `running (healthy)` |
|
|
| `web` | `running (healthy)` |
|
|
| `backup` | `running` |
|
|
|
|
Logs, se algo não ficar saudável:
|
|
|
|
```bash
|
|
docker compose logs --tail=100 migrate api worker
|
|
```
|
|
|
|
O worker deve registrar `liderança obtida; worker ativo` e `bot do Telegram iniciado`.
|
|
|
|
Teste local da porta (no próprio servidor; troque 3000 se usou outro `BP_WEB_PORT`):
|
|
|
|
```bash
|
|
curl -s http://192.168.18.50:3000/healthz
|
|
```
|
|
|
|
Deve responder `{"status":"ok"}`.
|
|
|
|
---
|
|
|
|
## 8. Firewall da porta do painel
|
|
|
|
Portas publicadas pelo Docker **ignoram** regras comuns de `ufw`/`iptables INPUT`. A regra vai na cadeia `DOCKER-USER`, aplicada por um serviço do systemd.
|
|
|
|
> **Outra porta:** se definiu `BP_WEB_PORT` (por exemplo `3010`), use essa porta no lugar de 3000 nesta etapa, no `WEB_PORT` do serviço de firewall e no Forward Port do NPM (etapa 9). Dentro do Docker o painel continua na 3000.
|
|
|
|
Coloque o IP do NPM no arquivo:
|
|
|
|
```bash
|
|
sed -i 's/IP_DO_NPM/192.168.18.10/' deploy/botpontos-firewall.service
|
|
```
|
|
|
|
Só se `BP_WEB_PORT` não for 3000, ajuste também a porta (troque 3010 pela sua):
|
|
|
|
```bash
|
|
sed -i 's/WEB_PORT=3000/WEB_PORT=3010/' deploy/botpontos-firewall.service
|
|
```
|
|
|
|
Instale e ative:
|
|
|
|
```bash
|
|
cp deploy/botpontos-firewall.service /etc/systemd/system/
|
|
```
|
|
|
|
```bash
|
|
systemctl daemon-reload && systemctl enable --now botpontos-firewall
|
|
```
|
|
|
|
Confira a regra:
|
|
|
|
```bash
|
|
iptables -S DOCKER-USER
|
|
```
|
|
|
|
Deve aparecer uma linha com `--ctorigdstport 3000` (ou a sua porta) e `! -s 192.168.18.10/32 -j DROP`.
|
|
|
|
**Teste de aceite:** de um computador da rede que **não** seja o NPM, o acesso direto precisa falhar (timeout):
|
|
|
|
```bash
|
|
curl -m 5 http://192.168.18.50:3000/healthz
|
|
```
|
|
|
|
---
|
|
|
|
## 9. DNS, certificado e Proxy Host
|
|
|
|
### 9.1 DNS interno
|
|
|
|
No DNS da rede (roteador, Pi-hole, AdGuard etc.), crie:
|
|
|
|
```text
|
|
botpontos.lan → 192.168.18.10 (IP do NPM, não do servidor Docker)
|
|
```
|
|
|
|
### 9.2 Certificado no NPM
|
|
|
|
No NPM: **SSL Certificates → Add SSL Certificate → Custom**. Envie o `.crt` (com a cadeia, se houver) e a `.key` emitidos pela CA interna para `botpontos.lan`.
|
|
|
|
O certificado raiz da CA interna precisa estar instalado nos computadores que acessam o painel.
|
|
|
|
### 9.3 Proxy Host
|
|
|
|
**Hosts → Proxy Hosts → Add Proxy Host:**
|
|
|
|
| Aba | Campo | Valor |
|
|
| --- | --- | --- |
|
|
| Details | Domain Names | `botpontos.lan` |
|
|
| Details | Scheme | `http` |
|
|
| Details | Forward Hostname / IP | `192.168.18.50` |
|
|
| Details | Forward Port | `3000` (ou o valor de `BP_WEB_PORT`) |
|
|
| Details | Block Common Exploits | ligado |
|
|
| Details | Websockets Support | desligado |
|
|
| Details | Access List | uma lista que permita só a rede local (ex.: `192.168.18.0/24`) |
|
|
| SSL | SSL Certificate | o certificado da etapa 9.2 |
|
|
| SSL | Force SSL / HTTP/2 / HSTS | ligados |
|
|
|
|
Abra `https://botpontos.lan` num computador da rede: deve aparecer a tela de login, sem alerta de certificado.
|
|
|
|
> Anote a data de validade do certificado interno. Com HSTS ligado, um certificado vencido **bloqueia** o acesso em vez de só mostrar aviso.
|
|
|
|
---
|
|
|
|
## 10. Primeiro acesso e primeiro admin
|
|
|
|
### 10.1 Conta owner do painel
|
|
|
|
No servidor (a senha, de no mínimo 12 caracteres, é pedida sem eco):
|
|
|
|
```bash
|
|
docker compose run --rm api admin create-owner --username admin
|
|
```
|
|
|
|
Entre em `https://botpontos.lan` com essa conta.
|
|
|
|
### 10.2 Primeiro admin do Telegram
|
|
|
|
1. A pessoa que será admin envia `/cadastrar` ao bot no Telegram.
|
|
2. No painel, **Usuários** → abra o cadastro.
|
|
3. Em **Credencial PontoMais**, informe e-mail e senha → **Validar e salvar**. A credencial é testada na hora; se a PontoMais recusar, nada é gravado.
|
|
4. Clique em **Ativar**.
|
|
5. Clique em **Tornar admin do bot**.
|
|
6. A pessoa envia `/ativarponto` e confere com `/status`.
|
|
|
|
A partir daí, novos pedidos de cadastro chegam como aviso no Telegram desse admin.
|
|
|
|
### 10.3 Demais usuários
|
|
|
|
Para cada usuário: `/cadastrar` no Telegram → credencial no painel → **Ativar** → o usuário envia `/ativarponto`.
|
|
|
|
Recomendação: comece com 1 a 3 usuários (piloto) por alguns dias antes de liberar para todos.
|
|
|
|
### 10.4 Conta de leitura para um usuário (opcional)
|
|
|
|
Para que uma pessoa acompanhe só os próprios dados no painel:
|
|
|
|
1. O usuário já deve estar cadastrado e ativo (item 10.2 ou 10.3).
|
|
2. Entre com o owner → **Contas** → **Nova conta**: defina usuário e senha, papel **leitura** e escolha o **Usuário do Telegram**.
|
|
3. Entregue a senha à pessoa. Ela verá apenas Início, Usuários, Lembretes e Feriados, e só os próprios dados.
|
|
|
|
Não há migration nem variável de ambiente nova para isso: o vínculo usa a coluna `web_accounts.user_id`, que já existe. O backend e o painel precisam ser atualizados juntos.
|
|
|
|
### 10.5 Feriados
|
|
|
|
Em **Feriados**, clique em **Sincronizar** para o ano atual (se houver chave da feriadosapi.com) e cadastre feriados manuais que faltarem.
|
|
|
|
---
|
|
|
|
## 11. Backup fora da máquina
|
|
|
|
O container `backup` faz um `pg_dump` por dia em `/opt/botpontos/backups`, guardando 14 dias. **Um backup no mesmo disco não protege contra falha do disco.** Copie para outra máquina ou NAS.
|
|
|
|
Exemplo com um compartilhamento montado em `/mnt/nas` e cron diário às 04:00:
|
|
|
|
```bash
|
|
mkdir -p /mnt/nas/botpontos
|
|
```
|
|
|
|
```bash
|
|
echo '0 4 * * * root cp -n /opt/botpontos/backups/*.dump /mnt/nas/botpontos/ 2>/dev/null' > /etc/cron.d/botpontos-backup
|
|
```
|
|
|
|
Guarde também, fora do servidor:
|
|
|
|
- a `encryption_key` (etapa 5.3);
|
|
- o arquivo `.env`;
|
|
- uma cópia da pasta `secrets/` (num local seguro).
|
|
|
|
### Restaurar um backup
|
|
|
|
Pare os serviços que escrevem no banco:
|
|
|
|
```bash
|
|
docker compose stop api worker web
|
|
```
|
|
|
|
Restaure (troque o nome do arquivo):
|
|
|
|
```bash
|
|
docker compose exec -T postgres pg_restore -U botpontos -d botpontos --clean --if-exists --no-owner < backups/botpontos-AAAAMMDD-HHMMSS.dump
|
|
```
|
|
|
|
Suba de novo:
|
|
|
|
```bash
|
|
docker compose up -d
|
|
```
|
|
|
|
A `encryption_key` usada no restore precisa ser a mesma da época do backup.
|
|
|
|
---
|
|
|
|
## 12. Conferência final
|
|
|
|
- [ ] `docker compose ps -a` com todos saudáveis e `migrate` em `exited (0)`.
|
|
- [ ] `timedatectl` mostra o relógio sincronizado.
|
|
- [ ] Acesso direto à porta do painel (3000 ou `BP_WEB_PORT`) bloqueado para quem não é o NPM.
|
|
- [ ] `https://botpontos.lan` abre sem alerta de certificado.
|
|
- [ ] Login no painel funciona; conta owner criada.
|
|
- [ ] Admin do Telegram recebe aviso ao surgir um novo `/cadastrar`.
|
|
- [ ] Um usuário piloto recebeu o lembrete de retorno do almoço.
|
|
- [ ] Feriados do ano sincronizados ou cadastrados.
|
|
- [ ] Backup do dia existe em `backups/` e foi copiado para fora.
|
|
- [ ] `encryption_key` guardada no cofre de senhas.
|
|
|
|
---
|
|
|
|
## Atualizar a aplicação
|
|
|
|
1. Gere um backup manual antes:
|
|
|
|
```bash
|
|
docker compose exec backup sh -c 'PGPASSWORD=$(cat /run/secrets/pg_password) pg_dump -h postgres -U botpontos -d botpontos -Fc -f /backups/antes-da-atualizacao.dump'
|
|
```
|
|
|
|
2. Copie a nova versão do código para `/opt/botpontos` como na etapa 4. O pacote não leva `.env` nem `backups/`, e `secrets/` só tem o `README.md`, então os arquivos do servidor são mantidos.
|
|
3. Reconstrua e suba (as migrations rodam sozinhas no serviço `migrate`):
|
|
|
|
```bash
|
|
docker compose up -d --build
|
|
```
|
|
|
|
4. Confira com `docker compose ps -a` e os logs.
|
|
|
|
**Versão com feriadosapi.com e conta de leitura restrita.** Ao atualizar de uma versão anterior (que usava a feriados.dev):
|
|
|
|
- Troque o conteúdo de `secrets/holiday_api_key` pela chave da feriadosapi.com (a chave antiga não serve).
|
|
- No `.env`, troque `BP_HOLIDAY_LOCATION` de `MG-belo-horizonte` para `3106200` (código IBGE). Se esquecer, os feriados não sincronizam e vale segunda a sexta, com aviso aos admins.
|
|
- A migration `00002` roda sozinha no serviço `migrate`. Ela só amplia o `CHECK` de `holidays.source`; os feriados já gravados continuam valendo, e o ano atual não é baixado de novo.
|
|
- Para corrigir o ano com a nova API, use **Feriados → Sincronizar**: só entram datas que ainda não estão na tabela.
|
|
- A conta de leitura restrita (10.4) não exige configuração extra, mas backend e painel precisam subir juntos.
|
|
|
|
**Versão com exclusão de contas e porta configurável.**
|
|
|
|
- A migration `00003` roda sozinha. Ela cria `audit_logs.actor_account_name` (preenchida para os eventos antigos) e ajusta as chaves estrangeiras para permitir **Contas → Excluir** sem perder a auditoria.
|
|
- `BP_WEB_PORT` é opcional: sem ela, o painel continua na 3000. Se for trocar a porta, ajuste o `.env`, o `WEB_PORT` do firewall e o Forward Port do NPM. A regra antiga continua no `iptables` até o próximo boot; para aplicar a nova na hora:
|
|
|
|
```bash
|
|
cp deploy/botpontos-firewall.service /etc/systemd/system/ && systemctl daemon-reload && systemctl restart botpontos-firewall
|
|
```
|
|
|
|
Lembre de pôr de novo o IP do NPM (e a porta) no arquivo antes de copiar, como na etapa 8, porque a nova versão do arquivo volta com `IP_DO_NPM`.
|
|
|
|
Atualize também o sistema e as imagens base de tempos em tempos:
|
|
|
|
```bash
|
|
apt update && apt full-upgrade -y
|
|
```
|
|
|
|
```bash
|
|
docker compose pull postgres backup && docker compose up -d --build
|
|
```
|
|
|
|
---
|
|
|
|
## Problemas comuns
|
|
|
|
| Sintoma | Causa provável | O que fazer |
|
|
| --- | --- | --- |
|
|
| `docker compose up` reclama de `BP_HOST_LAN_IP` | `.env` ausente ou sem a variável | etapa 5.1 |
|
|
| `web` não sobe: `address already in use` / `port is already allocated` | outra aplicação usa a porta do painel | defina outro `BP_WEB_PORT` (etapa 5.1) e ajuste firewall e NPM |
|
|
| `secret ... file not found` | algum arquivo de `secrets/` não existe | etapa 5.2 (o `holiday_api_key` pode ser vazio, mas precisa existir) |
|
|
| `migrate` termina com erro de senha | senhas do banco trocadas depois da primeira subida | as senhas só valem na 1ª inicialização do volume; veja `secrets/README.md` |
|
|
| `api`/`worker` saem com `BP_ENCRYPTION_KEY ... obrigatório` | chave ausente ou com menos de 32 caracteres | refaça `secrets/encryption_key` |
|
|
| `worker` sai com `BP_TELEGRAM_TOKEN ... obrigatório` | token ausente | etapa 5.2 |
|
|
| Worker com `falha no getUpdates` repetido | token errado ou servidor sem internet | confira o token e a saída para a internet |
|
|
| Painel abre, mas o login diz "Origem da requisição não permitida" | `BP_PUBLIC_URL` diferente do endereço usado no navegador | ajuste o `.env` (com `https://`, sem barra no fim) e rode `docker compose up -d` |
|
|
| Login funciona, mas toda ação diz "Token CSRF inválido" | cookies de outra origem ou cache | apague os cookies do site e entre de novo; use sempre o mesmo endereço |
|
|
| Após login, volta para a tela de login | `BP_COOKIE_SECURE=true` acessando por `http://` | acesse pelo NPM com `https://` |
|
|
| Navegador alerta sobre o certificado | CA interna não instalada no computador, ou nome fora do SAN | etapa 9.2 |
|
|
| Lembretes não chegam | usuário sem `/ativarponto`, dia não útil, fora da janela, ou dia sem pontos | `/status` no Telegram; tela do usuário e **Auditoria** no painel |
|
|
| Lembrete aparece como **expirado** | ponto detectado com mais de 10 min de atraso | normal em almoço muito cedo ou atraso da PontoMais; ver ARQUITETURA.md 9.3 |
|
|
| Usuário pausado "após falhas na PontoMais" | 3 falhas seguidas de consulta | teste a credencial no painel e religue os lembretes |
|
|
| Alerta de "PontoMais fora do ar" | todas as consultas do ciclo falharam | aguarde; ninguém é pausado; o admin recebe aviso quando voltar |
|