Rust, a blazing fast and memory-efficient language, made its first appearance about ten years ago. Rust has gained a lot of momentum recently with the popularity of WebAssembly, a language that allows languages like C++, C, and Rust to run in web browsers. This enables developers to build highly performant applications and provide web apps with native functionalities that are not available on the web platform.

In this tutorial, you will learn how to deploy a Rust application to a hosting platform. You will then automate its deployment by building a continuous deployment pipeline. The pipeline will make sure changes to the app are deployed once it is pushed to your remote repository.

Prerequisites

To follow along with this tutorial, a few things are required:

  1. Basic knowledge of Rust
  2. Rust installed on your system (find installation instructions here)
  3. Heroku account
  4. CircleCI account
  5. GitHub account

With all these installed and set up, we can begin the tutorial.

Creating the Rust API project

To begin, create a new Rust application by running the following command:

cargo new --bin rust-api

This will quickly scaffold a bare-bones Rust application inside the rust-api folder. The --bin flag specifies that we are building an application and not a library. Once the process is done, go into the root of the folder with cd rust-api.

You will be building a simple API project using the Rocket package. Rocket provides an API for developing web applications with Rust. Rocket requires the nightly version of Rust. You can either globally set/install the nightly version by running the following command anywhere on your system:

rustup default nightly

If you would rather, you can set the nightly version only for the project you are working on by running the following command at the root of your project:

rustup override set nightly

When the nightly version is set, open the Cargo.toml file at the root of your project. Add Rockets as a dependency:

.....

[dependencies]
rocket = "0.4.7"

The web API will contain two endpoints:

  • The root (/) endpoint sends a welcome message
  • The greet endpoint takes the URL parameter name and responds with a greeting

Locate the file src/main.rs and replace its contents with this code:

#![feature(proc_macro_hygiene, decl_macro)]

#[macro_use] extern crate rocket;

#[get("/")]
fn index() -> &'static str {
    "Welcome to the Rust API"
}

#[get("/greet/<name>")]
fn greet(name: String) -> String {
    format!("Hey {}, glad to have you here!", name)
}

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

This code defines two route handler functions, one for each route:

  • The index function returns a welcome message to the client
  • The greet function takes the name URL parameter as its argument and returns a string that includes the name in a greeting message

The main function instantiates the rocket web packaage, mounts the defined routes, and launches the web application.

To run this project, go to the root of the application, and run:

cargo run

This will boot up the web server and display the following message on the CLI, indicating that the server is up and running.

"Server Up"

You can then visit the two endpoints.

"Root endpoint"

"Greet endpoint"

Now that you have a working web API built with Rust, you can get it deployed on the web.

Creating a Heroku app

To deploy the Rust API, you need to set up a Heroku application to host the application. Navigate to your Heroku account management console and go to New -> Create new app. Create a new app and give it whatever name you prefer.

New app - Heroku

Take note of the app name you just entered; you will need this later in the tutorial. Find your Heroku API Key in the Account Settings section of your dashboard, and make a note of it. You will need it later in the tutorial.

Finally, install the Rust buildpack. Buildpacks are scripts that run when your application is deployed. For this exercise, you will need the https://github.com/emk/heroku-buildpack-rust buildpack.

Go to your Heroku application’s Settings page and scroll down to Buildpacks. Click Add buildpack. On the pop up, enter the https://github.com/emk/heroku-buildpack-rust link into the input field, then click Save Changes.

Add buildpack - Heroku

Setting up a CircleCI project for deployment

To set up your project on CircleCI, you first need to push the project to GitHub.

Next, go to the Add Projects page on the CircleCI dashboard.

Add Project - CircleCI

Click the Set Up Project button.

Add Config - CircleCI

On the set up page, click Use Existing Config to indicate that you will be adding a configuration file manually and not using the sample. You are prompted to either download a configuration file for the pipeline or to start building.

Build Prompt - CircleCI

Click Start Building. This build will fail because you have not set up your configuration file yet. We will complete this task later on.

Now we need to set up environment variables for the project that was just added. This will give the project authenticated access to your Heroku application for deployments.

Make sure your project is the currently selected project. Go to your project’s settings by clicking on the Project Settings button, which is at the top right of the Pipelines page.

Project settings - CircleCI

You should now be on the project settings page. On this page, click Environment Variables from the side menu.

On the Environment Variables page, click Add Environment Variable.

Add environment variable - CircleCI

Add these environment variables:

  • HEROKU_APP_NAME is the name of your Heroku application (in this tutorial cci-rust-api)
  • HEROKU_API_KEY is your Heroku account API key (it can be found under the Account tab under Heroku Account Settings)

You now have everything set up on your CircleCI console for deployment to Heroku.

Automating the deployment of the Rust API app

Your Rust configuration management is crucial. To configure your Rust application for deployment to Heroku, which includes setting up the app for deployment and creating a deployment pipeline. There are three steps to this process:

  1. Create a Procfile to instruct Heroku about how to run the application
  2. Create a RustConfig file to define the Rust version Heroku is to use (nightly)
  3. Create the configuration pipeline file

At the root of the Rust project, create a Procfile. Add this command:

web: ROCKET_PORT=$PORT ./target/release/rust-api

This command instructs Heroku to run the release version of the built application located at ./target/release/rust-api. Usually, this is enough for Heroku to run most Rust applications. However, Heroku uses a dynamic port and you need to tell Rocket to bind the web application to that port. Add the command ROCKET_PORT=$PORT before specifying the build location of the app. This sets rocket’s port environment variable, ROCKET_PORT, to the dynamic port $PORT, assigned by Heroku upon deployment.

Next, create the file RustConfig at the root of the project. Add this line:

VERSION=nightly

Creating the deployment pipeline script

In this script, we will use CircleCI’s Heroku orb to deploy the application from your GitHub repository straight to Heroku. Orbs are easy-to-use packages that abstract a lot of boilerplate and complex commands and workflows. Using orbs provides a developer-friendly API to use in configuration files.

At the root of your project, create a folder named .circleci and a file named config.yml within it. Inside config.yml, enter this code:

version: 2.1
orbs:
  heroku: circleci/heroku@0.0.10
workflows:
  heroku_deploy:
    jobs:
      - heroku/deploy-via-git

In this configuration, the Heroku orb circleci/heroku@0.0.10 is pulled in, which provides access to a powerful set of Heroku jobs and commands. One of those jobs is the heroku/deploy-via-git, which deploys your application straight from your GitHub repo to your Heroku account. This job already takes care of installing the Heroku CLI, installing project dependencies, running the build script, and deploying the application. It also picks up your environment variables to facilitate a smooth deployment to your Heroku application.

It is time to run the deployment setup. Commit all changes to the project and push to your remote GitHub repository. This will trigger the deployment pipeline and you should get a successful build.

Build successful - CircleCI

Click the build job heroku/deploy-via-git to review the details of the deployment.

Build details - CircleCI

Sometimes a successful build does not exactly equate to a successful deployment. There are still many things that can go wrong on the Heroku platform itself. To confirm that you really have a successful deployment, go to your Heroku application dashboard and click Open app. This opens the application at the Heroku-designated URL https://[APP_NAME].herokuapp.com. For this tutorial, that will be https://cci-rust-api.herokuapp.com/. The welcome message confirms a successful deployment.

Site Live - Heroku

Site Live 2 - Heroku

Nice work!

Managing your Rust API deployments and beyond

The Rust programming language brings loads of powerful capabilities to web apps. Its ability to easily be integrated with frameworks such as Node.js enables developers to add more performance capabilities to Node.js applications and the web in general. In this tutorial, you have learned how to easily deploy Rust applications by setting up a deployment pipeline to Heroku with CircleCI. This knowledge gives you another ease-of-use toolset to add to your Rust setup.

To get started applying what you have learned to your own work, sign up for your CircleCI free trial today.

Happy coding!


Fikayo Adepoju is a full-stack developer, technical writer, and tech content creator proficient in Web and Mobile technologies and DevOps with over 10 years experience developing scalable distributed applications. With over 40 articles written for CircleCI, Twilio, Auth0, and The New Stack blogs, and also on his personal Medium page, he loves to share his knowledge to as many developers as would benefit from it. You can also check out his video courses on Udemy.