Browse the Frappe Database from Your Laptop in 60 Seconds
Connect your local SQL client (DBeaver, DataGrip, TablePlus, mysql CLI) to the production Frappe MariaDB without changing anything on the server and without exposing port 3306 to the internet.
Why this is safe
- MariaDB stays bound to Docker's internal bridge — never reachable from the public internet.
- The SSH tunnel binds to
127.0.0.1on your Mac only — other devices on your LAN cannot reach it. - All traffic is encrypted inside the SSH session.
- No server-side config edits, no firewall holes. Closing the SSH session removes the forward.
Prerequisites
- SSH access to the server (key-based).
- The Frappe stack already running with the
frappe-marley-health-db-1container.
Step 1 — Open the tunnel
Replace the two placeholders, then run:
SERVER=root@<SERVER_IP>
KEY=~/path/to/your-ssh-key.pem
# Discover the DB container's IP on the server's docker network
DB_IP=$(ssh -i "$KEY" "$SERVER" \
"docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' frappe-marley-health-db-1")
echo "Container IP: $DB_IP"
# Forward localhost:3307 → container:3306 over SSH
ssh -i "$KEY" -N -L 127.0.0.1:3307:${DB_IP}:3306 "$SERVER"
Leave that terminal open. Add -f after -N to background it.
To stop the tunnel later:
pkill -f 'ssh.*3307:'
Step 2 — Find the Frappe site database name
Frappe creates a randomly-named site database (e.g. _5e5899d8398b5f7b). Read it from the canonical source:
ssh -i "$KEY" "$SERVER" \
"docker exec frappe-marley-health-backend-1 cat sites/frontend/site_config.json" \
| jq '{db_name, db_password}'
Or, with the tunnel already open, list databases directly:
mysql -h 127.0.0.1 -P 3307 -uroot -padmin -e "SHOW DATABASES;"
Step 3 — Connect from your SQL client
| Field | Value |
|---|---|
| Host | 127.0.0.1 |
| Port | 3307 |
| Username | root |
| Password | admin |
| Database | _xxxxxxxxxxxxxxxx (from step 2) |
| Driver | MariaDB (or MySQL 5.7+) |
CLI
mysql -h 127.0.0.1 -P 3307 -uroot -padmin <SITE_DB_NAME>
DBeaver / DataGrip / TablePlus
- New connection → MariaDB.
- Host
127.0.0.1, Port3307. - User
root, Passwordadmin. - Database = the
_xxxxxxxxname from step 2. - Test → Connect.
Per-site (least-privilege) credentials
For routine reads, prefer the per-site user instead of root. Both are inside site_config.json:
{
"db_name": "_5e5899d8398b5f7b",
"db_password": "xxxxxxxxxxxxxxxx"
}
Use db_name as both the username and the database name when connecting.
Troubleshooting
| Symptom | Fix |
|---|---|
bind: Address already in use | Another tunnel is open. pkill -f 'ssh.*3307:' and retry. |
DB_IP is empty | Container not running. ssh "$SERVER" docker ps | grep frappe. |
Access denied for user 'root' | Wrong password. Check DB_ROOT_PASSWORD in the server's .env. |
Client connects but SHOW DATABASES is empty | You're hitting the wrong container. Verify DB_IP belongs to frappe-marley-health-db-1. |