Axum #

Axum adalah framework web modern di ekosistem Rust yang dibangun di atas Tokio dan Tower, dengan fokus pada type-safety, composability, dan performance. Namun, seperti banyak proyek Rust lainnya, tantangan di local development sering kali bukan di runtime, melainkan di environment:

  • Versi Rust toolchain berbeda antar developer
  • Dependency native (OpenSSL, libc, dll)
  • Setup database & service pendukung
  • Waktu onboarding yang lama

Docker membantu menyelesaikan masalah ini dengan menyediakan environment local development yang konsisten dan reproducible. Artikel ini membahas secara mendetail dan rinci bagaimana menyusun Dockerfile dan Docker Compose untuk aplikasi Axum (Rust) dalam konteks local development, dengan fokus pada developer experience, bukan sekadar build image.

Prinsip Docker Axum #

Sebelum masuk ke teknis, penting meluruskan prinsipnya:

  • Fokus pada DX dan iteration speed, bukan binary sekecil mungkin
  • Mendukung auto-reload (via cargo watch)
  • Source code di-edit di host, dijalankan di container
  • Tidak mencampur concern production ke local dev

Docker untuk local dev adalah alat kolaborasi tim, bukan alat optimasi runtime.


Struktur Project Axum #

axum-app/
├── src/
│   └── main.rs
├── Cargo.toml
├── Cargo.lock
├── Dockerfile
├── docker-compose.yml
├── .dockerignore
└── .env

Struktur ini sederhana, eksplisit, dan cocok untuk sebagian besar service Axum.


.dockerignore: Fondasi yang Sering Diabaikan #

target
.git
.gitignore
Dockerfile
.dockerignore
.env

Tanpa .dockerignore:

  • Build akan lambat
  • Context Docker membengkak
  • Cache layer tidak efektif

Ini kesalahan kecil dengan dampak besar.


Dockerfile untuk Axum #

FROM rust:1.75-slim

WORKDIR /app

RUN apt-get update \
    && apt-get install -y --no-install-recommends \
       pkg-config \
       libssl-dev \
    && rm -rf /var/lib/apt/lists/*

RUN cargo install cargo-watch

COPY Cargo.toml Cargo.lock ./
RUN cargo fetch

COPY . .

EXPOSE 3000

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

Penjelasan Dockerfile #

1. Base Image #

rust:1.75-slim dipilih karena:

  • Sudah menyertakan Rust toolchain resmi
  • Lebih ringan dari Debian penuh
  • Cocok untuk compile-heavy workload di local dev

Untuk production, base image biasanya sangat berbeda.

2. Dependency Sistem #

Banyak crate (misalnya sqlx, openssl) membutuhkan dependency native. Langkah ini mencegah error build misterius.

3. cargo-watch #

cargo-watch memungkinkan:

  • Auto rebuild & restart server
  • Workflow mirip hot reload di Node/Python

Ini kunci DX di Rust web development.

4. Cargo fetch #

Menarik dependency lebih awal untuk:

  • Optimasi cache layer
  • Menghindari download ulang setiap perubahan kode

5. CMD dev mode #

Menjalankan:

cargo watch -x run

Setiap perubahan file akan memicu rebuild otomatis.


Contoh main.rs Sederhana #

use axum::{routing::get, Router};

#[tokio::main]
async fn main() {
    let app = Router::new().route("/", get(|| async { "Hello Axum" }));

    axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
        .serve(app.into_make_service())
        .await
        .unwrap();
}

Binding ke 0.0.0.0 wajib agar bisa diakses dari host.


Docker Compose Axum #

version: '3.9'

services:
  api:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: axum-dev
    ports:
      - "3000:3000"
    volumes:
      - .:/app
      - cargo_registry:/usr/local/cargo/registry
      - cargo_git:/usr/local/cargo/git
    environment:
      RUST_LOG: debug
    depends_on:
      - db

  db:
    image: postgres:16-alpine
    container_name: axum-db
    environment:
      POSTGRES_USER: axum
      POSTGRES_PASSWORD: axum
      POSTGRES_DB: axum_dev
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  cargo_registry:
  cargo_git:
  postgres_data:

Penjelasan Docker Compose #

1. Service api #

  • volumes:

    • .:/app → sinkronisasi source code
    • cargo_registry, cargo_git → cache dependency Rust
  • ports: expose Axum ke host

  • environment: logging lebih verbose untuk dev

2. Service db #

Axum sering dipakai bersama:

  • SQLx
  • SeaORM
  • Diesel

Database disertakan agar environment mendekati real usage.


Workflow Developer #

  1. Jalankan:

    docker compose up --build
    
  2. Akses http://localhost:3000

  3. Edit file Rust di src/

  4. cargo watch otomatis rebuild & restart

  5. Semua developer pakai toolchain identik


Kapan Docker Masuk Akal? #

Docker sangat masuk akal jika:

  • Tim > 1 orang
  • Banyak dependency native
  • Ada database / service pendukung

Docker kurang masuk akal jika:

  • Eksperimen satu file
  • Learning Rust dasar

Engineering selalu soal konteks dan trade-off.


Anti-Pattern #

  • ❌ Menggunakan binary production untuk local dev
  • ❌ Tidak cache Cargo registry
  • ❌ Binding ke 127.0.0.1 di container
  • ❌ Dockerfile terlalu kompleks
  • ❌ Menganggap Rust dev harus selalu tanpa Docker

Best Practice #

  • ✅ Gunakan volume cache Cargo
  • ✅ Gunakan cargo watch
  • ✅ Bind server ke 0.0.0.0
  • ✅ Pisahkan Dockerfile dev & prod
  • ✅ Gunakan .env.example

Penutup #

Dockerfile dan Docker Compose untuk Axum (Rust) di local development bukan tentang memperlambat Rust, tapi tentang menjinakkan kompleksitas environment.

Dengan setup yang tepat:

  • Iterasi tetap cepat
  • Onboarding lebih singkat
  • “Works on my machine” berkurang drastis
About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact