Graph-Relational DB
    Self-Hosted

    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

    ProjectGel 6 (formerly EdgeDB)
    LicenseApache 2.0
    Recommended PlanRamNode Cloud VPS 4 GB+ for production
    OSUbuntu 22.04 / 24.04 LTS
    Default Port5656 (EdgeQL + Postgres wire)
    Estimated Setup Time25–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.

    1

    Provision and Harden Your RamNode VPS

    System update + base utilities
    apt-get update && apt-get upgrade -y
    apt-get install -y curl gnupg ca-certificates ufw fail2ban
    adduser deploy
    usermod -aG sudo deploy

    Copy 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.

    Firewall + fail2ban
    ufw default deny incoming
    ufw default allow outgoing
    ufw allow OpenSSH
    ufw enable
    systemctl enable --now fail2ban
    2

    Add the Gel Package Repository

    Import signing key
    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.gpg
    Add APT source (jammy/noble)
    echo "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-6

    The 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.

    3

    Configure the systemd Unit

    Edit unit (survives upgrades)
    sudo systemctl edit --full gel-server-6
    Service environment
    [Service]
    Environment="GEL_SERVER_TLS_CERT_MODE=generate_self_signed"
    Environment="GEL_SERVER_ADMIN_UI=enabled"
    Environment="GEL_SERVER_INSTANCE_NAME=ramnode_prod"
    Enable + start
    sudo systemctl enable --now gel-server-6
    systemctl status gel-server-6

    First 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.

    4

    Set the Admin Password

    The initial password can only be set from the privileged local Unix socket:

    ALTER ROLE via admin 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'"
    5

    Open Up Network Listening

    Default is loopback only. To bind to a private network or all interfaces:

    Configure listen addresses
    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 tcp

    Restrict source IPs in ufw whenever possible. Never expose 5656 publicly without TLS plus the admin password.

    6

    Capture the TLS Certificate for Clients

    Read self-signed cert
    sudo cat /var/lib/gel/6/data/edbtlscert.pem
    Client environment
    export 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.

    7

    Connecting From Your Application

    Link instance for local dev
    gel instance link \
      --dsn "$GEL_DSN" \
      --trust-tls-cert \
      --non-interactive \
      ramnode_prod
    Python example
    import 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://.

    8

    Backups With gel dump

    Dump every branch
    gel --dsn "$GEL_DSN" --tls-ca-file /etc/ssl/gel/edbtlscert.pem \
      dump --all --format dir /backups/gel/$(date +%Y%m%d-%H%M)
    Restore
    gel --dsn "$NEW_DSN" restore --all /backups/gel/20260101-0300
    Daily cron at 03:00
    0 3 * * * /usr/local/bin/gel-backup.sh

    Have 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.

    9

    Upgrades

    Point releases (drop-in)
    sudo apt-get update
    sudo apt-get install --only-upgrade gel-6
    sudo systemctl restart gel-server-6

    Major version upgrades follow the dump → install side-by-side → restore → cut-over pattern. Use gel migration upgrade-check to validate your schema first.

    10

    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):

    Caddyfile
    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 .esdl files and ship migrations with gel 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