This is a simple example on how to use SurrealDB running in Docker and connect to it from your computer using a Rust-based client.
It is a simplified version of the example provided by SurrealDB.
I assume you already have Docker and Rust installed.
Start the SurrealDB in Docker
Create a volume for the database
First we create a volume in Docker to make it easy to have a persistent database without the need to think where to put it.
docker volume create my-surreal-db
Start the database server in one terminal
Then we can start the SurrealDB server in a Docker container.
The --name
flag tells Docker to call the container surrealdb
. This is an arbitrary name that can help us identify it if necessary.
The --rm
flag tells Docker to remove the container once it stopped running so having an easily recognizable name might not be that important.
The -p 8000:8000
flag tells Docker to share the internal port 8000 where SurrealDB listens on the 8000 port of the computer. By default this will only accept connections from your computer so this is fine.
The --user root
tells the Docker to run as user root.
The -v my-surreal-db:/database
maps the volume we created earlier to the /database
folder internally. Apparently this is where SurrealDB stores its files.
The surrealdb/surrealdb:latest
is the name of of the image we will use. It will be downloaded automatically if you don't have it on the disk yet.
The start --log trace file://database
is passed to SurrealDB. This is here we tell what is the name of the user and its password we would accept. It is also here where we tell SurrealDB to store its files in the /database
folder.
docker run --name surrealdb --rm -p 8000:8000 --user root \
-v my-surreal-db:/database surrealdb/surrealdb:latest \
start --log trace file://database
The Rust client
Once we have the database server running we need to create a crate for our code, add the dependencies and run.
Create the crate
$ cargo new in-docker-demo
$ cd in-docker-demo/
Add the dependencies to Cargo.toml
Obviously we need SurrealDB, but we also need serde to serialized and deserialize the structs and we need tokio for the async.
The specific versions probably do not matter much but if you want to check the code, you'll find the Cargo.lock
file in our GitHub repository.
examples/surrealdb/in-docker-demo/Cargo.toml
[package]
name = "in-docker-demo"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
surrealdb = "1.4.0"
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1.35", features = ["macros", "rt-multi-thread"] }
The code
Finally we have the code:
examples/surrealdb/in-docker-demo/src/main.rs
use serde::{Deserialize, Serialize};
use surrealdb::engine::remote::ws::Ws;
use surrealdb::sql::Thing;
use surrealdb::Surreal;
#[derive(Debug, Serialize, Deserialize)]
struct Message {
text: String,
}
#[derive(Debug, Deserialize)]
struct Record {
#[allow(dead_code)]
id: Thing,
}
#[tokio::main]
async fn main() -> surrealdb::Result<()> {
// Connect to the server
let db = Surreal::new::<Ws>("127.0.0.1:8000").await?;
// Select a specific namespace / database
db.use_ns("test-ns").use_db("test-db").await?;
let args = std::env::args().collect::<Vec<String>>();
if args.len() == 2 {
// Create a new message with a random id
let created: Vec<Record> = db
.create("messages")
.content(Message {
text: args[1].to_owned(),
})
.await?;
dbg!(created);
} else {
// Select all the messages records
let mut response = db.query("SELECT * from messages").await?;
let messages: Vec<Message> = response.take(0)?;
for message in &messages {
println!("{}", message.text);
}
}
Ok(())
}
First we connect to the server that listens on port 8000 (as defined on the Docker command line) on 127.0.0.1 (aka. localhost) as that's the default for Docker.
Then we select the namespace and database we are going to use. You can use any name there. The idea behind them is to allow you to map departments and project in a single organization to namespaces and databases.
Then we get a value from the command line. If the user supplied a value we use that value to create a new record in the database.
Otherwise we list the existing messages.
Running the code
This will add the message "Hello World" to the database:
cargo run "Hello World"
This will list all the messages.
cargo run
Stop and restart server
We can stop the database by pressing Ctrl-C.
We can then start it again with the same docker
command we started it earlier.
If we list the messages now they are all still there as they were saved in the database on that volume somewhere on your hard-disk.
Remove the volume
The volume with the database takes up some space on your disk. After you are done with all the experiments you can remove it using the following command:
docker volume remove my-surreal-db