Deploy a Rust Web App With Rocket
Tags: rust, webdev, docker, tutorial
Published: 2021-07-01 09:13:46


## Introduction

Rust is a popular programming language offering blazingly fast performance, and guaranteeing memory and thread safety.

In this tutorial, we will explain how to deploy a Rust web application using Rocket, a fast, easy, and flexible web framework.
We will then deploy the Rust web application on the Koyeb serverless platform offering a simple way to deploy Rust applications and offering native autoscaling, automatic HTTPS (SSL), auto-healing, and global load-balancing across our edge network with zero configuration.

## Requirements

To successfully follow and complete this guide, you need:
 - [Docker](https://docs.docker.com/get-docker/) installed on your machine
- A [Koyeb account](https://app.koyeb.com) to deploy and run the Rust web application
- The [Koyeb CLI](https://github.com/koyeb/koyeb-cli) installed to interact with Koyeb from the command line
- Have a registry we will use to store our Rust web app Docker image and deploy it on Koyeb

## Steps

To successfully deploy a Rust web application on Koyeb Serverless Platform, you need to follow these steps:

1. [**Create a Rust web app using Rocket**](#create-a-rust-web-app-using-rocket)
2. [**Dockerize the Rust web app**](#dockerize-the-rust-web-app)
3. [**Push the Docker image to a container registry**](#push-the-docker-image-to-a-container-registry)
3. [**Deploy the Dockerized Rust web app on Koyeb**](#deploy-the-dockerized-rust-web-app-on-koyeb)

## Create a Rust web app using Rocket

### Install Rust

To get started, let's start by configuring a Rust environment we will use to create the application.

If you do not have Rust installed on your machine, you can install using rustup. In your terminal, run the command below:

```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

Once rustup is installed, you may need to restart your current shell to reload your `PATH` environment variable. You can avoid this by configuring your current shell running:

```bash
source $HOME/.cargo/env
```

To ensure the latest toolchain is properly installed, in your terminal run:

```bash
rustup default stable
```

### Write the Rust web app using Rocket

To create our application, in your terminal run:

```bash
cargo new rust-rocket-app --bin
```

The command above uses Cargo, the Rust package manager to create a new package. The `--bin` option indicates to make a binary program.
Cargo created a `rust-rocket-app` directory containing two files:

- **Cargo.toml**: containing the metadata Cargo needs to compile our package
- **src/main.rs**: a "hello world" program Cargo generated for us

```bash
$ cd rust-rocket-app
$ tree .
.
├── Cargo.toml
└── src
    └── main.rs

1 directory, 2 files
```

As our web app uses Rocket, we need to add it as a package dependency. In the `rust-rocket-app` directory, open the `Cargo.toml` file and add rocket as a dependency under the `[dependencies]` section.

```yaml
[dependencies]
rocket = "0.5.0-rc.1"
```

Open and modify the `src/main.rs` with the code below:

```rust
#[macro_use] extern crate rocket;

#[get("/")]
fn index() -> &'static str {
    "Hello, world!"
}

#[get("/hello/<name>")]
fn hello(name: &str) -> String {
    format!("Hello, {}!", name)
}


#[launch]
fn rocket() -> _ {
    rocket::build()
        .mount("/", routes![index])
        .mount("/", routes![hello])
}
```

The code above creates two routes: `/`, returning "Hello, world!" and `/hello/<name>` returning "Hello, name!" where "name" is the route parameter. Then it mounts the routes and launches the application.

Finally, create a Rocket.to

To run and test the application locally, run:

```bash
cargo run
```

If everything goes fine, your app starts and you can test the routes using curl:

```bash
$curl localhost:8000/
Hello, world!
$curl localhost:8000/hello/koyeb
Hello, koyeb!
```

## Dockerize the Rust web app

To Dockerize our Rust web app, create a `Dockerfile` in your project directory.
In this guide, we use [Docker multi-stage build](https://docs.docker.com/develop/develop-images/multistage-build/) to keep the image layers size as small as possible and to ensure our image contains only what is needed to run.

In your Dockerfile, copy the content below:

```dockerfile
FROM rust:1 as builder
WORKDIR /app
COPY . .
RUN cargo install --path .


FROM debian:buster-slim as runner
COPY --from=builder /usr/local/cargo/bin/rust-rocket-app /usr/local/bin/rust-rocket-app
ENV ROCKET_ADDRESS=0.0.0.0
EXPOSE 8000
CMD ["rust-rocket-app"]
```

The first stage is used to build our application, in the second one we copy the application binary from stage one and use it to run the application.

To build the Docker image execute the following command:

```bash
docker build . -t <DOCKER_HUB_USERNAME>/rust-rocket-app
```

*In this guide we will push the Docker image to the Docker Hub. You are free to use another different registry as Koyeb allows you to deploy from any container registry.*

Once the build is completed, you can run a container using the image locally to validate everything is working as expected running:

```bash
docker run -p 8000:8000 <DOCKER_HUB_USERNAME>/rust-rocket-app
```

If everything goes fine, your container starts properly and you can test the routes using curl:

```bash
$curl localhost:8000/
Hello, world!
```

## Push the Docker image to a container registry

With the Docker image built and functional, we can now upload it to the Docker Hub container registry.
In your terminal run the command below to push the image:

```bash
docker push <DOCKER_HUB_USERNAME>/rust-rocket-app
```

Once the push command is completed, you will see your Docker image available on the Docker Hub.

## Deploy the Dockerized Rust web app on Koyeb

We are now ready to deploy our Rust web application on Koyeb. First, create a Koyeb Secret to store your container registry configuration.
In this guide, we will deploy our app from the Docker Hub. For other container registries example, check out the related [documentation](/docs/apps/private-container-registry-secrets).

*If your Docker image is public, there is no need to create a secret containing your container registry configuration.*

```bash
echo \
'{ \
  "auths": { \
    "index.docker.io/v1/": { \
      "username": "<REPLACE_ME_WITH_DOCKER_HUB_USERNAME>", \
      "password": "<REPLACE_ME_WITH_DOCKER_HUB_TOKEN>" \
    } \
  } \
}' | koyeb secrets create docker-hub-credentials
```

We can now deploy the Rust web application on Koyeb Serverless Platform running:

```bash
koyeb app init rust-rocket-app --docker "<REPLACE_ME_WITH_DOCKER_HUB_USERNAME>/rust-rocket-app" --ports 8000:http --routes /:8000 --docker-private-registry-secret docker-hub-credentials
```

This command creates a new Koyeb App and deploys our Rust application exposing port 8000 and making it publicly accessible on the `/` route of your Koyeb App URL.

To retrieve your Koyeb App URL and access your application, run:

```bash
$koyeb app get rust-rocket-app
ID                                  	NAME           	DOMAINS                             	UPDATED AT
d58ebed1-48c0-46b7-a2f1-91f3ffdbccf2	rust-rocket-app	rust-rocket-app-<YOUR_ORG>.koyeb.app	2021-06-23 09:46:55.411403 +0000 UTC
```

Open the URL in your browser to access your application running on Koyeb and natively offering autoscaling, automatic HTTPS (SSL), auto-healing, and global load-balancing across our edge network.