mirror of
https://github.com/Dvorinka/Containr.git
synced 2026-10-28 07:41:27 +00:00
feat(services): multi-domain, DNS check, maintenance + basic-auth gates (C2)
service_domains table holds the full hostname set; services.domain stays
the derived default and is synced on every domain write. Runtime spec
carries all domains into a multi-Host Traefik rule plus access gates.
- GET|POST /services/:id/domains, DELETE + POST /:domain_id/default
- GET /services/:id/domains/check — DNS preflight vs public_ip/base_url
(ok | wrong-target | pending), stamps last_checked_at
- maintenance_mode → Traefik redirectregex to /api/v1/maintenance
(base_url/BASE_URL setting; falls back to noop@internal offline)
- basic_auth [{username,password}] → bcrypt htpasswd on the label;
responses return usernames only
- First domain auto-defaults; domain="" via PUT clears all domains
- CLI: services domains list|add|remove|default|check, update
--maintenance/--basic-auth; MCP: 5 domain tools + update args
- Settings UI: Domains card (CRUD + DNS check badges) + Access card
- Fixes latent C1 bug: PUT without volumes 500'd — nil []byte sent as
bytea, not NULL; COALESCE needs untyped nil + ::jsonb cast
Verified live: domain CRUD + default sync, pending/wrong-target checks,
bcrypt htpasswd and both middlewares on the deployed container's labels.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
2f8f595d6e
commit
e995c98d05
19 files changed
+1565
-42
No files matched your search
@@ -38,6 +38,7 @@ auth login|logout|status token auth and profiles
|
||||
tokens list|create|revoke personal access tokens
|
||||
projects list|get|create|delete
|
||||
services list|get|create|update|delete|start|stop|restart|redeploy
|
||||
services domains list|add|remove|default|check multi-domain + DNS preflight
|
||||
volumes list|delete docker volume inventory + cleanup (admin)
|
||||
deploy <service-id> trigger a deployment (--no-cache, --commit-hash, --branch)
|
||||
deployments list|get|logs|rollback|cancel
|
||||
@@ -87,6 +88,33 @@ redeploy — `containr deploy <id>` to apply immediately.
|
||||
`volumes list` shows the node's docker volume inventory with in-use
|
||||
flags; `volumes delete <name>` removes an unused volume (admin scope).
|
||||
|
||||
## Service domains and access
|
||||
|
||||
A service can carry multiple hostnames; the default is mirrored to
|
||||
`services.domain`:
|
||||
|
||||
```bash
|
||||
containr services domains add <id> app.example.com --default
|
||||
containr services domains check <id> # DNS preflight per domain
|
||||
containr services domains remove <id> <domain-id>
|
||||
```
|
||||
|
||||
DNS check compares each domain to the expected target — set
|
||||
`app_settings.public_ip` (or `PUBLIC_IP` env) so `wrong-target` is
|
||||
meaningful; without it any resolvable domain reports `ok`.
|
||||
|
||||
Access gates apply via Traefik middlewares (no extra proxy):
|
||||
|
||||
```bash
|
||||
containr services update <id> --maintenance on
|
||||
containr services update <id> --basic-auth admin:secret --basic-auth ops:pw2
|
||||
```
|
||||
|
||||
Maintenance mode redirects all traffic to `<BASE_URL>/api/v1/maintenance`
|
||||
— set `app_settings.base_url` or `BASE_URL`; without it the service is
|
||||
taken offline with empty responses. Basic-auth credentials are stored
|
||||
bcrypt-hashed (htpasswd) and gate every request.
|
||||
|
||||
## MCP server
|
||||
|
||||
`containr-mcp` (`go build ./cmd/mcp`) exposes the same API as MCP tools
|
||||
|
||||
Reference in new issue
Block a user