Deploy A Rust Website on Heroku
Tags: rust, webdev, devops
Published: 2021-03-17 16:45:25

---
title: Deploy A Rust Website on Heroku
published: true
description: A short tutorial on deploying Rust web applications, in this case a Rocket framework app on Heroku.
tags: rust, webdev, devops
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kx4knlfi1isjvemvfaaw.png
canonical_url: https://jamesinkala.com/blog/deploy-a-rust-website-on-heroku/
---

Rust is a blazing fast and memory efficient programming language that's used by tech companies like Firefox, Dropbox and Cloudflare to name a few.

Today we are going to focus on the web side of Rust, hence the name "Rocket".

Well, per the official website [rocket.rs](https://rocket.rs) - _"Rocket is a web framework for Rust that makes it simple to write fast, secure web applications without sacrificing flexibility, usability, or type safety"_. That's a self explanatory introduction, nothing more I can add.

Having completed the formalities, let's launch some Rockets.

## Setting up Rocket ##
To run Rocket locally we need to have installed a compatible version of Rust ([install Rust](https://www.rust-lang.org/tools/install)), and since Rocket uses advanced and unstable features of Rust we'll need to use the `nightly` version of Rust.
To configure the nightly version of Rust as the default toolchain run the following command on your terminal.
```sh
rustup default nightly
```
or you can set it as the default toolchain for your Rocket project only by running the following command inside the Rocket project's directory after having created it.
```sh
rustup override set nightly
```

Now, proceed with creating a new cargo project
```sh
Cargo new rocket-demo-app --bin

# switch into the project's directory
cd rocket-demo-app
```

Add Rocket as a dependency in the `Cargo.toml` file found on the project's root.
```toml
...
[dependencies]
rocket = "0.4.7"
```

Update the `src/main.rs` file by adding a bit of Rocket code
```rs
#![feature(proc_macro_hygiene, decl_macro)]

#[macro_use] extern crate rocket;

#[get("/")]
fn index() -> &'static str {
  "This is my Rocket Demo app"
}

fn main() {
  rocket::ignite().mount("/", routes![index]).launch();
}
```

Then run the following command,
```sh
Cargo run
```

Rust will fetch all the dependencies used by Rocket, make a dev build of our project and run the binary code, launching our project.
```sh
Finished dev [unoptimized + debuginfo] target(s) in 3m 00s
     Running `target\debug\rocket-demo-app.exe`
🔧 Configured for development.
    => address: localhost
    => port: 8000
    => log: normal
    => workers: 8
    => secret key: generated
    => limits: forms = 32KiB
    => keep-alive: 5s
    => read timeout: 5s
    => write timeout: 5s
    => tls: disabled
🛰   Mounting /:
    => GET / (index)
🚀 Rocket has launched from http://localhost:8000
```
In the output above, Rocket has launched our project on the `8000` port, so to view it navigate to `http://localhost:8000`.

All we did on the `main/src.rs` file is declare an index route, mount it at the "/" path and launch our rocket app.

### Rocket routes ###
Rocket applications center around routes and handlers, where a `Rocket route` is simply a combination of __parameters__ matching an incoming request and a __handler__ that processes the request and returns a response.

A route is declared by annotating a function just as in the example above, the index route is:
```rs
#[get("/")]
fn index() -> &'static str {
  "This is my Rocket Demo app"
}
```
Where the annotation at the top - `#[get("/")]` is the route's attribute and the function that follows below it `fn index()` is the route's handler.

### Route mounting ###
Let's add a new route to our Rocket project.
Add the following code after the index route.
```rs
#[get("/about")]
fn about() -> &'static str {
  "This is the about page of my Rocket Demo app"
}
```
And re-run the cargo project.

When you try navigating to the `/about` page, you'll see a `404: Not Found` error.

__What happened?__

Well, Rocket needs to mount routes before dispatching requests to them, that is the reason we have `rocket::ignite().mount("/", routes![index]).launch();` inside the `main()` function for the first route.
Let's mount our ___about page__ route too. Update the `main()` function with the following code.
```rs
fn main(){
  rocket::ignite().mount("/", routes![index, about]).launch();
}
```
Re-run cargo and try visiting the "/about" route again.

After declaring and mounting our routes, we call the `lauch()` method which starts up the server and has our Rocket app up and running waiting for incoming requests to dispatch them accordingly.

For more on Rocket requests head to the [official documentation](https://rocket.rs/v0.4/guide/requests)

Before proceeding with the next step, use git to stage and commit all the changes done to the app.
```sh
git add . && git commit -m "initialize Rocket project"
```

## Setting up Heroku ##
Start with [creating an account on Heroku](https://signup.heroku.com/) if you do not have one before proceeding.

Inside the Heroku dashboard add a new app and fill in it's details
![Add new Heroku app](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lbzlzzbg74f7l0dxjphq.png)

Next, download and install the [Heroku CLI](https://devcenter.heroku.com/articles/heroku-command-line), then proceed with running the following command inside the project's directory.
```sh
heroku login
```

Follow the instructions which will redirect you to your browser and let you log into your Heroku account.

Back on the project, link the remote Heroku app to your Rocket project with the following command.
```sh
heroku git:remote -a rocket-demo-app
```

Create a new file on the project's root and name it `Procfile` without any extensions, add the following code into it.
```procfile
web: ROCKET_PORT=$PORT ROCKET_KEEP_ALIVE=0 ./target/release/rocket-demo-app
```

Specify a nightly version of Rust to work with by creating another file on the project's root, naming it `rust-toolchain` (without a file extension).
The following nightly version is a good start:
```txt
nightly-2020-10-24
```
Commit the new changes.


Use [Heroku's Rust buildpack](https://github.com/emk/heroku-buildpack-rust).
```sh
heroku buildpacks:set emk/rust
```

Then push the changes to heroku.
```sh
git push heroku master
```

After finishing all it needs to do, the command-line tool will give you the link your app has been deployed to, open the link and view the deployed app.
```sh
remote: -----> Building application using Cargo
remote:    Compiling rocket-demo v0.1.0 (/tmp/build_898d5ac6)
remote:     Finished release [optimized] target(s) in 3.39s
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote:
remote: -----> Compressing...
remote:        Done: 1.5M
remote: -----> Launching...
remote:        Released v6
remote:        https://rocket-demo-app.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/rocket-demo-app.git
   13450ef..0febf7c  main -> main
```
Above is an example output you'd expect from the heroku-cli tool.


This is a nice start when delving into deploying Rust applications and in this particular case we were deploying a Rocket framework app on Heroku.

There is so much more to learn and experiment in this "fast, easy, and flexible" framework, this has just been a short intro into deploying it, more can be learnt [here](https://rocket.rs/v0.4/guide/).

Go out there and launch some [Rockets](https://rocket.rs).

&nbsp;
&nbsp;

<center><a href="https://www.buymeacoffee.com/Xinnks" target="_blank"><img src="https://res.cloudinary.com/djx5h4cjt/image/upload/c_scale,h_50/james-sinkala/bmc-button.png" alt="Buy Me A Coffee" style="height: 50px !important;width: auto !important;" ></a></center>