DatabasesEverywhere configuration
Configure node identity, API exposure, allowed database images, host safety reserves, quota enforcement, storage paths, and backup policy before accepting customer instances.
Identity and secrets
The main configuration starts with values generated and stored by the panel:
remote: https://panel.example.com
uuid: node-db-1
token_id: node-db-1-primary
token: replace-with-at-least-32-random-bytes
jwt_signing_key: replace-with-a-different-32-byte-random-keytoken authenticates panel API requests. jwt_signing_key signs WebSocket and temporary-download credentials. Each secret must contain at least 32 random bytes, must be different, and must never be committed.
The configuration administration API cannot change uuid, token_id, token, jwt_signing_key, or the external FuseQuota helper path and digest. Change those boundaries directly on the host.
API listener and trusted hosts
Keep the API on loopback when a local reverse proxy terminates HTTPS:
api:
host: 127.0.0.1
port: 8090
trusted_hosts:
- node-api.example.comThe request Host must match remote, a concrete api.host, or an entry in api.trusted_hosts. If a browser sends an Origin, it is checked separately against the allow-list derived from remote.
To expose the native HTTPS server directly, use a non-loopback host and enable TLS:
api:
host: 0.0.0.0
port: 8443
ssl:
enabled: true
certificate: /etc/letsencrypt/live/node.example.com/fullchain.pem
key: /etc/letsencrypt/live/node.example.com/privkey.pemCleartext non-loopback API binds are rejected. Database gateways can bind publicly without TLS, but they log a warning because credentials, queries, and results can be intercepted. Enable each gateway's native TLS whenever traffic crosses an untrusted network.
Container runtime
Docker is the default:
daemon:
engine: docker
socket_path: /var/run/docker.sockPodman can use /run/podman/podman.sock for rootful operation or /run/user/<uid>/podman/podman.sock for rootless operation. Do not switch an occupied node between runtimes.
Database networking is intentionally not configurable. Every instance uses network_mode=none and a private Unix socket.
Database images
Use explicit version tags or digests. Bare image references and latest are rejected:
images:
postgres: "postgres:18.4"
redis: "redis:8.8.0"
mariadb: "mariadb:12.3.2"
mysql: "mysql:8.4"
mongodb: "mongo:8.3.4"
clickhouse: "clickhouse/clickhouse-server:26.4.4.38"
qdrant: "qdrant/qdrant:v1.18.2"
allowed:
postgres: ["postgres:18.4"]
redis: ["redis:8.8.0"]
mariadb: ["mariadb:12.3.2"]
mysql: ["mysql:8.4"]
mongodb: ["mongo:8.3.4", "mongo:7.0.37"]
clickhouse: ["clickhouse/clickhouse-server:26.4.4.38"]
qdrant: ["qdrant/qdrant:v1.18.2"]The configured default is always implicitly allowed. Keep every additional allow-list entry reviewed and administrator-controlled.
MySQL uses the official mysql:8.4 LTS image because the credential gateway depends on a compatibility authentication plugin removed from MySQL 9.x.
MongoDB 8.x has a known incompatibility with Linux kernel 6.19 and newer. If MongoDB fails on such a host, select the known-compatible mongo:7.0.37 image for MongoDB only.
Capacity reserves
Keep memory and disk headroom outside the database allocation pool:
allocation:
max_memory_mib: null
max_disk_mib: null
reserved_memory_mib: 512
reserved_disk_mib: 2048When a maximum is null, DatabasesEverywhere uses detected physical capacity minus the reserve. An explicit maximum can shrink the pool but cannot override the reserve.
New instances and memory or disk increases are rejected if projected allocations exceed the pool or current host availability would fall inside the reserve. Decreases are always allowed. Stopped and failed instances remain allocated until deletion.
CPU is a scheduling signal and per-instance runtime limit, but not a node admission reserve because CPU contention slows workloads without making the host unbootable.
Disk enforcement
Disk mode is detected on every daemon boot from the filesystem backing paths.volumes:
- Btrfs uses qgroups.
- ZFS uses refquotas.
- Project-quota-enabled XFS, ext4, and f2fs use native project quotas.
- Other supported filesystems use FuseQuota.
There is no manual disk.mode switch and no unenforced fallback.
Use the disk section to configure the bundled helper and native project ID range:
disk:
fuse_quota_binary: embedded
fuse_quota_binary_sha256: ""
fuse_quota_rescan_interval_seconds: 150
project_id_base: 200000Reserve a bounded range of up to 1,000,000 consecutive project IDs starting at project_id_base exclusively for DatabasesEverywhere. XFS mode rejects conflicting /etc/projects or /etc/projid entries instead of replacing them.
Official release binaries contain the matching verified FuseQuota helper. A source build for another architecture must point to a trusted, root-owned helper and provide its lowercase SHA-256 digest.
The systemd unit uses KillMode=process so healthy FuseQuota helpers and mounts can survive a normal daemon restart. After a host reboot or stale helper, the daemon repairs only the affected instance.
Storage paths
The recommended layout is:
paths:
data: /var/lib/dbev
metadata: /var/lib/dbev/metadata
volumes: /var/lib/dbev/volumes
backups: /var/lib/dbev/backups
sockets: /run/dbev/sockets
locks: /run/dbev/locks
logs: /var/log/dbev
artifacts: /var/lib/dbev/artifacts
exports: /var/lib/dbev/artifacts/exports
imports: /var/lib/dbev/artifacts/imports
fuse: /var/lib/dbev/fuse
tmp: /var/lib/dbev/tmpEvery existing ancestor is checked before creation and after hardening. It must be a real directory, be owned by root or the daemon user, and not be writable by group or others. A root-owned sticky directory such as /tmp is allowed.
The daemon and mutating maintenance commands share an exclusive lock under paths.locks. Stop the service before migrations, metadata resets, or development cleanup.
Move an existing path layout
Stop managed containers and the service before migrating:
sudo systemctl stop databases-everywhere
sudo dbev migrate-paths --dry-run
sudo dbev migrate-paths
sudo systemctl start databases-everywheresudo dbev --move-new-config is an alias. Live data is not moved unless the operator explicitly adds --force.
Automatic backups
Enable a daily schedule, per-instance retention, and bounded catalog previews:
backups:
enabled: true
interval_minutes: 1440
run_on_startup: false
retention_keep_latest_per_instance: 7
retention_max_age_days: 30
storage:
driver: local
browsing:
enabled: true
max_objects: 256
max_preview_objects: 32
preview_rows_per_object: 10
max_row_bytes: 4096
max_catalog_bytes: 1048576The storage driver can be local, s3, or kopia. Retention is applied per instance through the selected driver. Changing the driver selects a different inventory and does not migrate previous backups.
Row previews contain database content and need the same encryption and access policy as the backup. Set preview_rows_per_object: 0 to keep schema browsing without captured rows.
See Data operations and backups for S3, Kopia, restore, and temporary-download flows.
Apply and verify changes
Validate the file before restarting:
sudo dbev --config /etc/databases-everywhere/config.yml check-config
sudo dbev --setup
sudo systemctl restart databases-everywhereMost listener, TLS, path, image, and runtime changes require a restart. PATCH /api/system/config writes a merged configuration patch but returns restart_required: true rather than restarting the node automatically.