Add README.md, docs/ (fluxo, configuracao, arquitetura) in PT-BR and a CLAUDE.md technical reference in English describing the installer flow, generated files, containers and architecture. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
6.7 KiB
CLAUDE.md
Guidance for Claude Code when working in this repository.
User-facing docs are in Portuguese (BR): README.md and docs/. This file is in English and is the technical source of truth for how the code works.
What this is
A terminal UI (TUI) installer for the "App do Dono" client middleware. The middleware runs on a tenant's infrastructure and brokers communication between the tenant's servers and davinTI's central server.
The installer is a guided wizard that: checks Docker → logs into the private registry
→ pulls images → (optionally) sets up a WireGuard tunnel (vproxy) when there is no
public IP → collects configuration via terminal forms → generates config files
(config.toml, envs) → runs the Docker containers.
It is not the middleware itself — it only provisions and launches it via docker.
Tech stack
- Go 1.25
- Bubble Tea v2 (
charm.land/bubbletea/v2) — Elm-architecture TUI runtime. - Bubbles v2 —
textinput,spinnercomponents. - Lip Gloss v2 — styling.
- BurntSushi/toml — read existing
config.tomlfor form defaults. - Module path:
git.davinti.com.br/davinTI/app-dono/tui.
Layout
cmd/main.go Entry point; starts the Bubble Tea program.
internal/tui/
model.go Model struct, ConfigValues, loadConfig (defaults), InitialModel, Init.
steps.go step enum — the ordered wizard stages.
update.go Update: global keys + per-step dispatch (handlers).
view.go View: header + per-step body + help footer (AltScreen).
form.go Generic FormStep/FormField component (text/password/number/select).
cmds.go Msg types and async tea.Cmd wrappers around docker/file ops.
docker.go os/exec wrappers around the `docker` binary.
config.go Generates & writes config.toml and envs (+ numeric validation).
styles.go Lip Gloss palette/styles.
Makefile Multi-arch build + S3 publish.
Architecture (Model–Update–View)
- Model (model.go) holds all state:
currentStep, progress/error flags, oneFormStepper form, andconfigValues(ConfigValues) which accumulates each form'smap[string]stringoutput by section. - Update (update.go) handles global messages
(
Ctrl+C, window size, spinner tick) then dispatches oncurrentStepto per-step handlers. Step transitions happen when a form returnsdone == trueor when an async completion message arrives. - View (view.go) renders per-step.
- Commands (cmds.go) wrap every blocking op (docker calls,
file writes) as a
tea.Cmdreturning aMsg:DockerCheckedMsg,ImageDownloadFinishedMsg,ConfigFileMsg,DockerRunMsg,TickMsg.
Wizard flow
steps.go defines the order. See docs/fluxo.md for full detail.
StepCheckDocker—exec.LookPath("docker"). Missing →StepDockerInstall(instructs manual install and exits; never auto-installs Docker).StepDockerLogin→StepDownloadImage—docker login+pullof the app image. These registry credentials are reused later for the vproxy image.StepIPQuestion— "public IP available?"- Yes → jump to
StepAppConfig. - No → vproxy block:
StepWireguardConfig→StepGenerateWireguardFile(writesenvs) →StepDownloadWireguard→StepRunWireguard.
- Yes → jump to
- Config forms:
StepAppConfig→StepServerConfig→StepDatabaseConfig→StepCertConfig. StepGenerateFile— writesconfig.toml(validates numeric fields first).StepRunDocker— runsapp-dono-clientecontainer.StepDone.
Key constants
In update.go:
imageName = hub.davinti.com.br:443/app-dono/app-cliente:latestwireguardImageName = hub.davinti.com.br:443/davinti-vproxy:latestconfigPath = config.toml,wireguardConfigPath = envs
In docker.go: networkName = app-dono_app (all containers
join this network; created on demand).
Generated files
config.toml— app config, bind-mounted at/app/config.toml. If present at startup it seeds form defaults vialoadConfig. Generated byGenerateConfigTOML.envs— vproxy/WireGuard env vars, passed via--env-file. Generated only when there is no public IP. ByGenerateWireguardConfig.
Both are gitignored.
Containers
| Container | Image | Notes |
|---|---|---|
app-dono-cliente |
app-cliente | <host port>:8080, mounts config.toml + cert dir, --restart unless-stopped, runs as host uid:gid. |
vproxy |
davinti-vproxy | --cap-add=NET_ADMIN, /dev/net/tun, --env-file envs, only without public IP. |
seccomp=unconfined is added to either container when the "Modo Compatibilidade"
(seccomp_unconfined) select is "Sim" — for old machines.
Gotchas (read before editing)
- Port:
config.tomlalways writesport = 8080(hardcoded inGenerateConfigTOML). The form's "Porta" value only sets the host-side port in thedocker runmapping (<port>:8080); inside the container the app always listens on 8080. - Network name is the
networkNameconstant (app-dono_app) in docker.go; use it rather than re-typing the literal. - Registry credentials are collected once (login form) and reused for the vproxy pull — no second prompt.
- Containers run detached and are verified with
docker inspectforrunning; on failure the last 20 log lines are surfaced.
Build & run
go run ./cmd # run from source
go build -o installer ./cmd # local binary
make build # multi-arch (linux/darwin/windows, amd64/arm64) → ./dist
make build VERSION=2.0.0
make clean
make push S3_BUCKET=<bucket> VERSION=<v> # sync dist/ to S3 (version + latest)
make release S3_BUCKET=<bucket> VERSION=<v> # per-binary copy with OS/arch naming
There is no test suite. Verify changes by running go build ./... and exercising the
TUI manually. Requires a working Docker daemon and registry access to fully run.
Conventions
- User-facing strings in the TUI are Portuguese (BR); keep new ones consistent.
- Keep code comments and identifiers matching the surrounding style (mixed English identifiers, Portuguese user messages).
- When adding a wizard step: add it to
steps.go, a handler inupdate.go, a render branch inview.go, and any newMsg/Cmdincmds.go.