Files
nuc/docs/cloudbeaver-database-manager.md
Alejandro Gutiérrez 8b503a549c Add operational documentation
CloudBeaver database manager guide, Ecija intranet deployment,
Gitea-Coolify auto-deploy and integration docs, monitoring setup
with presentation, remote access guide, security architecture,
and Turbostarter deployment procedure.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:17:18 +01:00

249 lines
8.4 KiB
Markdown

# CloudBeaver Database Manager
**Date:** 2026-02-03
**Context:** Centralized database management UI for all NUC databases
## Summary
CloudBeaver CE (v24) provides a web-based SQL client connected to all databases on the NUC server. Instead of auto-discovery (which CloudBeaver CE doesn't support), all 9 database connections are pre-configured via `data-sources.json` and the container is connected to every relevant Docker network for direct container-to-container access.
## Access
| Property | Value |
|----------|-------|
| **URL** | `http://192.168.1.3:8978` |
| **Admin User** | `cbadmin` |
| **Admin Password** | `CloudBeaver2026!` |
| **Coolify UUID** | `joo4g4k0w08k8kcosgsgswc0` |
## Connected Databases
### Coolify Standalone DBs
| Connection | Type | Host (Container) | Database | User |
|------------|------|-------------------|----------|------|
| WhyRating Hub | PostgreSQL | `i8skkc8cwsgwgsg0g8kcw44k` | whyrating | whyrating |
| Turbostarter | PostgreSQL | `db-v4gogwwc8wkk4888ksscc4k4` | core | turbostarter |
| LiquidGym (MySQL) | MySQL 8 | `hgwcgs4oswwc8scg080scoo4` | liquidgym | liquidgym |
### Service Embedded DBs
| Connection | Type | Host (Container) | Database | User |
|------------|------|-------------------|----------|------|
| Outline | PostgreSQL | `postgres-pccg80wks4c084008owokkkg` | outline | HVubx2MKadO9V4JU |
| Google Scraper | PostgreSQL | `postgres-g4s8w4csk8s8ocswg48kkogo` | scraper | scraper |
| LiquidGym (Postgres) | PostgreSQL | `postgres-x4kk8g4k8w4g0cw480w84g4g` | postgres | postgres |
| Knosia | PostgreSQL | `postgres-ik80skko0008w4000c4w40os` | knosia | knosia |
| Authentik | PostgreSQL | `postgresql-e8owcw0s4wcswc4w4css0sws` | authentik | yth9ADhCXAsYytvI |
### Infrastructure
| Connection | Type | Host (Container) | Database | User | Access |
|------------|------|-------------------|----------|------|--------|
| Coolify DB | PostgreSQL | `coolify-db` | coolify | coolify | Read-only |
## Architecture
### How It Works
```
CloudBeaver Container
├── Network: coolify → coolify-db
├── Network: pccg80... → postgres-pccg80... (Outline)
├── Network: e8owcw... → postgresql-e8owcw... (Authentik)
├── Network: g4s8w4... → postgres-g4s8w4... (Google Scraper)
├── Network: x4kk8g... → postgres-x4kk8g... (LiquidGym PG + MySQL)
├── Network: ik80sk... → postgres-ik80sk... (Knosia)
├── Network: v4gogw... → db-v4gogw... (Turbostarter)
└── Volume: cloudbeaver-data → /opt/cloudbeaver/workspace (persistent)
```
CloudBeaver connects directly to database containers via Docker network DNS. No port forwarding or host networking needed — container names resolve within shared networks.
### Why Not Auto-Discovery?
CloudBeaver CE has no native auto-discovery. A Docker API-based script was considered but rejected due to:
- **Credential mismatch:** No reliable way to get DB passwords from Docker
- **Container name churn:** Coolify uses random UUIDs for container names
- **False positives:** Not all containers with port 5432 are accessible DBs
Pre-configured `data-sources.json` is more reliable and predictable.
## Coolify Compose
```yaml
services:
cloudbeaver:
image: 'dbeaver/cloudbeaver:24'
volumes:
- 'cloudbeaver-data:/opt/cloudbeaver/workspace'
ports:
- '8978:8978'
environment:
- SERVICE_URL_CLOUDBEAVER_8978
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:8978"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
networks:
- default
- coolify
- outline-net
- authentik-net
- scraper-net
- liquidgym-pg-net
- knosia-net
- turbostarter-net
networks:
coolify:
external: true
name: coolify
outline-net:
external: true
name: pccg80wks4c084008owokkkg
authentik-net:
external: true
name: e8owcw0s4wcswc4w4css0sws
scraper-net:
external: true
name: g4s8w4csk8s8ocswg48kkogo
liquidgym-pg-net:
external: true
name: x4kk8g4k8w4g0cw480w84g4g
knosia-net:
external: true
name: ik80skko0008w4000c4w40os
turbostarter-net:
external: true
name: v4gogwwc8wkk4888ksscc4k4
```
## Configuration Files
| File | Location | Purpose |
|------|----------|---------|
| **data-sources.json** | `/opt/cloudbeaver/workspace/GlobalConfiguration/.dbeaver/data-sources.json` | Connection definitions (host, port, db, driver) |
| **initial-data-sources.conf** | `/opt/cloudbeaver/conf/initial-data-sources.conf` | Backup copy for fresh container init |
| **Credentials** | Internal H2 database at `/opt/cloudbeaver/workspace/.data/cb.h2v2.dat` | Encrypted password storage |
## Adding a New Database
### 1. Find the database's Docker network
```bash
ssh nuc "docker inspect <db-container> --format '{{json .NetworkSettings.Networks}}' | jq -r 'keys[]'"
```
### 2. Add network to Coolify compose
Add a new entry under both `services.cloudbeaver.networks` and `networks`:
```yaml
services:
cloudbeaver:
networks:
- new-db-net # Add this
networks:
new-db-net: # Add this
external: true
name: <network-id-from-step-1>
```
Update via Coolify MCP:
```python
mcp__coolify__service(action="update", uuid="joo4g4k0w08k8kcosgsgswc0", docker_compose_raw="<updated yaml>")
```
### 3. Add connection to data-sources.json
```bash
ssh nuc "docker exec cloudbeaver-joo4g4k0w08k8kcosgsgswc0 cat /opt/cloudbeaver/workspace/GlobalConfiguration/.dbeaver/data-sources.json"
# Edit and write back the updated JSON with the new connection entry
```
Connection entry format:
```json
{
"new-db-id": {
"provider": "postgresql",
"driver": "postgres-jdbc",
"name": "Display Name",
"save-password": true,
"folder": "coolify-standalone",
"configuration": {
"host": "<container-name>",
"port": "5432",
"database": "<db-name>",
"url": "jdbc:postgresql://<container-name>:5432/<db-name>",
"configurationType": "MANUAL",
"type": "dev",
"auth-model": "native"
}
}
}
```
### 4. Redeploy and set credentials
```python
# Redeploy to pick up network changes
mcp__coolify__deploy(tag_or_uuid="joo4g4k0w08k8kcosgsgswc0")
```
Then set credentials via the CloudBeaver UI (log in, click the connection, enter username/password, check "Save credentials").
Or via GraphQL API:
```bash
# Authenticate first
curl -s http://192.168.1.3:8978/api/gql -H 'Content-Type: application/json' \
-c /tmp/cb-cookies \
-d '{"query":"mutation { authLogin(provider:\"local\", credentials:{user:\"cbadmin\",password:\"CloudBeaver2026!\"}) { authId } }"}'
# Initialize connection with credentials
curl -s http://192.168.1.3:8978/api/gql -H 'Content-Type: application/json' \
-b /tmp/cb-cookies \
-d '{"query":"mutation { initConnection(id:\"new-db-id\", credentials:{userName:\"user\",userPassword:\"pass\"}, saveCredentials:true) { id name connected } }"}'
```
## Troubleshooting
### Connection shows "Not connected"
1. **Check container exists:**
```bash
ssh nuc "docker ps | grep <container-name>"
```
2. **Check network connectivity:**
```bash
ssh nuc "docker exec cloudbeaver-joo4g4k0w08k8kcosgsgswc0 ping -c1 <container-name>"
```
3. **Check credentials are saved:** Log into CloudBeaver UI, click the connection, verify username/password fields are filled.
### MySQL "Public Key Retrieval not allowed"
MySQL 8 requires `allowPublicKeyRetrieval: true` in JDBC properties. Set via CloudBeaver UI: Connection → Driver Properties → Add `allowPublicKeyRetrieval` = `true`.
### "admin" username reserved
CloudBeaver CE reserves `admin` as a team name. Use a different admin username (we use `cbadmin`).
### Server shows "configuration expired"
This happens when CloudBeaver's initial setup wizard hasn't been completed. Access the UI at `http://192.168.1.3:8978` and complete the 3-step wizard (Welcome → Server Config → Confirm).
### Connections lost after redeploy
Connection definitions persist in `data-sources.json` on the volume. However, **credentials are stored in the H2 database** (`cb.h2v2.dat`). Both are on the `cloudbeaver-data` volume and survive normal redeploys. If the volume is deleted, connections will reload from `data-sources.json` but credentials will need to be re-entered.
## Related
- **Coolify Dashboard:** `http://192.168.1.3:8000`
- **Adminer (lightweight alternative):** `http://192.168.1.3:8088`
- **NocoDB (spreadsheet-style):** `http://192.168.1.3:8084`
- **CloudBeaver Docs:** https://dbeaver.com/docs/cloudbeaver/