Databases

Install Dgraph Graph Database on Ubuntu 24.04

Dgraph is a distributed, transactional graph database built for production workloads. It uses a native GraphQL-like query language called DQL (Dgraph Query Language), supports ACID transactions, and scales horizontally across multiple nodes. Dgraph splits responsibilities between two main components – Zero (cluster coordinator) and Alpha (data server) – giving you fine-grained control over replication, sharding, and cluster membership.

Original content from computingforgeeks.com - post 8884

This guide walks through installing Dgraph v25.3.0 on Ubuntu 24.04 LTS, starting the cluster services, defining a schema, running mutations and queries, and setting up systemd services for production use. The same steps apply to Ubuntu 22.04 with no changes.

Prerequisites

Before starting, confirm you have the following in place:

  • A server running Ubuntu 24.04 LTS with at least 4 GB RAM and 2 CPU cores
  • Root or sudo access
  • Ports 5080, 6080, 7080, 8080, and 9080 available (not used by other services)
  • Docker installed if using the container method – see Install Docker on Ubuntu 24.04

Step 1: Install Dgraph on Ubuntu 24.04

Dgraph ships as a single binary that handles both Zero and Alpha roles. You can install it directly from the official release tarball or run it as a Docker container.

Method 1: Binary Installation

Download the latest Dgraph v25.3.0 release from GitHub and extract it to your system path.

wget https://github.com/dgraph-io/dgraph/releases/download/v25.3.0/dgraph-linux-amd64.tar.gz
sudo tar -xzf dgraph-linux-amd64.tar.gz -C /usr/local/bin

Verify the installation by checking the version:

dgraph version

The output confirms Dgraph v25.3.0 is installed and ready:

Dgraph version   : v25.3.0
Dgraph codename  : dgraph
Dgraph SHA-256   : [build hash]
Commit timestamp  : 2026-03-06
Branch           : HEAD
Go version       : go1.24

Clean up the downloaded archive:

rm -f dgraph-linux-amd64.tar.gz

Method 2: Docker Installation

If you prefer containers, pull the official Dgraph image from Docker Hub.

docker pull dgraph/dgraph:v25.3.0

Confirm the image downloaded successfully:

docker images dgraph/dgraph

You should see the Dgraph image listed with the v25.3.0 tag:

REPOSITORY       TAG       IMAGE ID       CREATED        SIZE
dgraph/dgraph    v25.3.0   abc123def456   2 weeks ago    150MB

For a quick standalone setup that runs both Zero and Alpha in a single container, use the standalone image:

docker run -d --name dgraph \
  -p 5080:5080 -p 6080:6080 \
  -p 8080:8080 -p 9080:9080 \
  -v ~/dgraph:/dgraph \
  dgraph/standalone:v25.3.0

The standalone image is good for development and testing. For production, run Zero and Alpha as separate processes or containers as described in the following steps.

Step 2: Start Dgraph Zero (Cluster Coordinator)

Dgraph Zero manages the cluster – it tracks Alpha nodes, assigns data shards, and handles rebalancing. Every Dgraph deployment needs at least one Zero node running before any Alpha can join.

Create data directories for Zero:

sudo mkdir -p /var/lib/dgraph/zero
sudo mkdir -p /var/log/dgraph

Start Dgraph Zero, binding it to the default ports 5080 (gRPC) and 6080 (HTTP):

dgraph zero --wal /var/lib/dgraph/zero/zw --telemetry "reports=false;" > /var/log/dgraph/zero.log 2>&1 &

Check that Zero is running and listening on its ports:

ss -tlnp | grep -E '5080|6080'

You should see both ports bound to the dgraph process:

LISTEN  0  4096  *:5080  *:*  users:(("dgraph",pid=1234,fd=7))
LISTEN  0  4096  *:6080  *:*  users:(("dgraph",pid=1234,fd=8))

You can also query the Zero health endpoint to confirm it is the cluster leader:

curl http://localhost:6080/state | python3 -m json.tool | head -20

Step 3: Start Dgraph Alpha (Data Server)

Dgraph Alpha handles all data storage, indexing, queries, and mutations. It connects to Zero on startup to join the cluster and receive shard assignments.

Create the Alpha data directory:

sudo mkdir -p /var/lib/dgraph/alpha

Start Dgraph Alpha, pointing it at the running Zero instance:

dgraph alpha --zero localhost:5080 \
  --postings /var/lib/dgraph/alpha/p \
  --wal /var/lib/dgraph/alpha/w \
  --tmp /var/lib/dgraph/alpha/t \
  --telemetry "reports=false;" > /var/log/dgraph/alpha.log 2>&1 &

Verify Alpha is running and listening on ports 7080 (internal gRPC), 8080 (HTTP/GraphQL), and 9080 (external gRPC):

ss -tlnp | grep -E '7080|8080|9080'

All three Alpha ports should show as listening:

LISTEN  0  4096  *:7080  *:*  users:(("dgraph",pid=2345,fd=9))
LISTEN  0  4096  *:8080  *:*  users:(("dgraph",pid=2345,fd=10))
LISTEN  0  4096  *:9080  *:*  users:(("dgraph",pid=2345,fd=11))

Test the Alpha health endpoint to confirm it joined the cluster successfully:

curl http://localhost:8080/health

A healthy response returns JSON showing the instance is “up” and “healthy”:

[{"instance":"zero","address":"localhost:5080","status":"healthy"},
 {"instance":"alpha","address":"localhost:7080","status":"healthy","uptime":15}]

Step 4: Access Dgraph Ratel UI

Ratel is the web-based interface for Dgraph that lets you run queries, mutations, and visualize your graph data. Dgraph hosts Ratel as a standalone web application available at play.dgraph.io, which connects to your Alpha instance.

Open your browser and navigate to:

https://play.dgraph.io

In the Ratel interface, set the Dgraph server URL to your Alpha HTTP endpoint. If running locally, use:

http://localhost:8080

If accessing from a remote machine, replace localhost with your server’s IP address. Make sure port 8080 is open in your firewall (covered in Step 9).

Ratel provides three main panels – Query for running DQL queries, Mutate for inserting and modifying data, and Schema for managing your graph schema. The visualization panel renders query results as interactive graph diagrams.

Step 5: Define a Schema in Dgraph

Before inserting data, define a schema that tells Dgraph what predicates (fields) exist and what types of indexes to build. Without a schema, Dgraph stores data but cannot filter or sort on predicates efficiently.

Define a sample schema for a movie database with name, release date, and genre predicates. Send it to the /alter endpoint:

curl -X POST localhost:8080/alter -d '
  name: string @index(exact, term) .
  release_date: datetime @index(year) .
  genre: [string] @index(exact) .
  starring: [uid] @reverse .
  director: [uid] @reverse .

  type Movie {
    name
    release_date
    genre
    starring
    director
  }

  type Person {
    name
  }
'

A successful response returns:

{"code":"Success","message":"Done"}

The schema defines:

  • name – a string with exact match and term (full-text) indexes
  • release_date – a datetime indexed by year for range queries
  • genre – a list of strings with exact match index
  • starring and director – UID edges (relationships) with reverse index for traversing the graph in both directions

Verify the schema was applied by querying it back:

curl http://localhost:8080/query -d '
  schema {}
' -H "Content-Type: application/dql"

Step 6: Mutate Data with DQL

Mutations insert or modify data in Dgraph. DQL mutations use JSON or RDF triple format to describe nodes and edges. Here we use JSON format to add movies and people to the graph.

Insert a movie with its director and cast:

curl -X POST localhost:8080/mutate?commitNow=true -H "Content-Type: application/json" -d '{
  "set": [
    {
      "uid": "_:matrix",
      "dgraph.type": "Movie",
      "name": "The Matrix",
      "release_date": "1999-03-31",
      "genre": ["Sci-Fi", "Action"],
      "director": [
        {
          "uid": "_:wachowski",
          "dgraph.type": "Person",
          "name": "Lana Wachowski"
        }
      ],
      "starring": [
        {
          "uid": "_:keanu",
          "dgraph.type": "Person",
          "name": "Keanu Reeves"
        },
        {
          "uid": "_:laurence",
          "dgraph.type": "Person",
          "name": "Laurence Fishburne"
        }
      ]
    }
  ]
}'

The response includes the UIDs assigned to each new node. The _:matrix, _:keanu, etc. are blank node labels that Dgraph replaces with permanent UIDs:

{
  "data": {
    "code": "Success",
    "message": "Done",
    "uids": {
      "keanu": "0x2",
      "laurence": "0x3",
      "matrix": "0x1",
      "wachowski": "0x4"
    }
  }
}

Add another movie that shares an actor to build out the graph relationships:

curl -X POST localhost:8080/mutate?commitNow=true -H "Content-Type: application/json" -d '{
  "set": [
    {
      "uid": "_:john_wick",
      "dgraph.type": "Movie",
      "name": "John Wick",
      "release_date": "2014-10-24",
      "genre": ["Action", "Thriller"],
      "starring": [
        {
          "uid": "0x2",
          "dgraph.type": "Person",
          "name": "Keanu Reeves"
        }
      ]
    }
  ]
}'

Notice we reference Keanu Reeves by his existing UID (0x2) instead of creating a duplicate node. This is how you build connections between existing entities in the graph.

Step 7: Query Data with DQL

DQL (Dgraph Query Language) uses a GraphQL-like syntax to traverse and filter graph data. Queries go to the /query endpoint with Content-Type: application/dql.

Query all movies and their cast:

curl -s localhost:8080/query -H "Content-Type: application/dql" -d '{
  movies(func: type(Movie)) {
    uid
    name
    release_date
    genre
    starring {
      name
    }
    director {
      name
    }
  }
}' | python3 -m json.tool

The response returns all movies with their relationships expanded:

{
    "data": {
        "movies": [
            {
                "uid": "0x1",
                "name": "The Matrix",
                "release_date": "1999-03-31T00:00:00Z",
                "genre": ["Sci-Fi", "Action"],
                "starring": [
                    {"name": "Keanu Reeves"},
                    {"name": "Laurence Fishburne"}
                ],
                "director": [
                    {"name": "Lana Wachowski"}
                ]
            },
            {
                "uid": "0x5",
                "name": "John Wick",
                "release_date": "2014-10-24T00:00:00Z",
                "genre": ["Action", "Thriller"],
                "starring": [
                    {"name": "Keanu Reeves"}
                ]
            }
        ]
    }
}

Use a reverse edge to find all movies a specific person starred in:

curl -s localhost:8080/query -H "Content-Type: application/dql" -d '{
  actor(func: eq(name, "Keanu Reeves")) {
    name
    ~starring {
      name
      release_date
      genre
    }
  }
}' | python3 -m json.tool

The ~starring syntax traverses the reverse edge, returning all movies where Keanu Reeves appears in the starring list. Filter queries with @filter to narrow results:

curl -s localhost:8080/query -H "Content-Type: application/dql" -d '{
  sci_fi(func: type(Movie)) @filter(eq(genre, "Sci-Fi")) {
    name
    release_date
    genre
  }
}' | python3 -m json.tool

This returns only movies with the “Sci-Fi” genre. DQL supports a wide range of filter functions including eq, ge, le, has, allofterms, anyofterms, and regular expressions.

Step 8: Configure Dgraph as Systemd Services

For production use, run both Dgraph Zero and Alpha as systemd services so they start automatically on boot and restart on failure.

First, stop the background processes you started earlier:

pkill dgraph

Create a dedicated system user for Dgraph:

sudo useradd --system --no-create-home --shell /usr/sbin/nologin dgraph
sudo chown -R dgraph:dgraph /var/lib/dgraph /var/log/dgraph

Create the Dgraph Zero systemd unit file:

sudo vi /etc/systemd/system/dgraph-zero.service

Add the following configuration:

[Unit]
Description=Dgraph Zero - Cluster Coordinator
After=network.target

[Service]
Type=simple
User=dgraph
Group=dgraph
ExecStart=/usr/local/bin/dgraph zero --wal /var/lib/dgraph/zero/zw --telemetry "reports=false;"
Restart=on-failure
RestartSec=10
StandardOutput=append:/var/log/dgraph/zero.log
StandardError=append:/var/log/dgraph/zero.log
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

Create the Dgraph Alpha systemd unit file:

sudo vi /etc/systemd/system/dgraph-alpha.service

Add the following configuration:

[Unit]
Description=Dgraph Alpha - Data Server
After=network.target dgraph-zero.service
Requires=dgraph-zero.service

[Service]
Type=simple
User=dgraph
Group=dgraph
ExecStart=/usr/local/bin/dgraph alpha --zero localhost:5080 --postings /var/lib/dgraph/alpha/p --wal /var/lib/dgraph/alpha/w --tmp /var/lib/dgraph/alpha/t --telemetry "reports=false;"
Restart=on-failure
RestartSec=15
StandardOutput=append:/var/log/dgraph/alpha.log
StandardError=append:/var/log/dgraph/alpha.log
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

Reload systemd, enable both services, and start them in order:

sudo systemctl daemon-reload
sudo systemctl enable dgraph-zero dgraph-alpha
sudo systemctl start dgraph-zero

Wait a few seconds for Zero to initialize, then start Alpha:

sudo systemctl start dgraph-alpha

Verify both services are running:

sudo systemctl status dgraph-zero dgraph-alpha

Both services should show active (running). Check the Alpha health endpoint to confirm the cluster is operational:

curl -s http://localhost:8080/health | python3 -m json.tool

Step 9: Configure Firewall for Dgraph

Dgraph uses five TCP ports across its two components. Open the ports you need based on whether you are running a single-node setup or a multi-node cluster.

PortComponentPurpose
5080/tcpZeroInternal gRPC – Alpha-to-Zero communication
6080/tcpZeroHTTP admin – cluster state and management
7080/tcpAlphaInternal gRPC – Alpha-to-Alpha communication
8080/tcpAlphaHTTP/GraphQL – queries, mutations, schema
9080/tcpAlphaExternal gRPC – client connections

On Ubuntu, use UFW (Uncomplicated Firewall) to open the required ports. For a single-node setup where clients connect remotely, open ports 8080 and 9080:

sudo ufw allow 8080/tcp comment "Dgraph Alpha HTTP/GraphQL"
sudo ufw allow 9080/tcp comment "Dgraph Alpha gRPC"

For a multi-node cluster, also open the internal communication ports between Dgraph nodes. Restrict these to your cluster network only:

sudo ufw allow from 10.0.1.0/24 to any port 5080 proto tcp comment "Dgraph Zero gRPC"
sudo ufw allow from 10.0.1.0/24 to any port 6080 proto tcp comment "Dgraph Zero HTTP"
sudo ufw allow from 10.0.1.0/24 to any port 7080 proto tcp comment "Dgraph Alpha internal gRPC"

Replace 10.0.1.0/24 with your actual cluster subnet. Reload UFW and verify the rules:

sudo ufw reload
sudo ufw status numbered

The output lists all active rules with their port assignments and source restrictions:

Status: active

     To                         Action      From
     --                         ------      ----
[ 1] 8080/tcp                   ALLOW IN    Anywhere                   # Dgraph Alpha HTTP/GraphQL
[ 2] 9080/tcp                   ALLOW IN    Anywhere                   # Dgraph Alpha gRPC
[ 3] 5080/tcp                   ALLOW IN    10.0.1.0/24                # Dgraph Zero gRPC
[ 4] 6080/tcp                   ALLOW IN    10.0.1.0/24                # Dgraph Zero HTTP
[ 5] 7080/tcp                   ALLOW IN    10.0.1.0/24                # Dgraph Alpha internal gRPC

Step 10: Backup and Restore Dgraph Data

Dgraph supports online backups through its admin GraphQL endpoint. Backups capture the full cluster state including schema, data, and ACL information without taking the cluster offline.

Create a Backup

Create a backup directory and set the proper permissions:

sudo mkdir -p /var/backups/dgraph
sudo chown dgraph:dgraph /var/backups/dgraph

Trigger a full backup using the admin endpoint. Dgraph Alpha must be configured to allow the backup path by setting the --export flag or using the default path:

curl -s localhost:8080/admin -H "Content-Type: application/json" -d '{
  "query": "mutation { export(input: {format: \"json\"}) { response { message } } }"
}' | python3 -m json.tool

A successful export returns a confirmation message with the export path:

{
    "data": {
        "export": {
            "response": {
                "message": "Export completed."
            }
        }
    }
}

The export files are stored in the Alpha data directory under an export folder with a timestamped directory name. List the exported files:

ls -la /var/lib/dgraph/alpha/export/

Copy the export directory to your backup location for safekeeping:

sudo cp -r /var/lib/dgraph/alpha/export/* /var/backups/dgraph/

Restore from Backup

To restore data from an export, use the dgraph live command to load the exported JSON or RDF files into a running cluster. Make sure Zero and Alpha are both running before starting the restore.

First, restore the schema:

dgraph live -s /var/backups/dgraph/dgraph.schema.gz \
  -f /var/backups/dgraph/g01.json.gz \
  -a localhost:9080 \
  -z localhost:5080

The -s flag points to the schema file, -f to the data file, -a to the Alpha gRPC address, and -z to the Zero gRPC address. The restore process loads all nodes and edges back into the database.

Verify the restore by running a test query against the data:

curl -s localhost:8080/query -H "Content-Type: application/dql" -d '{
  check(func: has(name), first: 5) {
    uid
    name
    dgraph.type
  }
}' | python3 -m json.tool

For automated backups, add a cron job that runs the export daily. If you manage MongoDB or other NoSQL databases alongside Dgraph, schedule backups at staggered times to avoid I/O contention.

Conclusion

You now have Dgraph v25.3.0 running on Ubuntu 24.04 with Zero and Alpha configured as systemd services, a defined schema, sample data loaded, and firewall rules in place. The setup handles queries, mutations, and exports out of the box.

For production hardening, configure TLS encryption between Zero and Alpha nodes, set up ACL (Access Control Lists) to restrict database access, deploy multiple Zero and Alpha instances for high availability, and ship the Dgraph logs to a centralized monitoring stack for alerting on cluster health.

Related Articles

Debian Install Plesk Control Panel on Ubuntu | Debian VOIP Install Festival TTS for Asterisk on Ubuntu 24.04 Ubuntu Install Sentora Web Hosting on Ubuntu 22.04|20.04|18.04 Desktop Install Cockpit Web Console on Ubuntu 24.04

Leave a Comment

Press ESC to close