Deploy Gel (formerly EdgeDB) on a RamNode VPS
A complete self-hosting guide for Gel 6 — the graph-relational database on top of PostgreSQL with EdgeQL and full SQL support. The canonical migration target for former Gel Cloud users.
At a Glance
| Project | Gel 6 (formerly EdgeDB) |
| License | Apache 2.0 |
| Recommended Plan | RamNode Cloud VPS 4 GB+ for production |
| OS | Ubuntu 22.04 / 24.04 LTS |
| Default Port | 5656 (EdgeQL + Postgres wire) |
| Estimated Setup Time | 25–40 minutes |
About the Rebrand & Cloud Shutdown
EdgeDB was renamed Gel in February 2025. In December 2025, Gel Data Inc. joined Vercel and Gel Cloud was shut down on January 31, 2026. The engine remains open source, packages.geldata.com still serves releases, and bare-metal self-hosting is the recommended migration target — which is exactly what this guide covers.
Provision and Harden Your RamNode VPS
apt-get update && apt-get upgrade -y
apt-get install -y curl gnupg ca-certificates ufw fail2ban
adduser deploy
usermod -aG sudo deployCopy your SSH key to the new user, then in /etc/ssh/sshd_config set PermitRootLogin no and PasswordAuthentication no. Restart SSH and verify deploy login from a second terminal before closing root.
ufw default deny incoming
ufw default allow outgoing
ufw allow OpenSSH
ufw enable
systemctl enable --now fail2banAdd the Gel Package Repository
sudo mkdir -p /usr/local/share/keyrings
sudo curl --proto '=https' --tlsv1.2 -sSf \
-o /usr/local/share/keyrings/gel-keyring.gpg \
https://packages.geldata.com/keys/gel-keyring.gpgecho "deb [signed-by=/usr/local/share/keyrings/gel-keyring.gpg] \
https://packages.geldata.com/apt \
$(grep VERSION_CODENAME= /etc/os-release | cut -d= -f2) main" \
| sudo tee /etc/apt/sources.list.d/gel.list
sudo apt-get update
sudo apt-get install -y gel-6The package installs the gel-server-6 binary, a gel system user, the data directory at /var/lib/gel/6/data, and a disabled systemd unit gel-server-6.service. The Gel CLI is bundled.
RHEL/Alma/Rocky: drop https://packages.geldata.com/rpm/gel-rhel.repo into /etc/yum.repos.d/ then yum install gel-6. SELinux must be permissive or disabled.
Configure the systemd Unit
sudo systemctl edit --full gel-server-6[Service]
Environment="GEL_SERVER_TLS_CERT_MODE=generate_self_signed"
Environment="GEL_SERVER_ADMIN_UI=enabled"
Environment="GEL_SERVER_INSTANCE_NAME=ramnode_prod"sudo systemctl enable --now gel-server-6
systemctl status gel-server-6First start bootstraps Gel's embedded Postgres cluster. The data dir contains the cluster, the generated edbtlscert.pem, and runtime state. Do not remove User=gel from the unit — Gel refuses to run as root.
Set the Admin Password
The initial password can only be set from the privileged local Unix socket:
read -s -p "New admin password: " PASSWORD; echo
RUNSTATE_DIR=$(systemctl show gel-server-6 -P ExecStart \
| grep -o -m 1 -- "--runstate-dir=[^ ]\+" \
| awk -F "=" '{print $2}')
sudo gel --port 5656 --tls-security insecure --admin \
--unix-path "$RUNSTATE_DIR" \
query "ALTER ROLE admin SET password := '$PASSWORD'"Open Up Network Listening
Default is loopback only. To bind to a private network or all interfaces:
gel --port 5656 --tls-security insecure --password \
query "CONFIGURE INSTANCE SET listen_addresses := {'0.0.0.0'};"
sudo systemctl restart gel-server-6
sudo ufw allow from YOUR_APP_SERVER_IP to any port 5656 proto tcpRestrict source IPs in ufw whenever possible. Never expose 5656 publicly without TLS plus the admin password.
Capture the TLS Certificate for Clients
sudo cat /var/lib/gel/6/data/edbtlscert.pemexport GEL_DSN="gel://admin:YOUR_PASSWORD@gel.example.com:5656"
export GEL_TLS_CA_FILE="/etc/ssl/gel/edbtlscert.pem"All official client libs (TypeScript, Python, Go, Rust, Java, Elixir) read these env vars automatically. For Let's Encrypt certs, point GEL_SERVER_TLS_CERT_FILE and GEL_SERVER_TLS_KEY_FILE at fullchain.pem and privkey.pem and skip the CA file entirely.
Connecting From Your Application
gel instance link \
--dsn "$GEL_DSN" \
--trust-tls-cert \
--non-interactive \
ramnode_prodimport gel
client = gel.create_client() # reads GEL_DSN and GEL_TLS_CA_FILE
result = client.query("SELECT 1 + 1;")
print(result)Gel 6 also exposes the Postgres wire protocol on the same port — connect with psql, asyncpg, pgx, Drizzle, Prisma, or SQLAlchemy by switching the DSN to postgres://.
Backups With gel dump
gel --dsn "$GEL_DSN" --tls-ca-file /etc/ssl/gel/edbtlscert.pem \
dump --all --format dir /backups/gel/$(date +%Y%m%d-%H%M)gel --dsn "$NEW_DSN" restore --all /backups/gel/20260101-03000 3 * * * /usr/local/bin/gel-backup.shHave gel-backup.sh run the dump then prune with find /backups/gel -mindepth 1 -maxdepth 1 -mtime +30 -exec rm -rf \;. Logical dumps survive version upgrades; physical snapshots of /var/lib/gel/6/data are faster but version-locked.
Upgrades
sudo apt-get update
sudo apt-get install --only-upgrade gel-6
sudo systemctl restart gel-server-6Major version upgrades follow the dump → install side-by-side → restore → cut-over pattern. Use gel migration upgrade-check to validate your schema first.
Health Checks and Monitoring
Gel exposes HTTP health endpoints on the database port: /server/status/ready and /server/status/alive. Both return JSON suitable for uptime checks and load balancers. For a Caddy reverse proxy in front of the HTTP-based features (REST, GraphQL, admin UI):
gel.example.com {
reverse_proxy https://127.0.0.1:5656 {
transport http {
tls
tls_insecure_skip_verify
}
}
}Application traffic on the binary protocol should bypass the proxy and hit port 5656 directly.
What's Next
- Define your schema in
.esdlfiles and ship migrations withgel migration create - Use branches (Gel's database equivalent) to isolate previews and feature work
- Connect ORMs over the Postgres wire protocol when you need an existing toolchain
- Schedule offsite restic/borg replication of
/backups/gel
