Skip to main content
Version: 1.8 (latest)

SSH Tunnel

Connect to databases that aren't directly reachable from Databasement: in private networks, behind a bastion/jump host, or on a remote Docker host whose database ports aren't published.

How it works

Databasement runs ssh -N -L <localPort>:<host>:<port> before each backup or restore and closes it afterward. SSH credentials are encrypted at rest.

No database tools needed on the SSH host

The dump and restore tools (mariadb-dump, pg_dump, mongodump, and so on) run inside the Databasement container and are NOT NEEDED on the SSH host.

Configuration​

Enable SSH Tunnel on the database server and point it at the SSH host:

FieldDescription
SSH HostSSH server hostname or IP (bastion, jump host, or remote Docker host)
SSH PortSSH port (default: 22)
SSH UsernameSSH user
Auth TypePassword or Private Key (with optional passphrase)
Enable compressionAdds -C to the tunnel, trading CPU on both ends for bandwidth. Off by default; worth enabling on slow links

Reusing an SSH configuration​

Once you've saved an SSH config, the form offers Use existing (pick a saved config) or Set up a new SSH config. Reusing one lets several database servers share the same host connection — update it once and every server that references it follows.

Generating an SSH key​

With Auth Type set to Private Key, the form can Generate a new Ed25519 keypair for you. Copy the displayed public key into ~/.ssh/authorized_keys on the SSH server before saving — it's shown only once and the public key isn't stored.

Creating an SSH configuration via the API​

SSH configurations are also a REST resource, so a whole tunnel-backed server can be provisioned without touching the UI. POST /api/v1/database-server-ssh-configs returns the new config's id, ready to pass as ssh_config_id when creating the database server:

curl -X POST https://databasement.example.com/api/v1/database-server-ssh-configs \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"host": "bastion.example.com",
"port": 22,
"username": "databasement",
"auth_type": "key",
"generate_key": true
}'

With generate_key, the keypair is generated server-side and the public key comes back in the response — copy it into authorized_keys on the SSH host. As in the UI, it is returned only once and never stored. Omit generate_key to send your own private_key (and optional key_passphrase), or use "auth_type": "password" with a password.

compression is accepted here too, and defaults to false when omitted.

Credentials are write-only: GET, PUT and the list endpoint never return them, and omitting them on PUT keeps the stored ones. A configuration still attached to a database server cannot be deleted. See REST API for the full reference.

Backing up databases on a remote host​

When databases run in Docker containers on a remote machine with ports only on an internal network, the tunnel reuses the same SSH access you already use to manage that host — no separate agent is needed, and the database stays private.

Publish the database port to the host's loopback, so it's reachable from the host but not from the network:

services:
db:
image: postgres:16
ports:
- "127.0.0.1:5432:5432"

Set the database Host to 127.0.0.1 and Port to 5432. Loopback is exactly where the tunnel terminates, so Databasement can reach the database while the network cannot.

Optional: SSH server in the stack​

If the host doesn't expose SSH — or you'd rather not publish the database port at all — add a small SSH server to the same Compose project. Only the SSH port is published; Databasement reaches the database by its service name over the project's default network.

services:
db:
image: postgres:18

sshd:
image: lscr.io/linuxserver/openssh-server
environment:
USER_NAME: databasement
PUBLIC_KEY: "ssh-ed25519 AAAA... databasement-tunnel"
DOCKER_MODS: linuxserver/mods:openssh-server-ssh-tunnel
ports:
- "2222:2222" # only SSH is published — not the database

Point the SSH Tunnel at the host on port 2222, then set the database Host to db and Port to 5432 — the service name resolves on the project's default network.

For same-host containers sharing a Docker network (no SSH), see Docker Networking instead.

Security​

Keep the database private

What matters most is that the database is not reachable from the public internet: either because its host is on a private network, or because you bound the port to loopback (127.0.0.1:5432:5432).

Optionally, restrict the SSH key to forwarding only in authorized_keys:

restrict,port-forwarding ssh-ed25519 AAAA... databasement-tunnel