Back

Rust for NodeJS developers (IV) - SQLx CLI

Captain's log, stardate d429.y41/AB

Rust Node.js Web development Guides PostgreSQL Docker
Carlos López
Full-stack developer
Rust for NodeJS developers (IV) - SQLx CLI

Welcome to Part 4 of our "Rust for Node.js Developers" series!
If you missed our previous article on setting up a Docker development environment, you can catch up here.

In this article, we'll explore SQLx - a robust database toolkit for Rust.
According to its official repository, SQLx is:

An async, pure Rust SQL crate featuring compile-time checked queries without a DSL.

What makes SQLx stand out?

Let's get started by setting up a PostgreSQL database using SQLx!

Setting Up PostgreSQL with Docker

Start by adding a Postgres service to your development environment:

.dockerdev/compose.yml:

name: rust-for-nodejs-developers

services:
  backend-app:
    command: ["cargo", "watch", "-x", "run"]
    restart: unless-stopped
    tty: true
    environment:
      DATABASE_URL: postgresql://root:password@db:5432/rocket
      ROCKET_ADDRESS: 0.0.0.0
    build:
      context: ../
      dockerfile: ./.dockerdev/Dockerfile
    volumes:
      - ../.:/app
      - backend-target:/app/target
      - backend-cargo:/usr/local/cargo
    ports:
      - 8000:8000

  db:
    image: postgres
    restart: unless-stopped
    environment:
      POSTGRES_USER: root
      POSTGRES_PASSWORD: password
      POSTGRES_DB: rocket
      POSTGRES_HOST: db
      POSTGRES_PORT: 5432
    ports:
      - 5432:5432
    volumes:
      - dbvolume:/var/lib/postgresql/data
    command: ["postgres", "-c", "log_statement=all"]

volumes:
  backend-target:
  backend-cargo:
  dbvolume:

Adding SQLx CLI to your project

Enhance your Docker environment with the SQLx CLI by adding the following to your Dockerfile (remember to rebuild your Docker image afterward):

FROM rust:1.81.0

WORKDIR /app

COPY . .

RUN cargo install cargo-watch &&\
    # Install SQLx CLI tool for database management
    cargo install sqlx-cli --no-default-features --features native-tls,postgres &&\
    # Update package list
    apt-get update &&\
    # Install PostgreSQL development files required for SQLx
    apt-get install -y libpq-dev=15.6-0+deb12u1 --no-install-recommends &&\
    # Clean up apt cache to reduce image size
    apt-get clean &&\
    # Remove package lists to reduce image size
    rm -rf /var/lib/apt/lists/*

EXPOSE 8000

CMD ["cargo", "watch", "-x", "run"]

Streamlining Development with Make

Update your Makefile to simplify working with SQLx:

Makefile.toml:

[env]
# Define reusable Docker commands
DOCKER_SCRIPT = "docker compose -f .dockerdev/compose.yml"
DOCKER_SCRIPT_RUN = "${DOCKER_SCRIPT} run --remove-orphans --rm backend-app"

# Development task
[tasks.develop]
script = "${DOCKER_SCRIPT} up"

# SQLx CLI helper
[tasks.sqlx]
script = "${DOCKER_SCRIPT_RUN} sqlx ${@}"

# One-time database setup
[tasks.setup]
script = [
    "cargo make sqlx database create",
    "cargo make sqlx migrate run"
]

Create our first database migration by running cargo make sqlx migrate add -r init.
The -r flag creates a reversible migration.
This command will generate two files in the /migrations/ directory with names similar to 20250215155515_init.up.sql and 20250215155515_init.down.sql.
We'll modify these files to define our initial database structure.

/migrations/20250215155515_init.up.sql

CREATE TABLE users (
  id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  username VARCHAR (50) UNIQUE NOT NULL,
  email VARCHAR (50) UNIQUE NOT NULL
);

/migrations/20250215155515_init.down.sql

DROP TABLE IF EXISTS "users" CASCADE;

You can now initialize your database by running cargo make setup (make sure your app is already running with cargo make develop).

Result

You can find the complete code for this tutorial in this branch.

Coming Up Next

In our next article, we'll learn how to connect our application to the database using SQLx.

Share this post

Related Articles

How I use Docker for Rails development: running services

How I use Docker for Rails development: running services

Project setup can be a very cumbersome process for developers. In this blog post, our developer Dani explains how he uses Docker to develop in Rails

Read full article
Rust for NodeJS developers (I) - Why and how?

Rust for NodeJS developers (I) - Why and how?

We are always open to exploring new technologies. Recently, Rust has caught our attention due to its high performance, memory safety and reliability. In this series of articles, we will share the experience of learning Rust as a Node.js developer by building a GraphQL API in Rust.

Read full article
Rust for NodeJS developers (II) - Rocket

Rust for NodeJS developers (II) - Rocket

Rocket is a robust web framework for Rust, offering developers a streamlined approach to building high-performance web applications. In this article, we'll dive into how to get started with Rocket.

Read full article