infra: stack Traefik (Swarm), exemplos de env, CI GitHub Actions e ajuste workspace pnpm
This commit is contained in:
parent
e4db48d8b4
commit
ec1539b446
7 changed files with 255 additions and 1 deletions
59
.env.example
Normal file
59
.env.example
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
# Ambiente local — Sistema de Chamados
|
||||
# Copie este arquivo para `.env` e preencha os valores sensíveis.
|
||||
# Nunca faça commit de `.env` com segredos reais.
|
||||
|
||||
# Convex
|
||||
CONVEX_DEPLOYMENT=anonymous:anonymous-sistema-de-chamados
|
||||
NEXT_PUBLIC_CONVEX_URL=http://127.0.0.1:3210
|
||||
CONVEX_SYNC_SECRET=dev-sync-secret
|
||||
|
||||
# Next.js / App URL
|
||||
NEXT_PUBLIC_APP_URL=http://localhost:3000
|
||||
|
||||
# Better Auth
|
||||
# Gere um segredo forte (ex.: `openssl rand -hex 32`)
|
||||
BETTER_AUTH_SECRET=change-me
|
||||
BETTER_AUTH_URL=http://localhost:3000
|
||||
|
||||
# Banco de dados (Prisma)
|
||||
DATABASE_URL=file:./prisma/db.sqlite
|
||||
|
||||
# Provisionamento e inventário de máquinas
|
||||
# Segredo obrigatório para registrar/atualizar máquinas (Convex)
|
||||
MACHINE_PROVISIONING_SECRET=change-me-provisioning
|
||||
# Tempo de vida do token de máquina (ms) — padrão 30 dias
|
||||
MACHINE_TOKEN_TTL_MS=2592000000
|
||||
# Opcional: segredo dedicado para webhook do FleetDM (senão usa o de provisionamento)
|
||||
FLEET_SYNC_SECRET=
|
||||
|
||||
# SMTP (envio de e-mails)
|
||||
SMTP_ADDRESS=
|
||||
SMTP_PORT=465
|
||||
SMTP_DOMAIN=
|
||||
SMTP_USERNAME=
|
||||
SMTP_PASSWORD=
|
||||
SMTP_AUTHENTICATION=login
|
||||
SMTP_ENABLE_STARTTLS_AUTO=false
|
||||
SMTP_TLS=true
|
||||
MAILER_SENDER_EMAIL="Suporte <no-reply@seu-dominio.com>"
|
||||
|
||||
# Alertas (actions do Convex)
|
||||
# Hora local (America/Sao_Paulo) para rodar alertas automáticos
|
||||
ALERTS_LOCAL_HOUR=8
|
||||
|
||||
# Seeds e sincronizações auxiliares
|
||||
SYNC_TENANT_ID=tenant-atlas
|
||||
SYNC_DEFAULT_ASSIGNEE=agent@example.com
|
||||
SEED_TENANT_ID=tenant-atlas
|
||||
SEED_ADMIN_PASSWORD=admin123
|
||||
SEED_AGENT_PASSWORD=agent123
|
||||
SEED_USER_TENANT=tenant-atlas
|
||||
SEED_USER_EMAIL=
|
||||
SEED_USER_PASSWORD=
|
||||
SEED_USER_NAME=
|
||||
SEED_USER_ROLE=admin
|
||||
|
||||
# Desenvolvimento Desktop (Tauri/Vite)
|
||||
# Em redes locais, defina o IP do host para HMR.
|
||||
TAURI_DEV_HOST=
|
||||
|
||||
97
.github/workflows/ci-cd-web-desktop.yml
vendored
Normal file
97
.github/workflows/ci-cd-web-desktop.yml
vendored
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
name: CI/CD Web + Desktop
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
tags:
|
||||
- 'v*.*.*'
|
||||
|
||||
env:
|
||||
APP_DIR: /srv/apps/sistema
|
||||
VPS_UPDATES_DIR: /var/www/updates
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
name: Deploy (VPS Linux)
|
||||
if: ${{ startsWith(github.ref, 'refs/heads/') }}
|
||||
runs-on: [ self-hosted, linux, vps ]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Sync workspace to APP_DIR
|
||||
run: |
|
||||
mkdir -p "$APP_DIR"
|
||||
rsync -az --delete --exclude '.git' --exclude '.next' ./ "$APP_DIR"/
|
||||
|
||||
- name: Install and build (Next.js)
|
||||
run: |
|
||||
cd "$APP_DIR"
|
||||
corepack enable || true
|
||||
pnpm install --frozen-lockfile
|
||||
pnpm prisma:generate
|
||||
pnpm build
|
||||
|
||||
- name: Optional Swarm deploy (stack.yml)
|
||||
if: ${{ hashFiles(format('{0}/stack.yml', env.APP_DIR)) != '' }}
|
||||
run: |
|
||||
cd "$APP_DIR"
|
||||
docker stack deploy --with-registry-auth -c stack.yml sistema
|
||||
|
||||
desktop_release:
|
||||
name: Desktop Release (Windows)
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
|
||||
runs-on: [ self-hosted, windows, desktop ]
|
||||
defaults:
|
||||
run:
|
||||
working-directory: apps/desktop
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install deps (desktop)
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build with Tauri
|
||||
uses: tauri-apps/tauri-action@v0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||
with:
|
||||
projectPath: apps/desktop
|
||||
|
||||
- name: Upload latest.json + bundles to VPS
|
||||
uses: appleboy/scp-action@v0.1.7
|
||||
with:
|
||||
host: ${{ secrets.VPS_HOST }}
|
||||
username: ${{ secrets.VPS_USER }}
|
||||
key: ${{ secrets.VPS_SSH_KEY }}
|
||||
source: |
|
||||
**/bundle/**/latest.json
|
||||
**/bundle/**/*
|
||||
target: ${{ env.VPS_UPDATES_DIR }}
|
||||
overwrite: true
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -33,6 +33,8 @@ yarn-error.log*
|
|||
|
||||
# env files (can opt-in for committing if needed)
|
||||
.env*
|
||||
!.env.example
|
||||
!apps/desktop/.env.example
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ Aplicação Next.js 15 com Convex e Better Auth para gestão de tickets da Rever
|
|||
```bash
|
||||
pnpm install
|
||||
```
|
||||
2. Ajuste o arquivo `.env` (ou crie a partir do exemplo) e confirme os valores de:
|
||||
2. Ajuste o arquivo `.env` (ou crie a partir de `.env.example`) e confirme os valores de:
|
||||
- `NEXT_PUBLIC_CONVEX_URL` (gerado pelo Convex Dev)
|
||||
- `BETTER_AUTH_SECRET`, `BETTER_AUTH_URL`, `DATABASE_URL`
|
||||
3. Aplique as migrações e gere o client Prisma:
|
||||
|
|
@ -42,6 +42,12 @@ Aplicação Next.js 15 com Convex e Better Auth para gestão de tickets da Rever
|
|||
|
||||
> Se o CLI perguntar sobre configuração do projeto Convex, escolha criar um novo deployment local (opção padrão) e confirme. As credenciais são armazenadas em `.convex/` automaticamente.
|
||||
|
||||
### Variáveis de ambiente
|
||||
|
||||
- Exemplo na raiz: `.env.example` — copie para `.env` e preencha segredos.
|
||||
- App Desktop: `apps/desktop/.env.example` — copie para `apps/desktop/.env` e ajuste `VITE_APP_URL`.
|
||||
- Nunca faça commit de arquivos `.env` com valores reais (já ignorados em `.gitignore`).
|
||||
|
||||
## Scripts úteis
|
||||
|
||||
- `pnpm lint` — ESLint com as regras do projeto.
|
||||
|
|
|
|||
10
apps/desktop/.env.example
Normal file
10
apps/desktop/.env.example
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# Ambiente local do App Desktop (Vite/Tauri)
|
||||
# Copie para `apps/desktop/.env` e ajuste.
|
||||
|
||||
# URL da aplicação web (Next.js) que será carregada dentro do app desktop.
|
||||
VITE_APP_URL=http://localhost:3000
|
||||
|
||||
# Opcional: IP do host para desenvolvimento com HMR fora do localhost
|
||||
# Ex.: 192.168.0.10
|
||||
TAURI_DEV_HOST=
|
||||
|
||||
|
|
@ -1,3 +1,6 @@
|
|||
packages:
|
||||
- .
|
||||
|
||||
ignoredBuiltDependencies:
|
||||
- '@prisma/client'
|
||||
- '@prisma/engines'
|
||||
|
|
|
|||
77
stack.yml
Normal file
77
stack.yml
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
version: "3.8"
|
||||
|
||||
services:
|
||||
web:
|
||||
image: node:20-bullseye
|
||||
working_dir: /app
|
||||
command: >
|
||||
bash -lc "corepack enable \
|
||||
&& corepack prepare pnpm@9 --activate \
|
||||
&& pnpm install --frozen-lockfile \
|
||||
&& pnpm prisma:generate \
|
||||
&& npx prisma migrate deploy \
|
||||
&& pnpm build \
|
||||
&& pnpm start -p 3000"
|
||||
volumes:
|
||||
- ./:/app
|
||||
- sistema_db:/app/data
|
||||
environment:
|
||||
NODE_ENV: "production"
|
||||
# Mantém o SQLite fora do repositório
|
||||
DATABASE_URL: "file:/app/data/db.sqlite"
|
||||
deploy:
|
||||
mode: replicated
|
||||
replicas: 1
|
||||
placement:
|
||||
constraints:
|
||||
- node.role == manager
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.docker.network=traefik_public
|
||||
- traefik.http.routers.sistema_web.rule=Host(`tickets.esdrasrenan.com.br`)
|
||||
- traefik.http.routers.sistema_web.entrypoints=websecure
|
||||
- traefik.http.routers.sistema_web.tls=true
|
||||
- traefik.http.routers.sistema_web.tls.certresolver=le
|
||||
- traefik.http.services.sistema_web.loadbalancer.server.port=3000
|
||||
networks:
|
||||
- traefik_public
|
||||
|
||||
convex:
|
||||
image: node:20-bullseye
|
||||
working_dir: /app
|
||||
command: >
|
||||
bash -lc "corepack enable \
|
||||
&& corepack prepare pnpm@9 --activate \
|
||||
&& pnpm install --frozen-lockfile \
|
||||
&& set -a && . ./.env && set +a \
|
||||
&& pnpm convex:dev --port 3210 --hostname 0.0.0.0"
|
||||
volumes:
|
||||
- ./:/app
|
||||
- convex_data:/root/.convex
|
||||
environment:
|
||||
NODE_ENV: "production"
|
||||
deploy:
|
||||
mode: replicated
|
||||
replicas: 1
|
||||
placement:
|
||||
constraints:
|
||||
- node.role == manager
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.docker.network=traefik_public
|
||||
- traefik.http.routers.sistema_convex.rule=Host(`convex.esdrasrenan.com.br`)
|
||||
- traefik.http.routers.sistema_convex.entrypoints=websecure
|
||||
- traefik.http.routers.sistema_convex.tls=true
|
||||
- traefik.http.routers.sistema_convex.tls.certresolver=le
|
||||
- traefik.http.services.sistema_convex.loadbalancer.server.port=3210
|
||||
networks:
|
||||
- traefik_public
|
||||
|
||||
volumes:
|
||||
sistema_db:
|
||||
convex_data:
|
||||
|
||||
networks:
|
||||
traefik_public:
|
||||
external: true
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue