docker.recipes

Axum + PostgreSQL

advanced

Ergonomic Rust web framework built on Tokio with PostgreSQL.

Overview

Axum is a modern Rust web framework developed by the Tokio team, built from the ground up on the Tower ecosystem of middleware and services. It leverages Rust's type system for compile-time safety while providing ergonomic extractors, handlers, and routing capabilities that make building high-performance web services intuitive. Axum inherits Tokio's exceptional async runtime performance, making it ideal for I/O-intensive applications that need to handle thousands of concurrent connections efficiently. This stack combines Axum's zero-cost abstractions and memory safety with PostgreSQL's robust ACID compliance and advanced querying capabilities. The pairing excels at building data-intensive applications where compile-time guarantees prevent runtime database errors through SQLx's compile-time query verification. PostgreSQL's JSON/JSONB support complements Axum's excellent serde integration, enabling flexible APIs that can handle both structured relational data and document-style payloads within the same application. This combination targets teams building production web services that prioritize performance, reliability, and developer productivity. Rust developers migrating from Node.js or Go will appreciate Axum's familiar routing patterns while gaining memory safety and predictable performance. The stack particularly appeals to fintech, IoT platforms, and real-time applications where PostgreSQL's transaction guarantees and Axum's low-latency request handling create a compelling foundation for mission-critical systems.

Key Features

  • Tower middleware ecosystem integration for composable request/response processing layers
  • Compile-time verified SQL queries through SQLx preventing runtime database errors
  • Zero-copy request parsing with extractors that leverage Rust's ownership system
  • PostgreSQL's JSONB operators for efficient semi-structured data queries within Axum handlers
  • Tokio's work-stealing scheduler optimized for high-concurrency async I/O operations
  • Type-safe route handlers with automatic OpenAPI schema generation potential
  • PostgreSQL connection pooling with deadlock detection and automatic recovery
  • Built-in tracing integration for observability across async request boundaries

Common Use Cases

  • 1Real-time trading platforms requiring sub-millisecond response times with ACID transaction guarantees
  • 2IoT data ingestion APIs processing millions of sensor readings with PostgreSQL's time-series capabilities
  • 3Multi-tenant SaaS applications leveraging PostgreSQL's row-level security and Axum's middleware
  • 4GraphQL APIs using async-graphql with Axum's handler system and PostgreSQL's complex join optimization
  • 5Microservices handling financial transactions where Rust's memory safety prevents data corruption
  • 6Content management systems requiring PostgreSQL's full-text search with custom ranking algorithms
  • 7Event-driven architectures using PostgreSQL's LISTEN/NOTIFY with Axum's WebSocket support

Prerequisites

  • Rust toolchain 1.70+ with Cargo for building the Axum application
  • Minimum 1GB RAM for PostgreSQL with buffer pool optimization
  • Port 3000 available for Axum HTTP server and port 5432 for PostgreSQL connections
  • Understanding of async/await patterns and Rust's ownership model
  • SQLx CLI installed for database migrations and compile-time query verification
  • Basic knowledge of PostgreSQL query optimization and indexing strategies

For development & testing. Review security settings, change default credentials, and test thoroughly before production use. See Terms

docker-compose.yml

docker-compose.yml
1services:
2 axum:
3 build: .
4 container_name: axum
5 environment:
6 DATABASE_URL: postgres://${DB_USER}:${DB_PASSWORD}@postgres:5432/${DB_NAME}
7 ports:
8 - "3000:3000"
9 depends_on:
10 - postgres
11 networks:
12 - axum-network
13
14 postgres:
15 image: postgres:16-alpine
16 environment:
17 POSTGRES_DB: ${DB_NAME}
18 POSTGRES_USER: ${DB_USER}
19 POSTGRES_PASSWORD: ${DB_PASSWORD}
20 volumes:
21 - postgres_data:/var/lib/postgresql/data
22 networks:
23 - axum-network
24
25volumes:
26 postgres_data:
27
28networks:
29 axum-network:
30 driver: bridge

.env Template

.env
1DB_NAME=axum
2DB_USER=axum
3DB_PASSWORD=changeme

Usage Notes

  1. 1Docs: https://docs.rs/axum/latest/axum/
  2. 2Access at http://localhost:3000
  3. 3Built on Tower ecosystem (layers, services)
  4. 4From Tokio team - excellent async support
  5. 5Use SQLx for compile-time checked queries
  6. 6Ergonomic extractors for request data

Individual Services(2 services)

Copy individual services to mix and match with your existing compose files.

axum
axum:
  build: .
  container_name: axum
  environment:
    DATABASE_URL: postgres://${DB_USER}:${DB_PASSWORD}@postgres:5432/${DB_NAME}
  ports:
    - "3000:3000"
  depends_on:
    - postgres
  networks:
    - axum-network
postgres
postgres:
  image: postgres:16-alpine
  environment:
    POSTGRES_DB: ${DB_NAME}
    POSTGRES_USER: ${DB_USER}
    POSTGRES_PASSWORD: ${DB_PASSWORD}
  volumes:
    - postgres_data:/var/lib/postgresql/data
  networks:
    - axum-network

Quick Start

terminal
1# 1. Create the compose file
2cat > docker-compose.yml << 'EOF'
3services:
4 axum:
5 build: .
6 container_name: axum
7 environment:
8 DATABASE_URL: postgres://${DB_USER}:${DB_PASSWORD}@postgres:5432/${DB_NAME}
9 ports:
10 - "3000:3000"
11 depends_on:
12 - postgres
13 networks:
14 - axum-network
15
16 postgres:
17 image: postgres:16-alpine
18 environment:
19 POSTGRES_DB: ${DB_NAME}
20 POSTGRES_USER: ${DB_USER}
21 POSTGRES_PASSWORD: ${DB_PASSWORD}
22 volumes:
23 - postgres_data:/var/lib/postgresql/data
24 networks:
25 - axum-network
26
27volumes:
28 postgres_data:
29
30networks:
31 axum-network:
32 driver: bridge
33EOF
34
35# 2. Create the .env file
36cat > .env << 'EOF'
37DB_NAME=axum
38DB_USER=axum
39DB_PASSWORD=changeme
40EOF
41
42# 3. Start the services
43docker compose up -d
44
45# 4. View logs
46docker compose logs -f

One-Liner

Run this command to download and set up the recipe in one step:

terminal
1curl -fsSL https://docker.recipes/api/recipes/axum-postgres/run | bash

Troubleshooting

  • sqlx::Error: error returned from database: relation does not exist: Run 'sqlx migrate run' to apply pending database migrations before starting Axum
  • Connection refused on postgres:5432: Add 'depends_on: postgres' to axum service and verify both containers are on the same Docker network
  • Compile error 'query does not exist': Set DATABASE_URL environment variable during build or use sqlx offline mode with 'cargo sqlx prepare'
  • High memory usage in PostgreSQL container: Adjust shared_buffers and work_mem settings in postgresql.conf or add POSTGRES_INITDB_ARGS environment variable
  • Axum handler timeout errors: Increase SQLx connection pool timeout settings or implement connection retry logic with exponential backoff
  • SQLSTATE 40P01 deadlock detected: Implement transaction retry logic in Axum handlers or reorder table access patterns to prevent lock cycles

Community Notes

Loading...
Loading notes...

Download Recipe Kit

Get all files in a ready-to-deploy package

Includes docker-compose.yml, .env template, README, and license

Ad Space