This article will talk about how to use Docker for quick Rocket web app deployment. This architecture can be scaled with more complicated CI/CD framework and Kubernetes clusters for large scale application and zero downtime deployment.
Prerequisite
- Linux server
- Local dev machine with Rust installed
- Docker with Docker Compose
- Follow this guide for setting up Traefik.
- Domain name
Getting started
Update rust
Install rustup
by following the instructions on its website. Once rustup
is installed, ensure the latest toolchain is installed by running the command:
rustup default stable
Initiate Rocket sample app
cargo new hello-rocket --bin
cd hello-rocket
Now, add Rocket as a dependency in your Cargo.toml
:
[dependencies]
rocket = "0.5.1"
Modify src/main.rs
so that it contains the code for the Rocket Hello, world!
program, reproduced below:
#[macro_use] extern crate rocket;
#[get("/")]
fn index() -> &'static str {
"Hello, world!"
}
#[launch]
fn rocket() -> _ {
rocket::build().mount("/", routes![index])
}
Finally, we can run below command to test our first app:
cargo run
Build docker image and upload
Add Dockerfile
There are many tutorials out there but it is always a good practice to follow official documents: https://rocket.rs/guide/v0.5/deploying/#containerization
Note that, in order to test Docker image in local, EXPOSE
is needed:
FROM docker.io/rust:1-slim-bookworm AS build
## cargo package name: customize here or provide via --build-arg
ARG pkg=hello-rocket
WORKDIR /build
COPY . .
RUN --mount=type=cache,target=/build/target \
--mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/usr/local/cargo/git \
set -eux; \
cargo build --release; \
objcopy --compress-debug-sections target/release/$pkg ./main
################################################################################
FROM docker.io/debian:bookworm-slim
WORKDIR /app
## copy the main binary
COPY --from=build /build/main ./
## copy runtime assets which may or may not exist
COPY --from=build /build/Rocket.tom[l] ./static
COPY --from=build /build/stati[c] ./static
COPY --from=build /build/template[s] ./templates
## ensure the container listens globally on port 8000
ENV ROCKET_ADDRESS=0.0.0.0
ENV ROCKET_PORT=8000
## uncomment below to test in local
## EXPOSE 8000
CMD ./main
Make sure the
pkg
set to same value as package name inCargo.toml
Build Docker image
docker build -t your_username/my-rocket-image .
Upload Docker image to Docker Hub
First make sure you have Docker Hub account and then login to Docker:
Docker login
Then upload Docker image to Docker Hub:
docker push your_username/my-rocket-image
Deploy docker image to cloud instance with Docker Compose and Traefik
Assume you already followed this guide and Traefik reverse proxy is up running in your server.
Run uploaded Rocket app Docker image
First let’s add a folder:
mkdir ~/rocket-docker && cd ~/rocket-docker
Then add docker-compose.yml
:
vi docker-compose.yml
networks:
traefik:
external: true
services:
app:
image: your_username/my-rocket-image:latest
networks:
- traefik
labels:
- "traefik.enable=true"
- "traefik.http.routers.rocket-docker.rule=Host(`your-domain.com`)"
- "traefik.http.routers.rocket-docker.service=rocket-docker"
- "traefik.http.routers.rocket-docker.entrypoints=websecure"
- "traefik.http.services.rocket-docker.loadbalancer.server.port=8000"
- "traefik.http.services.rocket-docker.loadbalancer.passhostheader=true"
- "traefik.http.routers.rocket-docker.tls=true"
- "traefik.http.routers.rocket-docker.tls.certresolver=letsencrypt"
- "traefik.http.routers.rocket-docker.middlewares=compresstraefik"
- "traefik.http.middlewares.compresstraefik.compress=true"
- "traefik.docker.network=traefik"
restart: unless-stopped
Make sure to update
your-domain.com
Run below to start service:
docker compose up -d
Verify by visiting www.your-domain.com
see if everything works properly.
Develop and update service with latest change
Try change something in your local Next.js app, and run upload script again:
docker build -t your_username/my-rocket-image . && docker push your_username/my-rocket-image
Then go to your cloud instance and run below:
docker pull your_username/my-rocket-image:latest && docker compose -f ~/rocket-docker/docker-compose.yml up -d
Lastly, verify the change by visiting www.your-domain.com
.
Leave a Reply