How to deploy Rust Web Application

Steadylearner
12 min readDec 27, 2018
Rust Programming Language Image from official website

People who use Rust mostly end up loving its features such as performance, reliability and productivity. It is not so easy to start to learn it, but there are great and friendly communities to help you.

You can find the latest contents at Steadylearner.

On top of that, there are decent package management tools like cargo and cargo-edit that makes you feel like you are using the JavaScript or Python for package management.

It seems that the programming language itself and packages(crates in Rust) are maturing also.

The language developers and contributers are also giving their time to enhance Webassembly integration to attract more Frontend Developers and make web application faster.

However, I thought that there are almost no practical examples for people without much experience in Programming.

Besides, it was much more difficult to find real examples for intergating Frontend Web Application and then deploying the production files to the web.

So I was not sure that I could upload my website to the web with Rust.

But I eventually made it and want to share the process with you.

TL;DR It is not so different from deploying Node js or Python backend app.

First, Buy VPS service such as DigitalOcean, AWS etc and repeat what you have been doing in your local development environment in Linux Vitrual Machine they give.

Then, configure Apache or Nginx and systemd service worker to start your project inside the host service..

For this post, I will use DigitalOcean as an example. I doubted that it is worth using the service or not and especially more for Rust.

But later I found that it is relatively easy if you already know how to use Linux Command Line.

I think that it works well with very low price with two month free trial time for you to test.

You wouldn’t need that much time to begin with if you follow the instruction well and read this post.

Before move on, I also suggest you read some prerequisite links to help you.

[Prerequisites]

  1. If you don’t know how to use Vim yet, please read How to learn Vim for beginners article that I prepared for you. It will help you to edit files inside the Linux Virtual Machine from DigitalOcean.
  2. I use Rust Rocket Framework and this post is based on Deploy Rocket using Letsencrypt and nginx(Just read it for reference)
  3. Follow this post about preparing DigitalOcean Deploy Environment with SSH at least before the title “Installing Environment Dependencies”.
  4. If you are not familiar with POSIX terminal, you may read keyboard shortcuts for bash command.

That maybe a lot to read before move on. But it is better than to have insufficient information before you start.

I want you to read the previous posts in the list below if you hadn’t also.

  1. Showing static HTML, CSS, JS Files with Rust Rocket Route
  2. undefined route handling with Rocket and Tera
  3. How to include Single Page App in Rust Web Application
  4. Deploying Rust Web App at DigitalOcean
  5. How to secure HTTPS for Rust Web App

If you are stuck following this post, Please leave a comment or contact me at LinkedIn and I will help you.

[Table of Contents]

  1. DigitalOcean Setup
  2. Installing Dependencies for Linux Virtual Machine
  3. Nginx Configuration as a reverse proxy server
  4. Donwloading Files from Github and test it with Rust Rocket
  5. Creating systemd service for your Rust application
  6. Conclusion

1. DigitalOcean Setup

DigitalOcean Website Screentshot by steadylearner

I wouldn’t write details about using DigitalOcean Service for there are many great documentations already.

Just use Ubuntu 16.04 and the lowest price version to follow this article.

At this moment, I hope you already read the article I provided and made a new droplet like a image below.

creating new droplet at DigitalOcean by steadylearner

You can use whatever option you want following the instructions but saving your resource is important. So please, don’t forget to use the lowest price option. It will be enough to test your project.

DigitalOcen Price Option from its official site

and we will also use Ubuntu 16.04 for our choice.

DigitalOcen Price Option from its official site

At this point, your computer should have been connected with your virtual machine that the service provides with SSH like the image below.

With command $ssh yoursite@xxx.xxx.x.xx, it will show you messages like image below.

message from DigitalOcean with right SSH configuration by steadylearner

You will see somewhat username@project:~$ in your Linux Kernel.

We are ready to prepare Nginx and Rust Rocket Web Application.

(If you don’t know url of your website, please visit the DigitalOcean project page)

At this moment, Your Linux Virtual Machine is almost empty. It will be easy to think that you have to start from nothing.

(It has Git to download your project easily, Vim to edit Nginx and Rocket Rust files already. We will see how to use them later.)

So you have to repeat what you have done to prepare your project before inside the virtual machine.

Then follow the what I will show you in the next processes.

2. Installing Dependencies for Linux Virtual Machine

Photo by Fotis Fotopoulos on Unsplash

This is very tedious work. You have to install Rust Compiler, Cargo, Node, Nginx etc to prepare the deployment.

(It is not Rust or this post specific issue and I think it is better to use docker instead if you know it well)

The major jobs you have to do are to install Rust to compile Rocket Application and Nginx to work as reverse proxy server for it.

(You may visit Showing static HTML, CSS, JS Files with Rust Rocket Route if you hadn’t any Rust project yet to follow this post.)

I hope you made it through well for you already know what you have done inside your computer before.

To advance, You have to verify minimum requirments are ready with command $sudo nginx -h and $rustup and $cargo

You should see the images like ones below.

nginx with nginx -h command after installation by steadylearner
rustup after installation by steadylearner
cargo after installation by steadylearner

and you are prepared to do the main work for uploading your site.

That would be easy if you know how to handle Nginx configuration and also read the github repository already.

We will just follow along the example with some variations for the new version of Rust Rocket application.

I hope you already know what is tld(top-level-domain).

3. Nginx Configuration as a reverse proxy server

nginx image from the official site

You are almost there. You may make all work following documentations given above.

But they are not exactly written for DigitalOcean with Rust and Nginx together.

So I hope you didn’t tweak anything from the default configurations of nginx yet.

(For allowing HTTPS, read the last post of this series)

You will see that there is no much to do and I will show you working examples that are merely different from current working example.

Just refer the given code snippet below instead of those described in the repository and save it to /etc/nginx/sites-available/ as your-domain.tld.conf

server {
#listen 80; # Only if sysctl net.ipv6.bindv6only = 1
listen 80;
listen [::]:80;
# The example for yourdomain.tld could be steadylearner.com
# You just replace it for your domain.
server_name yourdomain.tld www.yourdomain.tld; # 1. location / {
# Forward requests to rocket v4.0 production port
proxy_pass http://0.0.0.0:8000; # 2.
proxy_buffering off; # Single Page App work faster with it
proxy_set_header X-Real-IP $remote_addr;
}
}

This example is very simple but there are some points you have to know.

  1. You need to enable www at DigitalOcean to prefix it to your sitename

(You may read how-to-manage-records, using-cname-for-www and refer the image below, here CNAME is used for simpilicity, you can use A or AAAA record for www instead if you want to enable HTTPS and making A record following the official documentation is not difficult.)

Visit DigitalOcean to prefix www to redirect(screenshot by steadylearner)

2. The port for V 4.0 Rocket Prodcution App is http://0.0.0.0:8000 and it is different from the repository I gave above and you should have caution not to use the same port from the example.

You can verify nginx work fine or not with $sudo nginx -t and it will show messages similar to this.

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

and you can make sym link for this file with

cd /etc/nginx/sites-enabled && sudo ln -s ../sites-available/your-domain.tld.conf

You should have used various commands of nginx to follow this post.

You may not want to repeat them and you can save alias similiar to these lines below that I prepared and want to share for you.

Copy and paste them inside your ~/.bashrc file with $vim ~/.bashrc to make your life easier and use $source ~/.bashrc to use them.

You don’t have to remember details if you know what you want to do.

#nginx
alias startn="sudo systemctl start nginx"
alias stopn="sudo systemctl stop nginx"
alias restartn="sudo systemctl restart nginx"
alias reloadn="sudo systemctl reload nginx"
alias statusn="service nginx status"
alias testn="sudo nginx -t"
alias foldern="cd /etc/nginx"

I think there were no diffiuclt points for Nginx if you already read and followed instruction well. You didn’t even have to edit default nginx.conf file.

But if you like to serve gzip file for your Rust Rocket Application. You may include configuration codes like the snippet below and test they are working well and verify they are not commented also.

#inside nginx.conf(/etc/nginx/nginx.conf)##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 5; # it is better not to be larger than 5
gzip_buffers 16 8k;
gzip_http_version 1.1;
# write what you want to be served as gzip compressed file when use requested it.gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

You can verify the result later with command like

$ curl http://yourdomain.com --silent --write-out "%{size_download}\n" --output /dev/null

$ curl http://yourdomain.com --silent -H "Accept-Encoding: gzip, other things" --write-out "%{size_download}\n" --output /dev/null

and the result will be much better and easier than trying to implement serving compressed files to users with Rust or other things without having much working and undeprecated examples.

If you managed to serve gzip files with Rust code and still want to compress and serve them without Nginx, you can use $find . | gzip *.ext to compress and $find . | gzip -d *.gz to decompress inside the target folder.

You don’t need webpack compressor or else to do that.

4. Donwload Files from Github and Serve it with Rust Rocket

Photo by Pankaj Patel on Unsplash

Your virtual machine was almost empty but you could edit and save the files with Vim and git for they are already pre-installed.

So you can donwload your project files from you repository with command like $git clone https://github.com/steadylearner/Rust-Web-App.git.

You can use whatever you want to save files in your virtual machine and build the development envrionment to make your web application work and serve your project at specific port.

You might want to do it on your home directory. For that, use $cd ~ && mkdir yourwebsite and save your project files.

Again, you know better what you are doing. For it is just repeating what you have done and only difference is paths to serve and link files and directories.

If you are using Rocket for this example, download the files in your virtual machine, you can use $cargo check first to verify everything works fine first.

Then use $cargo run --release to make production files in target directory inside your virtual machine.

After that we will use systemd service to automate the process and I will exaplian it later.

Wanna update files later?

  1. You have to repeat the command $cargo run --release whenever you tweaked your Rust files for it is compiled language and need to make new binary everytime to make all work.
  2. For static files such as HTML, CSS, JavaScript, Images and other simple files, You don’t need to compile and just replace them with updated ones.

5. Creating systemd service for your Rust application

Photo by Alex Jones on Unsplash

This is the last phase to end this long process. We will refer Rocket Website Documentation about for development environment. It explains that there are development, staging and production environment.

For we are dealing with prodcution files and uploading it to the internet, we will just care for production part.

Luckily, You don’t have to know a lot about how this works for Rocket has its own default configuration to help you work less.

Just find that some of those parts in description are used inside systemd service that we are going to made.

.service: A service unit describes how to manage a service or application on the server. This will include how to start or stop the service, under which circumstances it should be automatically started, and the dependency and ordering information for related software.(from DigitalOcean Documeation)

You have to make /etc/systemd/system/your-domain.tld.service and write content in it like the code snippet below.

[Unit]
Description=Rust Rocket Web Application Example from steadylearner
[Service]
User=www-data
Group=www-data
WorkingDirectory=/home/yourname/yourwebsite/yourproject/
Environment="ROCKET_ENV=prod"
Environment="ROCKET_ADDRESS=0.0.0.0"
Environment="ROCKET_PORT=8000"
Environment="ROCKET_LOG=critical"
ExecStart=/home/yourname/yourwebsite/yourproject/target/release/yourproject
[Install]
WantedBy=multi-user.target

Save it and everything is ready. You should find the working path for your project.

You can use $sudo systemctl start your-domain.tld.service.

That will make Rocket to compile Production files and serve them to port instead of you.

You can also use $sudo systemctl enable your-domain.tld.service to make it work automatically for every reboot of the system.

You may visit your domain your-domain.tld at this point.

The result will be only nginx relevant files or the DigitalOcean Virtual Machine is serving your production files well as it does at Steadylearner.

Hope it worked well.

You may have failed but don’t give up for you already know that there is working example of this post.

You can use more alias like these code snippet that I let for your convenience.

# ufw firewall(install ufw first)
alias allownginx="sudo ufw allow 'Nginx Full'"
alias reloadufw="sudo ufw reload"
# systemd service
alias start="sudo systemctl start yourdomain.tld.service"
alias stop="sudo systemctl stop yourdomain.tld.service"
alias status="sudo systemctl status yourdomain.tld.service"
alias reload="sudo systemctl daemon-reload"
# It works automatically for every reboot, use it just once.
alias autoreload="sudo systemctl enable yourdomain.tld.service"

You may save those snippet in your ~/.bashrc file and use them to save your time.

That was all in uploading our first Rust Web Application to the web.

You may follow the last post for this series to enable HTTPS for your site at this moment.

6. Conclusion

Prove of this post at www.steadylearner.com

I know that it is not easy to follow this post.

You did well if you made it. Otherwise you can eventually achieve what you want. It is not impossible to do this process as I thought without examples.

I hope this article helped you get through the deployment part of Rust Web Application.

I felt that there is nothing special in using Rust for web development. Only ports to serve files would be different from others and the rest of the process will be similiar.

You may do the same for other programming languages and frameworks also.

Thanks and please share this post with others.

p.s

  1. Follow me at Twitter or LinkedIn if you want the latest contents
  2. Visit www.steadylearner.com for the complete example.
Photo by freestocks.org on Unsplash

There are many links for this post here so I let this at last so that you don’t have to search on your own when you visit this post later.

[Set of links]

  1. Starting with DigitalOcean Droplet
  2. Getting SSH and connect to DigitalOcean Virtual Machine
  3. How to start using Vim
  4. How to install nginx
  5. Installing Rust Toolchain
  6. Rocket Nginx Deploy Process
  7. Mange records to use www prefix
  8. Systemd

I am not a native English speaker. When some words don’t make sense, grammar problems etc. Please leave a comment below. I will read this post again and edit them right away.

--

--