TutorialsLast Updated Dec 8, 20237 min read

Continuous deployment for Rust applications

Fikayo Adepoju

Fullstack Developer and Tech Author

Developer D sits at a desk working on an intermediate-level project.

Rust, a blazing fast and memory-efficient language, made its first appearance about ten years ago. Rust has gained a lot of momentum with the popularity of WebAssembly, a language that allows languages like C++, C, and Rust to run in web browsers. Using Rust and WebAssembly, developers can build highly performant applications and give web apps native functionalities 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

Our tutorials are platform-agnostic, but use CircleCI as an example. If you don’t have a CircleCI account, sign up for a free one here.

Creating the Rust API project

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

cargo new --bin rust-api-heroku

This will quickly scaffold a bare-bones Rust application inside the rust-api-heroku 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-heroku.

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 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..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 package, 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 message on the CLI, indicating that the server is up and running.

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

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-heroku

This command instructs Heroku to run the release version of the built application located at ./target/release/rust-api-heroku. 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 section, you will create the configuration script required to deploy your application from your GitHub repository straight to Heroku.

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:
  node: circleci/node@5.1.0

jobs:
  deploy-app:
    docker:
      - image: "cimg/base:stable"
    steps:
      - checkout
      - run:
          name: Deploy app to Heroku
          command: |
            git push https://heroku:$HEROKU_API_KEY@git.heroku.com/$HEROKU_APP_NAME.git main
workflows:
  deploy:
    jobs:
      - deploy-app

The configuration above uses git to deploy your latest code changes to your Heroku account using your account credentials.

Our next task is to get our project set up on CircleCI. Begin by pushing your project to GitHub.

Next, log into your CircleCI account. If you signed up with your GitHub account, all your repositories will be available on your project’s dashboard.

Click Set Up Project next to your rust-api-heroku project.

Select project

You will be prompted to enter the name of the branch where your configuration file is housed as shown below

Click Set Up Project once you are done. This will trigger your first workflow, but it will fail.

CircleCI build failed

The deployment process fails because we have not provided our Heroku API key. To fix that, click the Project Settings button, then click the Environment Variables menu option. Add two new variables.

  • For HEROKU_APP_NAME, add the app name you used in Heroku. The name will be either rust-api-heroku or a custom name if you created one.

  • For HEROKU_API_KEY enter the Heroku API key that you retrieved earlier from the account settings page.

Re-run your workflow from the start, and this time your workflow will run successfully.

Build successful

To confirm that your workflow was successful, you can open your newly deployed app in your browser. The URL for your application should be in this format https://<HEROKU_APP_NAME>-<RANDOM_NUMBER>.herokuapp.com/. You can find the generated domain name for your app on the settings page.

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.

Conclusion

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 expand your knowledge, learn how to set up continous integration for Rust applications. From start to finish, you can increase the value of Rust for your team so you can build better apps, faster. The complete source code can be found here on GitHub

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 LinkedIn Learning (Lynda.com) Author, 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.

Copy to clipboard