Rocket #
Rocket adalah framework web Rust yang terkenal dengan ergonomi API, type-safety yang kuat, dan macro-based routing. Rocket sangat nyaman untuk developer Rust, namun memiliki karakteristik khusus:
- Bergantung erat pada Rust nightly (pada versi tertentu) atau fitur compiler spesifik
- Compile time relatif berat
- Sangat sensitif terhadap konfigurasi environment
Karena itu, Docker untuk local development Rocket tidak boleh disamakan dengan Docker production. Artikel ini membahas secara mendalam dan rasional bagaimana membangun:
DockerfileRocket untuk local developmentdocker-compose.ymlyang mendukung hot reload, volume mount, dan database- Best practice serta anti-pattern yang sering terjadi di proyek Rocket
Fokus utama: developer experience (DX), kecepatan iterasi, dan konsistensi environment.
Prinsip Docker Rocket #
Sebelum masuk ke konfigurasi, pahami dulu prinsip utamanya:
- Compile Rust mahal → dependency caching wajib
- Rocket sering restart saat development → hot reload penting
- Local dev ≠ production → image size bukan prioritas
- Source code harus di-mount → bukan di-copy berulang
Implikasi desain:
- Gunakan image Rust resmi
- Hindari distroless
- Pisahkan Dockerfile dev & prod
Struktur Project Rocket #
.
├── Cargo.toml
├── Cargo.lock
├── src/
│ └── main.rs
├── Rocket.toml
├── Dockerfile
├── docker-compose.yml
└── .dockerignore
Dockerfile Rocket #
Contoh Dockerfile #
FROM rust:1.75-slim
# Install system dependencies
RUN apt-get update && apt-get install -y \
pkg-config \
libssl-dev \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# Install cargo-watch for hot reload
RUN cargo install cargo-watch
WORKDIR /app
# Copy manifest only (dependency cache)
COPY Cargo.toml Cargo.lock ./
# Dummy build to cache dependencies
RUN mkdir src && echo "fn main() {}" > src/main.rs \
&& cargo build \
&& rm -rf src
# Copy actual source code
COPY src ./src
COPY Rocket.toml ./Rocket.toml
EXPOSE 8000
CMD ["cargo", "watch", "-x", "run"]
Penjelasan Dockerfile #
Base Image #
FROM rust:1.75-slim
Alasan:
- Toolchain Rust lengkap
- Cocok untuk compile cepat
- Lebih stabil untuk Rocket dibanding image minimal
System Dependencies #
libssl-dev
Digunakan untuk:
- TLS
- Database driver
- Crate crypto
Tanpa dependency ini, build Rocket sering gagal secara silent.
Hot Reload dengan cargo-watch #
RUN cargo install cargo-watch
Manfaat:
- Rebuild otomatis saat file berubah
- Tidak perlu restart container
- Feedback loop cepat
Dependency Caching Strategy #
COPY Cargo.toml Cargo.lock ./
RUN cargo build
Ini adalah pola wajib di Rust Docker:
- Dependency hanya rebuild saat manifest berubah
- Source code update tidak memicu rebuild dependency
Runtime Command #
CMD ["cargo", "watch", "-x", "run"]
Efek:
- File berubah → compile ulang → Rocket restart
- Cocok untuk local dev
Docker Compose Rocket #
Contoh docker-compose.yml #
version: "3.9"
services:
app:
build:
context: .
container_name: rocket_app
volumes:
- .:/app
- cargo-registry:/usr/local/cargo/registry
- cargo-git:/usr/local/cargo/git
ports:
- "8000:8000"
environment:
ROCKET_ENV: development
ROCKET_ADDRESS: 0.0.0.0
ROCKET_PORT: 8000
DATABASE_URL: postgres://postgres:postgres@db:5432/app_db
depends_on:
- db
db:
image: postgres:16
container_name: rocket_db
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: app_db
ports:
- "5432:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
volumes:
cargo-registry:
cargo-git:
postgres-data:
Penjelasan Docker Compose #
Volume Mount Source Code #
- .:/app
- Edit kode di host
- Rocket reload otomatis via cargo-watch
Cache Cargo Dependency #
- cargo-registry:/usr/local/cargo/registry
- cargo-git:/usr/local/cargo/git
Ini sangat penting:
- Build ulang container jauh lebih cepat
- Dependency tidak di-download ulang
Environment Rocket #
ROCKET_ADDRESS=0.0.0.0
Tanpa ini:
- Rocket bind ke
localhost - Tidak bisa diakses dari host
Contoh main.rs Rocket #
#[macro_use] extern crate rocket;
#[get("/")]
fn index() -> &'static str {
"Hello Rocket!"
}
#[launch]
fn rocket() -> _ {
rocket::build().mount("/", routes![index])
}
Rocket otomatis bind sesuai environment variable.
File Rocket.toml (Opsional) #
[default]
address = "0.0.0.0"
port = 8000
log_level = "debug"
Bisa menggantikan environment variable jika diinginkan.
.dockerignore (Wajib) #
target
.git
.env
Tanpa ini:
- Context build besar
- Cache Docker sering invalid
Workflow Developer #
docker compose up --build
Alur kerja:
- Edit kode → auto rebuild
- Error langsung muncul
- Database siap pakai
Anti-Pattern #
❌ Multi-stage build untuk local dev ❌ Tidak cache Cargo registry ❌ Copy seluruh source sebelum dependency ❌ Tidak set ROCKET_ADDRESS
Dockerfile Production Terpisah? #
Saat:
- Deploy ke Kubernetes
- CI/CD pipeline
- Image size penting
- Security hardening
Solusi:
Dockerfile.devDockerfile.prod
Penutup #
Docker untuk Rocket bukan sekadar menjalankan Rust di container, tetapi tentang:
- Mengurangi compile cost Rust
- Menjaga DX tetap cepat
- Menyatukan environment seluruh tim
Dengan Dockerfile dan Docker Compose ini, Anda mendapatkan local development Rocket yang stabil, cepat, dan scalable.