Skip to content

Development and architecture

How to run the panel on your computer and how the code is organized. To contribute (standards, tests, pull request flow), read CONTRIBUTING.md.

Terminal window
pnpm install
SETUP_TOKEN=dev-token pnpm dev
# or, with Docker:
SETUP_TOKEN=dev-token docker compose -f docker-compose.dev.yml up
  • Panel (production build served by the API): http://localhost:9000
  • Frontend with hot reload: http://localhost:5173 (proxy /api → 9000)
  • Wizard: http://localhost:5173/setup with the token dev-token
  • Project domains: use *.localhost (served over plain HTTP by Caddy, no SSL)

Ready-to-deploy examples in examples/.

pnpm monorepo with strict TypeScript end to end:

tws-panel/
├── apps/
│ ├── server/ # Fastify API: wizard, projects, domains, email,
│ │ # certificates, notifications, backups,
│ │ # security, alerts and auditing
│ └── web/ # React SPA (Vite + Tailwind + shadcn/ui):
│ # /setup wizard + dark pt-BR dashboard
├── packages/
│ ├── core/ # shared types and constants
│ ├── security/ # scan engine + hardening + baseline/diff
│ ├── deploy/ # detection, ingestion, guardrails, Caddy, pipelines
│ └── mailer/ # Stalwart, DKIM, DNS checklist, blacklist,
│ # deliverability score
├── scripts/
│ ├── install.sh # one-shot installer (idempotent, 100% Docker)
│ ├── hardening/ # idempotent shell scripts per phase (00–07)
│ ├── hooks/ # local git hooks (pre-commit / pre-push)
│ ├── show-token.sh, reset-*.sh, reativar-acesso-ip.sh,
│ │ restaurar-painel.sh, uninstall.sh # VPS operations utilities
│ └── test-*.mts # verification suites (Phases 3 and 4)
├── examples/ # example apps for deploy (testing only)
├── site/ # documentation site (Starlight); the guides live in site/src/content/docs/
├── docs/ # README images, internal specs and the Portuguese community texts
├── comoFuncionaSistema/ # machine-readable documentation (for AI agents)
├── Dockerfile # multi-stage build of the panel (production)
├── docker-compose.yml # production: panel on 127.0.0.1:PAAS_PORT (default 9000)
└── docker-compose.dev.yml # local dev with hot reload

How the modules relate to each other:

┌─────────────┐
browser ───►│ apps/web │ (SPA: wizard + dashboard)
└──────┬──────┘
│ /api
┌──────▼──────┐ ┌───────────────┐
│ apps/server │─────►│ @paas/security│──► host (Lynis, UFW,
│ (Fastify) │ └───────────────┘ fail2ban, baseline)
└──┬───┬───┬──┘
│ │ │ ┌───────────────┐
│ │ └─────►│ @paas/deploy │──► Docker + central Caddy
│ │ └───────────────┘ (automatic SSL)
│ │ ┌───────────────┐
│ └─────────►│ @paas/mailer │──► Stalwart (SMTP/IMAP/DKIM)
│ └───────────────┘ + Roundcube (webmail)
│ ┌───────────────┐
└─────────────►│ @paas/core │ (shared types)
└───────────────┘
State persisted in the paas_data volume (/data, JSON files, mode 0600)
— no database. External services only the ones you turn on: GitHub,
Telegram and the S3/R2 storage for backups.

The guides live in site/src/content/docs/<language>/ (en is the default, pt-br the secondary one) and are published with Starlight. Files have the same path in every language; a page that has not been translated yet is shown in English on the site. To add a language, create its folder next to en/ and add an entry to locales in site/astro.config.mjs.

Terminal window
pnpm docs:dev # local server with live reload
pnpm docs:build # builds site/dist (the same step the GitHub Pages workflow runs)
pnpm docs:links # checks internal links and anchors in every .md file

Between guides, use relative links to the .md file (for example ../guides/operations.md#anchor): they work on GitHub and are rewritten to the site URLs at build time.