Databases Azure

Gel (formerly EdgeDB) on Ubuntu 24.04 on Azure User Guide

| Product: Gel on Ubuntu 24.04 LTS on Azure

Overview

Gel, formerly EdgeDB, is an open source graph-relational database built on top of PostgreSQL. You describe your data as typed object types with links and properties in a declarative schema, evolve it through versioned migrations, and query it with EdgeQL, a composable query language that returns rich, deeply nested results without hand written joins. Gel ships a built-in web administration interface, the Gel UI, with a schema browser, an interactive REPL and a data explorer. The cloudimg image installs Gel 7 from the official package repository, runs the server as the packaged gel-server-7 systemd service bound to loopback, fronts the Gel UI behind an nginx reverse proxy on TCP 80 with HTTP Basic auth, and generates a fresh database instance with a unique superuser password, TLS certificate and reverse-proxy password on the first boot of every VM. A small demo schema and data set are seeded so the schema browser and data explorer are populated the moment you sign in. Backed by 24/7 cloudimg support.

What is included:

  • Gel 7 installed from the official packages.geldata.com repository, running as the gel-server-7 systemd service (data directory /var/lib/gel/7/data, PostgreSQL 17 backend)
  • The built-in Gel UI (schema browser, EdgeQL REPL, data explorer) fronted by nginx on :80
  • nginx HTTP Basic auth as an outer gate on the UI, with a per-VM password in a root-only file
  • The Gel server bound to loopback only (127.0.0.1:5656, HTTPS) and reached solely through the reverse proxy
  • A per-VM superuser password, TLS certificate and reverse-proxy password, generated fresh on the first boot of every VM and never baked into the image
  • A seeded demo schema (a Person and Movie object type with links) recorded as a real migration
  • gel-server-7.service + nginx.service as systemd units, enabled and active
  • 24/7 cloudimg support

Prerequisites

An active Azure subscription, an SSH key pair, and a VNet + subnet in the target region. Standard_B2ms (2 vCPU / 8 GiB RAM) is a good starting point; scale up for larger workloads. NSG inbound: allow 22/tcp from your management network and 80/tcp for the Gel UI (front with TLS for public exposure - see Enabling HTTPS). The database port 5656 stays bound to loopback and is never exposed.

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Gel by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size; under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22) and HTTP (80). Then Review + create then Create.

Step 2 - Deploy from the Azure CLI

az vm create \
  --resource-group <your-rg> \
  --name gel \
  --image <marketplace-image-urn> \
  --size Standard_B2ms \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/id_ed25519.pub \
  --vnet-name <your-vnet> --subnet <your-subnet> \
  --public-ip-sku Standard

az vm open-port --resource-group <your-rg> --name gel --port 80 --priority 1010

Step 3 - Connect to your VM

ssh azureuser@<vm-public-ip>

Step 4 - Confirm the services are running

systemctl is-active gel-server-7 nginx

Both services report active. The Gel server bootstraps a fresh instance on the first boot and applies the seeded migration; on later boots it starts in a few seconds.

Gel service status and version

Step 5 - Retrieve your credentials

The superuser password, the Gel UI reverse-proxy password and the URLs are generated uniquely on the first boot of your VM and written to a root-only file:

sudo cat /root/gel-credentials.txt

This file contains:

  • GEL_ADMIN_USER (admin) and GEL_ADMIN_PASSWORD - the Gel superuser, used to sign in to the Gel UI and to run EdgeQL
  • GEL_UI_USER and GEL_UI_PASSWORD - the outer nginx HTTP Basic auth credentials that gate the Gel UI
  • GEL_URL - the Gel UI address for this VM

Store these somewhere safe.

Step 6 - Check the health endpoint and the network shape

nginx serves an unauthenticated health endpoint for load balancers and probes, while the database itself stays bound to loopback behind the auth wall:

curl -s http://localhost/health

It returns ok. The Gel server listens only on 127.0.0.1:5656, and any request to the UI without the Basic-auth credentials is refused with 401:

sudo ss -tlnp | grep -E '127.0.0.1:5656|:80 ' || true
curl -s -o /dev/null -w 'unauthenticated /ui/ -> HTTP %{http_code}\n' http://localhost/ui/

Gel loopback listeners and the nginx auth wall

Step 7 - Sign in to the Gel UI

Browse to http://<vm-public-ip>/ui. Your browser first prompts for the nginx Basic-auth credentials - enter GEL_UI_USER and GEL_UI_PASSWORD from Step 5. The Gel UI then presents its own sign-in screen: log in as admin with GEL_ADMIN_PASSWORD.

The Gel UI sign-in screen

Step 8 - Browse the typed schema

Open the main branch, then the Schema view. The image ships a seeded schema with a Person type and a Movie type that links to a director and multiple actors. The schema browser shows both the declarative SDL and an entity graph.

The Gel UI schema browser showing the Person and Movie types

The same schema and its recorded migration are visible from the CLI:

PW=$(sudo grep '^GEL_ADMIN_PASSWORD=' /root/gel-credentials.txt | cut -d= -f2-)
printf '%s\n' "$PW" | gel --host 127.0.0.1 --port 5656 --user admin --tls-security insecure --password-from-stdin query 'select schema::ObjectType { name } filter .name like "default::%";'

The recorded migration and the schema object types

Step 9 - Query with EdgeQL

Use the built-in REPL to run EdgeQL. EdgeQL returns rich, nested results directly - here every movie with its release year and the director's name, in one query with no joins:

The Gel UI REPL running a nested EdgeQL query

The Data Explorer shows the seeded objects in a grid, with the typed columns and links:

The Gel UI data explorer showing the seeded movies

You can run the same EdgeQL from the CLI. The gel client connects to the local server over the self-signed instance certificate:

PW=$(sudo grep '^GEL_ADMIN_PASSWORD=' /root/gel-credentials.txt | cut -d= -f2-)
printf '%s\n' "$PW" | gel --host 127.0.0.1 --port 5656 --user admin --tls-security insecure --password-from-stdin query 'select Movie { title, release_year, director: { name } } order by .release_year;'

An EdgeQL query returning the seeded movies from the CLI

Step 10 - Insert and persist data

Mutations are ordinary EdgeQL. Insert a new object and confirm the count changes:

PW=$(sudo grep '^GEL_ADMIN_PASSWORD=' /root/gel-credentials.txt | cut -d= -f2-)
printf '%s\n' "$PW" | gel --host 127.0.0.1 --port 5656 --user admin --tls-security insecure --password-from-stdin query "insert Person { name := 'Ada Lovelace' };"
printf '%s\n' "$PW" | gel --host 127.0.0.1 --port 5656 --user admin --tls-security insecure --password-from-stdin query 'select count(Person);'

Data is stored in the PostgreSQL-backed instance under /var/lib/gel/7/data and persists across service restarts and reboots.

Step 11 - Connect an application

Gel provides client libraries for the popular languages. Point a client at the server with the superuser credentials (or create a dedicated role for the application). For example, in Python:

pip install gel

import gel
client = gel.create_client(
    host="127.0.0.1", port=5656,
    user="admin", password="<GEL_ADMIN_PASSWORD>",
    tls_security="insecure",   # self-signed per-VM cert; supply the cert for production
)
print(client.query("select Movie { title } order by .release_year"))

For production, connect over the instance's TLS certificate (found in the data directory) rather than tls_security="insecure", and create a least-privilege role for the application instead of using the superuser.

Step 12 - Enabling HTTPS with your own domain

For public exposure, point a DNS record at the VM and terminate TLS at nginx with a real certificate:

sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d gel.your-domain.com

The database and the Gel UI already run over the loopback interface behind nginx, so adding a public certificate is all that is required to serve the UI over HTTPS.

Step 13 - Maintenance

  • Credentials: re-read them any time with sudo cat /root/gel-credentials.txt.
  • Service management: sudo systemctl status gel-server-7 nginx, and sudo systemctl restart gel-server-7 to restart the database.
  • Logs: sudo journalctl -u gel-server-7 -n 100 --no-pager.
  • Backups: back up the data directory /var/lib/gel/7/data, or use gel dump to export a branch.
  • Updates: the OS receives unattended security updates; upgrade Gel with sudo apt-get update && sudo apt-get install --only-upgrade gel-server-7.

Backed by 24/7 cloudimg support.