Actix #

Actix Web adalah salah satu framework web paling mature dan berperforma tinggi di ekosistem Rust. Ia dikenal stabil, battle-tested, dan sering dipilih untuk service dengan kebutuhan throughput tinggi.

Namun, seperti proyek Rust pada umumnya, tantangan terbesar Actix di local development bukan pada runtime, melainkan pada:

  • Konsistensi Rust toolchain antar developer
  • Dependency native (OpenSSL, libc, dll)
  • Setup database dan service pendukung
  • Onboarding developer baru yang memakan waktu

Docker membantu menormalkan semua itu dengan menyediakan environment local development yang konsisten dan reproducible. Artikel ini membahas secara mendetail dan rinci bagaimana menyusun Dockerfile dan Docker Compose untuk aplikasi Actix Web (Rust) dalam konteks local development, dengan fokus pada developer experience (DX).

Prinsip Docker Actix #

Sebelum masuk ke teknis, kita perlu menyepakati prinsip dasarnya:

  • Fokus pada iteration speed & DX, bukan binary sekecil mungkin
  • Mendukung auto-reload menggunakan cargo watch
  • Source code diedit di host, dijalankan di container
  • Tidak mencampur concern production ke local dev

Docker di sini adalah alat kolaborasi tim, bukan alat optimasi performa runtime.


Struktur Project Actix #

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

Struktur ini cukup untuk sebagian besar service Actix, baik REST API maupun service internal.


.dockerignore: Fondasi yang Sering Diremehkan #

target
.git
.gitignore
Dockerfile
.dockerignore
.env

Tanpa .dockerignore:

  • Context Docker membengkak
  • Build melambat drastis
  • Cache layer tidak efektif

Kesalahan kecil ini sering luput, padahal dampaknya besar.


Dockerfile Actix #

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 8080

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

Penjelasan Dockerfile #

1. Base Image #

rust:1.75-slim dipilih karena:

  • Menggunakan Rust resmi
  • Lebih ringan dari Debian full
  • Cocok untuk local dev dengan compile-heavy workload

Untuk production, base image biasanya sangat berbeda (multi-stage, distroless).

2. Dependency Sistem #

Banyak crate Actix ecosystem (misalnya openssl, sqlx, diesel) membutuhkan dependency native.

Langkah ini mencegah error build yang sulit dilacak.

3. cargo-watch untuk Auto Reload #

cargo-watch memungkinkan:

  • Rebuild otomatis saat source code berubah
  • Restart server tanpa perintah manual

Ini mendekatkan DX Rust ke Node/Python world.

4. Cargo Fetch #

Menarik dependency lebih awal untuk:

  • Optimasi Docker layer cache
  • Menghindari download dependency berulang

Ini penting karena dependency Rust relatif berat.

5. CMD Dev Mode #

cargo watch -x run

Setiap perubahan file di src/ akan memicu rebuild dan restart otomatis.


Contoh main.rs Sederhana #

use actix_web::{web, App, HttpServer, Responder};

async fn index() -> impl Responder {
    "Hello Actix"
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .route("/", web::get().to(index))
    })
    .bind(("0.0.0.0", 8080))?
    .run()
    .await
}

⚠️ Binding ke 0.0.0.0 wajib agar bisa diakses dari host.


Docker Compose Actix #

version: '3.9'

services:
  api:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: actix-dev
    ports:
      - "8080:8080"
    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: actix-db
    environment:
      POSTGRES_USER: actix
      POSTGRES_PASSWORD: actix
      POSTGRES_DB: actix_dev
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  cargo_registry:
  cargo_git:
  postgres_data:

Penjelasan Docker Compose #

1. Service api #

  • .:/app → sinkronisasi source code
  • Cargo cache volumes → mempercepat rebuild
  • RUST_LOG=debug → logging verbose di dev

2. Service db #

Actix sering digunakan bersama:

  • SQLx
  • Diesel
  • SeaORM

Database dimasukkan agar environment local mendekati production.


Workflow Developer #

  1. Jalankan:
    docker compose up --build
    
  2. Akses http://localhost:8080
  3. Edit file Rust di src/
  4. cargo watch rebuild otomatis
  5. Semua developer memakai 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
  • Belajar Actix dasar

Engineering selalu soal konteks dan trade-off.


Anti-Pattern #

  • ❌ Menggunakan binary production untuk local dev
  • ❌ Tidak cache Cargo dependency
  • ❌ Binding ke 127.0.0.1 di container
  • ❌ Dockerfile terlalu kompleks
  • ❌ Menganggap Docker memperlambat Rust

Best Practice #

  • ✅ Gunakan cache Cargo (cargo_registry, cargo_git)
  • ✅ Gunakan cargo watch
  • ✅ Bind server ke 0.0.0.0
  • ✅ Pisahkan Dockerfile dev & prod
  • ✅ Dokumentasikan env via .env.example

Penutup #

Dockerfile dan Docker Compose untuk Actix (Rust) di local development bukan tentang mengorbankan performa, tapi tentang menjinakkan kompleksitas environment.

Dengan setup yang tepat:

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