Simplified EdgeDB Setup for Modern Database Management
A Step-by-Step Guide to Setting Up EdgeDB for Beginners
Welcome to the world of modern database management with EdgeDB! Whether you’re a software developer, data scientist, or a tech enthusiast eager to explore new technologies, EdgeDB promises to revolutionize the way you work with data. In this article, I’ll walk you through a simplified and more verbose setup, inspired by my personal struggle to grasp some of the concepts behind this novel piece of software and how to integrate it with the old and familiar project setups.
I will present you with three different ways to setup and interface with the database using a very simple python script as a demo client.
Prerequisites
This guide assumes you have already installed Python and/or Docker installed on your system. I use Python only to showcase a demo database client application therefore you can choose to use your own program written in any language which has an EdgeDB Client Library.
This guide also assumes you are running Linux on your host, however, everything works just fine on Windows as well. In order to keep this article as brief as possible, Windows-specific alternatives for certain commands are omitted but you can find them in the official documentation linked throughout this page.
Project Structure
The following project structure supports all three approaches described in this article however please note that not all files are used in every example. For the sake of brevity, I will reuse the same structure and files for all options.
my_project/
│
├── dbschema/ # Directory for your schema definition (.esdl) files
├── default.esdl # Define your database schema here
├── migrations/ # Directory for database migration files
│
├── edgedb.toml # EdgeDB configuration file
│
├── main.py # Your Python client application code
│
├── requirements.txt # Python dependencies list (if using Docker)
│
├── Dockerfile # Dockerfile for containerization (if needed)
│
├── docker-compose.yml # Docker Compose file (if using Docker)
│
└── ...
The edgedb.toml
and dbschema/migrations
file and directory will be automatically created by the EdgeDB CLI.
EdgeDB Demo Schema
We need some sort of structure that we can test our client against. Add the following to your dbschema/default.esdl
file:
module default {
type Person {
required name: str;
}
type Movie {
title: str;
multi actors: Person;
}
};
Python Client Source-code
We will be testing our setup with a synchronous client, however, keep in mind that EdgeDB and the Python client library also support asynchronous requests.
Add the following code to your main.py
file:
import edgedb
# Establish a connection to the EdgeDB instance
client = edgedb.create_client()
try:
# Insert data into the database
insert_data_query = r'''
INSERT Person {
name := 'Tom Cruise'
};
INSERT Person {
name := 'Val Kilmer'
};
INSERT Movie {
title := 'Top Gun: Maverick',
actors := (
select Person
filter .name in {
'Tom Cruise',
'Val Kilmer'
}
)
};
'''
client.execute(insert_data_query)
# Query for movies and the
query = r'''
SELECT Movie {
title,
actors: {
name
}
}
'''
# Execute the query
result = client.query(query)
# Print the results
for movie in result:
print(f"Movie: {movie.title}")
for actor in movie.actors:
print(f" Actor: {actor.name}")
except Exception as e:
print(f"An error occurred: {e}")
finally:
# Close the connection when done
client.close()
Option 1: Local Code and Database
Everything runs on the host, bare-metal
This is the simplest setup, suitable for both develop and bare-metal servers. The following is based on the official Quickstart Guide.
1. Installation: Begin by installing EdgeDB on your machine. On Linux we can do this by running
curl https://sh.edgedb.com --proto '=https' -sSf1 | sh
2. Initialize Your Project: Create a project directory as described and initialize it as an EdgeDB project:
edgedb project init
This is an interactive command which will scaffold your project by creating the necessary structure and files unless they already exist. Because we already defined a dbschema/default.esdl
file, that one will be skipped and instead we will only see a new edgedb.toml
file created under the project root directory.
This command will also spin up an EdgeDB server and “link” your current directory to that server, meaning all CLI commands you run will be executed against that instance unless unlinked.
More information regarding EdgeDB projects and instances as well as some clarification on what they actually are can be found here.
3. Generate Migrations: Create Database Migrations using the EdgeDB CLI
As you have noticed at this point, EdgeDB is designed to manage migrations instead of forcing the developer to rely on functionalities from ORMs.
This works by comparing your schema definition inside dbschema/default.esdl
with the schema currently defined inside the database instance itself.
edgedb migration create
Skip this step if you are using a project with existing EdgeDB migrations.
4. Migrate Your Schema: Apply all migrations to the database:
# This command is an alias for `edgedb migration apply`
edgedb migrate
5. Setup the Application: Prepare a virtual environment and install Python dependencies:
# Navigate to the directory where the virtual environment is located
cd /path/to/project
# Create a Python virtual environment
python -m venv venv
# Activate the virtual environment
source venv/bin/activate
# Install the required Python dependencies
pip install edgedb
6. Test the Application: Start the Python application by running:
# From within the Python venv, run
python main.py
In the console we expect to see Python printing out our movie and the list of associated actors. That should look something like this:
Movie: Top Gun: Maverick
Actor: Tom Cruise
Actor: Val Kilmer
Option 2: Local Code and Dockerized Database
The code runs on the host while EdgeDB is in a Docker container
Let’s take our setup and step further and dockerize our EdgeDB instance. While the CLI is very straightforward to use for setting up EdgeDB, there are many reasons why you may want or need to have EdgeDB running from within a Docker container.
With this in mind, the good folks at EdgeDB have prepared an official image for us to use, as well as documentation to accompany it.
Let’s dive into the steps to set this up:
1. Create and run an EdgeDB Docker container
docker run \
--name edgedb \
-e EDGEDB_SERVER_SECURITY=insecure_dev_mode \
-v /my/data/directory:/var/lib/edgedb/data \
-v ./dbschema:/dbschema \
-d edgedb/edgedb
Please replace /my/data/directory
with an actual directory on your system.
Note: Data persistence will not work on Windows. You will have to set up a Docker volume and bind to that instead. More info here.
By default, during the bootstrapping phase, the EdgeDB container will look for migrations in your dbschema/migrations
directory and execute them. Therefore, if you are continuing here from the previous section where we already created migrations using the EdgeDB CLI on the host, you can skip the next two steps.
2. Create database migrations
docker exec edgedb edgedb --tls-security=insecure \
-H localhost migration create --non-interactive
Despite running everything inside the container, and even if we previously ran edgedb project init
on the host, there is no edgedb.toml
file within the container itself, therefore we have to explicitly define the instance connection parameters. Keep in mind that we are simply using the EdgeDB CLI bundled with the Docker image containing the server.
You should now see a new migrations/
directory under dbschema/
or if you already had it created manually, you will notice a new file inside it named something like 00001.edgeql
.
Troubleshooting: If you get a Connection Timeout after running this command, it may be because the EdgeDB server is not yet up-and-running. Give it a few minutes and try again.
3. Apply database migrations
docker exec edgedb edgedb --tls-security=insecure -H localhost migrate
4. Define an EdgeDB Remote Instance
On the host machine, we will use the EdgeDB CLI to define a remote instance. You can think of this as a connection configuration which can later be used by projects.
The following process is the same for any server, regardless if on localhost or some external address. Run the following command and follow through the interactive configuration:
edgedb instance link
Specify server host [default: localhost]:
> localhost
Specify server port [default: 5656]:
> 5656
Specify database user [default: edgedb]:
> edgedb
Specify database name [default: edgedb]:
> edgedb
Unknown server certificate: SHA1:77070415... Trust? [y/N]
> y
Specify a new instance name for the remote server
[default: localhost]:
> edgedb_docker
5. Configure project to use remote instance
We now need to associate our current project directory with the instance we created. We will use the edgedb project init
command to interactively configure the project with the following inputs:
edgedb project init
Do you want to initialize a new project? [Y/n]
> Y
Specify the name of EdgeDB instance to use with this project [default: ...]:
> edgedb_docker
Do you want to use existing instance "edgedb_docker" for the project? [y/n]
> y
6. Test the Application:
You may now test the application just like you did in the previous section by running
# Activate the virtual environment
source venv/bin/activate
# From within the Python venv, run
python main.py
Option 3: Fully Containerized Application
The client app and EdgeDB are both in Docker containers
You might think this would involve simply creating a custom, multi-stage Docker image derived from the official Python and EdgeDB CLI image, initializing the EdgeDB project non-interactively, installing the dependencies for Python via Pip and going on with your day.
Well so did I, but as it turns out you cannot run edgedb project init
within a Docker container and hence the inspiration for this guide.
The EdgeDB Client can either use a linked instance created and associated via their CLI, or it can utilize environment variables to create a connection. This means that running edgedb project init
on a project is not always required. Let’s take a look at this demo setup I made…
The docker-compose.yml
file
version: '3.9'
services:
app:
image: app
container_name: app
environment:
- EDGEDB_DSN=edgedb://edgedb:5656?tls_security=insecure
volumes:
- .:/usr/src/app # Bind the current directory to the container
networks:
- internal
edgedb:
image: edgedb/edgedb
container_name: edgedb
env_file:
- "./.env"
volumes:
- dbdata:/var/lib/edgedb/data # Data persistence
- "./dbschema:/dbschema" # Schema persistence
ports:
- 5656:5656
networks:
- internal
volumes:
dbdata:
networks:
internal:
driver: bridge
The Dockerfile
file
FROM python:3
WORKDIR /usr/src/app
COPY ./requirements.txt /install/requirements.txt
RUN pip3 install -r /install/requirements.txt
CMD [ "python", "-u", "./main.py" ]
The .env
file
EDGEDB_SERVER_SECURITY=insecure_dev_mode
EDGEDB_SERVER_ADMIN_UI=enabled
EDGEDB_SERVER_BIND_ADDRESS="0.0.0.0"
And requirements.txt
edgedb==1.6.0
We can now get the project rolling in a few short, familiar steps…
1. Build the Docker image for our client application
docker build -t app .
2. Run the containerized EdgeDB server
docker-compose up -d edgedb
At this point you will have a running EdgeDB server container and if you already had database migrations defined in your dbschema/migrations
directory then they will have been executed as well. If this is the case then continue to step 5, otherwise proceed with the next steps.
3. Create database migrations
For the sake of demonstrating a fully-containerized setup we will not use the EdgeDB CLI on the host (if installed) and will rely on the CLI bundled with the EdgeDB Docker image.
This process is similar to the steps from Option 2. of this guide except this time we use docker-compose exec
instead of docker exec
:
docker-compose exec edgedb edgedb --tls-security=insecure -H localhost migration create --non-interactive
4. Apply database migrations
docker-compose exec edgedb edgedb --tls-security=insecure -H localhost migrate
5. Test the application
This time we run our Python application as a Docker container:
docker-compose up app
Since we are not running the command in detached
mode, in the terminal we should see something like
Attaching to app
app | Movie: Top Gun: Maverick
app | Actor: Tom Cruise
app | Actor: Val Kilmer
app exited with code 0
Important notes
Notice how in the CLI commands we use --tls-security=insecure
as well as ?tls_security=insecure
. This is possible thanks to the environment variable EDGEDB_SERVER_SECURITY=insecure_dev_mode
, which is explained in detail here. This enables us to connect to the EdgeDB server without configuring any SSL files on the client application, as well as to access the Admin Web UI without having to set up any credentials.
Of course this makes the whole setup totally insecure and inadequate for a production environment. Perhaps we can explore a more secure setup in some future article?
Exploring the Built-In Web UI
EdgeDB comes with a handy built-in web-based administration interface that makes visualizing and exploring your database very straightforward. Here’s how to access it:
- Open Web UI: To access the web UI, open your web browser and navigate to
http://localhost:5656/ui
; - Database Exploration: Once logged in, you will see a grid of all the databases created within the database server. You can view the one we created by clicking on the grid box named
edgedb
; - Schema Visualization: One of the highlights of the web UI is the ability to visualize your schema. You can navigate to the Schema view from the left-hand side menu.
As of the time of writing, the UI lacks some visual cues that it is still loading data from the backend so if you don’t see anything but the client app works, give it a minute.
Conclusion
EdgeDB empowers you to manage data in a new, more intuitive way, making it a valuable asset for software engineers, data scientists, and innovators in different fields. I hope that by following this guide your setup has been simplified or at the very least have a more clear idea of how everything is meant to work together.