Skip to content

Commit dc492ef

Browse files
committed
v26.5.0
v26.5.0 — Privacy & Recon module Opt-in OSINT scanner plus file-metadata hygiene toolkit, both running in a hardened container sandbox. AGPL-3.0-or-later, no runtime caps, no call-home. Full notes in CHANGELOG.md and docs/v26.5/release-notes.md.
1 parent 17621d7 commit dc492ef

842 files changed

Lines changed: 51093 additions & 100035 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.example

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,27 +32,20 @@ ENCRYPTION_KEY=CHANGE_ME_GENERATE_WITH_OPENSSL_RAND_HEX_32
3232
# usulnet image tag
3333
USULNET_VERSION=latest
3434

35-
# Operation mode: master | agent
36-
USULNET_MODE=master
35+
# Operation mode: standalone | master
36+
USULNET_MODE=standalone
3737

38-
# Exposed ports (usulnet app)
38+
# Exposed ports
3939
USULNET_HTTP_PORT=8080
4040
USULNET_HTTPS_PORT=7443
4141

42-
# Nginx reverse proxy ports
43-
NGINX_HTTP_PORT=80
44-
NGINX_HTTPS_PORT=443
45-
46-
# Nginx ACME email for Let's Encrypt certificates (required for SSL)
47-
# USULNET_NGINX_ACME_EMAIL=admin@example.com
48-
4942
# Database
5043
DB_USER=usulnet
5144
DB_NAME=usulnet
5245

5346
# Host terminal (web terminal into the Docker host via nsenter)
5447
HOST_TERMINAL_ENABLED=true
55-
HOST_TERMINAL_USER=nobody_usulnet
48+
HOST_TERMINAL_USER=nobody
5649

5750
# =============================================================================
5851
# Agent — Only needed with --profile agent

.github/copilot-instructions.md

Lines changed: 319 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
# GitHub Copilot Instructions for usulnet
2+
3+
## Project Overview
4+
5+
**usulnet** is a self-hosted Docker Management Platform written in **Go** — a single-binary alternative to Portainer. It provides container lifecycle management, security scanning, backup management, reverse proxy configuration, monitoring, multi-node orchestration, and developer tooling through a unified web UI.
6+
7+
- **Module path:** `github.com/fr4nsys/usulnet`
8+
- **Go version:** 1.25.7
9+
- **License:** AGPL-3.0-or-later
10+
- **Current release:** v26.2.0 Beta
11+
12+
## Architecture
13+
14+
### Operation Modes
15+
16+
The platform supports three operation modes:
17+
18+
1. **standalone** — Single Docker host. All services local. No NATS required.
19+
2. **master** — Standalone + NATS gateway server for remote agent management.
20+
3. **agent** — Connects to master via NATS. No web UI. Executes Docker operations on its local host.
21+
22+
### Entry Points
23+
24+
| Binary | Location | Framework | Purpose |
25+
|--------|----------|-----------|---------|
26+
| `usulnet` | `cmd/usulnet/` | Cobra CLI | Main server (`serve`, `migrate`, `config`, `admin`, `version`) |
27+
| `usulnet-agent` | `cmd/usulnet-agent/` | `flag` package | Remote node agent |
28+
29+
### Key Directories
30+
31+
- `cmd/` — Binary entry points (usulnet and usulnet-agent)
32+
- `internal/api/` — REST API layer with Chi router and middleware
33+
- `internal/services/` — Business logic layer (~39 service packages)
34+
- `internal/repository/postgres/` — PostgreSQL repositories with migrations
35+
- `internal/web/` — Web UI layer (server-side rendered with Templ)
36+
- `web/static/` — Static assets (CSS, JS, fonts)
37+
- `tests/` — Tests (unit, integration, e2e, benchmarks, load)
38+
39+
## Technology Stack
40+
41+
### Backend
42+
43+
- **Language:** Go 1.25.7
44+
- **HTTP Router:** go-chi/chi/v5
45+
- **Database:** PostgreSQL via pgx/v5 + sqlx
46+
- **Cache:** Redis (go-redis/v9)
47+
- **Messaging:** NATS with JetStream
48+
- **Docker:** Docker SDK v28.5.1
49+
- **Auth:** JWT (golang-jwt/jwt/v5), OIDC, LDAP
50+
- **Logging:** uber-go/zap with structured logging
51+
- **Config:** spf13/viper + spf13/cobra
52+
- **Validation:** go-playground/validator/v10
53+
54+
### Frontend
55+
56+
- **Templates:** Templ v0.3.977 (type-safe Go HTML templates)
57+
- **CSS:** Tailwind CSS v3.4.17 (standalone CLI, no Node.js)
58+
- **Reactivity:** Alpine.js 3.14.8
59+
- **Interactivity:** HTMX 2.0.4
60+
- **Charts:** Chart.js
61+
- **Terminal:** xterm.js (WebSocket-based)
62+
- **Code Editor:** Monaco Editor
63+
- **RDP:** Apache Guacamole
64+
- **Fonts:** IBM Plex Sans/Mono, Space Grotesk (self-hosted)
65+
66+
## Code Conventions
67+
68+
### File Naming
69+
70+
- `handler_<feature>.go` — Web page handlers
71+
- `adapter_<feature>.go` — Type adapters (service → web layer)
72+
- `routes_<area>.go` — Route registration
73+
- `*_templ.go` — Auto-generated from `.templ` files (DO NOT EDIT)
74+
- `*_test.go` — Test files
75+
76+
### Required Copyright Header
77+
78+
Every Go file must include this header:
79+
80+
```go
81+
// SPDX-License-Identifier: AGPL-3.0-or-later
82+
// Copyright (c) 2024-2026 usulnet contributors
83+
// https://github.com/fr4nsys/usulnet
84+
```
85+
86+
### Import Organization
87+
88+
Group imports in this order:
89+
1. Standard library
90+
2. Third-party packages
91+
3. Local packages (`github.com/fr4nsys/usulnet/...`)
92+
93+
Local imports use the module path prefix configured in `.golangci.yml` via goimports.
94+
95+
### Error Handling
96+
97+
- Always wrap errors with context: `fmt.Errorf("descriptive context: %w", err)`
98+
- Services return errors; handlers log and respond with structured JSON
99+
- Non-fatal failures are logged but don't block startup
100+
101+
### Logging
102+
103+
- Use **zap** via wrapper at `internal/pkg/logger`
104+
- Structured key-value pairs: `log.Info("message", "key", value, "key2", value2)`
105+
- Levels: debug, info, warn, error, fatal
106+
- JSON in production, console in development
107+
108+
### Service Architecture
109+
110+
- **Constructor injection:** `NewService(repo, deps..., config, logger)`
111+
- All services accept a `*logger.Logger`
112+
- Lifecycle methods: `Start(ctx)` / `Stop()` where applicable
113+
- **Nil-safe design:** handlers check if services are nil
114+
- **Repository pattern:** each domain has a repository in `internal/repository/postgres/`
115+
116+
### RBAC
117+
118+
Three role tiers enforced via Chi middleware:
119+
- `admin` — Full access (`RequireAdmin` middleware)
120+
- `operator` — Operational access (`RequireOperator` middleware)
121+
- `viewer` — Read-only (`RequireViewer` middleware)
122+
123+
## Build & Development
124+
125+
### Quick Commands
126+
127+
```bash
128+
# Build
129+
make build # Full build: templ + CSS + go build
130+
make build-agent # Build agent binary only
131+
make frontend # Generate templates + compile CSS
132+
133+
# Run
134+
make run # go run ./cmd/usulnet
135+
make dev-up # Start dev services (PostgreSQL, Redis, NATS, MinIO)
136+
make dev-down # Stop dev services
137+
138+
# Test
139+
make test # go test -v -race -cover ./...
140+
make test-coverage # Coverage with HTML report
141+
make test-e2e # E2E tests (requires services, build tag: e2e)
142+
143+
# Quality
144+
make lint # golangci-lint run ./...
145+
make lint-fix # Auto-fix linting issues
146+
make fmt # gofmt -s -w .
147+
make vet # go vet ./...
148+
make quality # Full quality gate (lint + vet + coverage check)
149+
150+
# Database
151+
make migrate # Run migrations up
152+
make migrate-down # Roll back migrations
153+
make migrate-status # Show migration status
154+
155+
# Hooks
156+
make install-hooks # Install pre-commit hook
157+
```
158+
159+
### Development Workflow
160+
161+
1. Start infrastructure: `make dev-up`
162+
2. Run server: `make run`
163+
3. Edit `.templ` files → `make templ` (or `make templ-watch`)
164+
4. Edit CSS → `make css` (or `make css-watch`)
165+
5. Run tests: `make test`
166+
6. Run linter: `make lint`
167+
7. Full check: `make quality`
168+
8. Build: `make build`
169+
170+
### Adding New Features
171+
172+
When adding a feature, follow this pattern:
173+
1. Add models in `internal/models/`
174+
2. Add repository in `internal/repository/postgres/` with migration
175+
3. Add service in `internal/services/<feature>/`
176+
4. Add API handlers in `internal/api/handlers/`
177+
5. Add web handlers in `internal/web/handler_<feature>.go`
178+
6. Register routes in `internal/web/routes_*.go` or `internal/api/router.go`
179+
7. Wire service in `internal/app/app.go`
180+
181+
## Database
182+
183+
### PostgreSQL
184+
185+
- Driver: `pgx/v5` + `sqlx`
186+
- 36 numbered migrations in `internal/repository/postgres/migrations/`
187+
- Naming: `NNN_description.{up,down}.sql`
188+
- Run: `make migrate` or `go run ./cmd/usulnet migrate up`
189+
- Status: `make migrate-status`
190+
191+
### Redis
192+
193+
- Session storage and JWT blacklisting
194+
- Client at `internal/repository/redis/`
195+
196+
## Configuration
197+
198+
- Loaded via **Viper** with `mapstructure` tags
199+
- Override with env vars: `USULNET_<KEY>_<NESTED_KEY>`
200+
- Main config: `config.yaml`
201+
- Agent config: `config.agent.yaml`
202+
203+
Key sections: `server`, `database`, `redis`, `nats`, `security`, `storage`, `trivy`, `docker`, `logging`, `metrics`, `observability`
204+
205+
## Testing
206+
207+
| Type | Command | Coverage |
208+
|------|---------|----------|
209+
| Unit/Integration | `make test` | 40% minimum |
210+
| Coverage report | `make test-coverage` | Outputs `coverage.html` |
211+
| Benchmarks | `make test-benchmark` | Router, JWT validation |
212+
| E2E | `make test-e2e` | Requires services |
213+
| Load | `tests/load/` | k6 script |
214+
215+
Test environment uses `docker-compose.test.yml` with offset ports.
216+
217+
## Linting
218+
219+
Uses **golangci-lint** with 15 linters (see `.golangci.yml`):
220+
221+
gosec, staticcheck, govet, errcheck, ineffassign, unused, gocritic, revive, gofmt, goimports, prealloc, nilerr, errorlint, misspell, unconvert, whitespace
222+
223+
**Exclusions:**
224+
- `*_templ.go` files fully excluded
225+
- Test files excluded from gosec, errcheck, gocritic, prealloc
226+
- `G101` (hardcoded credentials) excluded from gosec
227+
- `fieldalignment` and `shadow` disabled in govet
228+
229+
## Pre-commit Hook
230+
231+
Install: `make install-hooks`
232+
233+
Runs:
234+
1. `gofmt` check (excludes `_templ.go`)
235+
2. `go vet ./...`
236+
3. `go test -short -count=1 ./...`
237+
4. `golangci-lint run --fast ./...` (if installed)
238+
239+
## Docker
240+
241+
### Development
242+
243+
```bash
244+
make dev-up # Start PostgreSQL, Redis, NATS, MinIO
245+
make run # Run server locally
246+
make dev-down # Stop services
247+
```
248+
249+
### Production Build
250+
251+
3-stage multi-stage Dockerfile:
252+
1. golang:1.25.7-alpine — Templ CLI, generate templates, build binary
253+
2. alpine:3.21 — Download Tailwind CLI, compile CSS
254+
3. alpine:3.21 — Runtime (docker-cli, trivy, neovim, ripgrep, non-root user)
255+
256+
Ports: **8080** (HTTP), **7443** (HTTPS with self-signed TLS)
257+
258+
## Best Practices
259+
260+
### Code Quality
261+
262+
- **Fix bugs when found** — Don't defer unless it requires multi-day work
263+
- **Choose correct fix over quick fix** — Avoid technical debt
264+
- **Never assume, always verify** — Read code, check behavior
265+
- **Document with file:line references** — Context for future sessions
266+
- **Use existing libraries** — Only add new deps if absolutely necessary
267+
268+
### Testing
269+
270+
- Write tests that match existing patterns
271+
- Use table-driven tests for multiple scenarios
272+
- Mock external dependencies (Docker, NATS, etc.)
273+
- Test error paths, not just happy paths
274+
- E2E tests require build tag: `e2e`
275+
276+
### Comments
277+
278+
- Don't add comments unless they match file style or explain complex logic
279+
- Code should be self-documenting where possible
280+
- Use structured logging for runtime information
281+
282+
### Tools
283+
284+
- Prefer Makefile targets over direct tool calls
285+
- Use ecosystem tools (npm init, pip install) to automate
286+
- Use refactoring tools for automated changes
287+
- Run linters to fix style issues
288+
289+
## Security
290+
291+
- No hardcoded secrets in source code
292+
- Use AES-256-GCM for encryption (`internal/pkg/crypto`)
293+
- Password hashing via bcrypt
294+
- JWT with blacklisting support
295+
- TOTP 2FA support (`internal/pkg/totp`)
296+
- Input validation via `go-playground/validator`
297+
298+
## Key Dependencies
299+
300+
| Category | Package |
301+
|----------|---------|
302+
| HTTP | go-chi/chi/v5 |
303+
| Templates | a-h/templ |
304+
| Database | jackc/pgx/v5, jmoiron/sqlx |
305+
| Redis | redis/go-redis/v9 |
306+
| Messaging | nats-io/nats.go |
307+
| Docker | docker/docker v28.5.1 |
308+
| Auth | golang-jwt/jwt/v5, coreos/go-oidc/v3, go-ldap/ldap/v3 |
309+
| Logging | uber-go/zap |
310+
| Config | spf13/viper, spf13/cobra |
311+
| Observability | OpenTelemetry |
312+
313+
## Additional Resources
314+
315+
- Full guide: `CLAUDE.md` (comprehensive AI assistant instructions)
316+
- Architecture: `docs/architecture.md`
317+
- Development: `docs/development.md`
318+
- API docs: `docs/api.md`
319+
- Agent docs: `AGENT_DEVELOPMENT.md`

0 commit comments

Comments
 (0)