DEV Community

loading...
Cover image for How to deploy Rust web app with DigitalOcean

How to deploy Rust web app with DigitalOcean

steadylearner profile image Steadylearner Updated on ・13 min read

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

On top of that, there are decent package management tools like cargo, cargo-edit etc. The programming language itself and packages(crates in Rust) are maturing also.

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

However, it was difficult to find the real examples to integrate frontend app to Rust and then deploying it to the web.

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.

If you have already experience in deploying websites in other languages, deploying Rust will not be so different from deploying Node or Python backend app.

  1. Buy VPS service such as DigitalOcean that offers the same operating system you use in your local machine.

  2. Repeat what you have been doing in your local development environment in a virtual machine they give.

  3. Configure Apache or Nginx and systemd service worker to work as proxy server

  4. Start your project inside the host service and serve it with your domain.

You may read on or just apply the process for a Rust or other web framework you use.

[Prerequisite]

  1. How to install Rust
  2. Rust Website
  3. DigitalOcean
  4. SSH
  5. How to use Vim
  6. Deploy Rocket with Nginx and LetsEncrypt
  7. Bash Command
  8. Linux

I hope you already have Rust installed in your machine and have web application ready.

For this post, I will use DigitalOcean as an example. First, I doubted that it would work or not with Rust. But later I found that it is easy if you already know how to use Linux Command Line. Because what they give you is just a Linux Virtual Machine and you can repeat what you did in your local machine.

Then, it will work. You are watching the result if you are at Steadylearner.

It works well with very low price with two month free trial time for you to test. You will not need that much time to begin with if you follow the instruction from this post.

It will be helpful if you are already familiar with Vim, CLI, Linux etc.

You should search for information about Nginx. It works well with default configuration but I hope you search information about it on your own.

If you don't have ssh keys in your machine yet, please follow the documentation from DigitalOcean I gave you.

What you need to do is just type ssh-keygen and follow the instruction in your machine.

You can repeat the process if your hardware is broken or when you need to start from nothing when you want to use it in antoher machine.

It will work in those situations also so do not worry and just follow the instructions your service providers give you.

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

You may read a lot after you made your app deployed with this post.

Table of Contents

  1. DigitalOcean Setup
  2. Install dependencies for your virtual machine
  3. Configure Nginx as a reverse proxy server
  4. Save your project in your virtual machine
  5. Create systemd service to serve your web application
  6. HTTPS for your website
  7. Conclusion

You can skip the DigtialOcean Setup part if you do not want to use it or just refer to it.

You will not need the Installing Dependencies for Linux Virtual Machine if you already know how to set up development environment.

Just repeat what you have done in your local machine after you buy VPS service from [DigtialOcean] or whatever service host provide.

If you have problem while following this post, please contact me with Twitter or LinkedIn and I will help you.

1. DigitalOcean Setup

DigitalOcean Website Screenshot by steadylearner

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

Just use Ubuntu 16.04 or Ubuntu 18.04 or whatever you want and the lowest price version to follow this article.

You can use this as an example and hope you already made an account.

DigitalOcean Website Screenshot by steadylearner

You can use whatever option you want but saving your resource is important.

Use the lowest price option. It will be enough to test your project.

DigitalOcean Website Screenshot by steadylearner

and we will also use Ubuntu 16.04 for our choice.

DigitalOcean Website Screenshot by steadylearner

Your computer should have been connected with your virtual machine that the service provides with SSH like the image below following the instruction.

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

DigitalOcean Website Screenshot by steadylearner

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

We are ready with DigitalOcean and we can write code to deploy our Rust Web Application with Nginx.

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

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

If you forget the domain of your website, you can use

$host www.steadylearner.com
Enter fullscreen mode Exit fullscreen mode

Test it with $host yourwebsite instead.

2. Install dependencies for your virtual machine

This is very tedious work if you had many dependencies.

For your machine is just an empty virtual machine, You have to install Rust Compiler, Cargo, Node, Nginx etc to prepare the deployment.

If you are familiar with Docker, you could have used it instead to save your time.

What is important is to install Rust to compile your Rust Web App and Nginx to work as reverse proxy server for it.

To advance, You have to verify minimum requirements are ready with command

$sudo nginx -h

nginx with nginx -h command

$rustup

rustup after installation

$cargo

cargo command after installation

and you are ready to write the real codes to deploy your website.

In this post, we will use Rust Rocket framework but you can use Actix or whatever framework and languages you want instead.

They will work because what you learn really in this post is how to use Nginx as proxy server for your web app in POSIX system.

3. Configure Nginx as a reverse proxy server

Nginx from its website

You are almost there. You could make it work with the documentations I gave you above.

But following the post will save your time, so I hope you did not tweak anything from the default yet.

You will see that it is just the matter of copy and paste when you have a real example.

Refer to the code snippet below for Nginx save it in /etc/nginx/sites-available/ as your-domain.tld.conf

your-domain.tld could be steadylearner.com

Just use yours instead.

server {
    #listen 80; # Only if sysctl net.ipv6.bindv6only = 1
    listen 80;
    listen [::]:80;

    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;
    }
}
Enter fullscreen mode Exit fullscreen mode

The example is very simple but there are two points you should 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.

You can refer to the image below.

Visit DigitalOcean to prefix www with http or https to redirect your domain

CNAME is used here, but you can use A or AAAA record for www instead if you want to enable HTTPS later in this post.

2. The Rust Web framework we will use is Rocket and the port for its production is http://0.0.0.0:8000. You had to help nginx to proxy the request to your Rust web application.

You could use other port and configuration if you use another framework such as Actix or ones from other languages etc.

Whenever you edit nginx relevant files, you can test it 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
Enter fullscreen mode Exit fullscreen mode

If it passed, you can use make sym link for the file your-domain.tld.conf you made before with

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

I hope you made it well to this point.

You will need various commands of nginx after you deploy your website.

Copy and paste them inside your ~/.bashrc file with $vim ~/.bashrc and use $source ~/.bashrc to use them if you want.

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"
Enter fullscreen mode Exit fullscreen mode

There were no difficult points. You didn’t even have to edit default nginx.conf file.

If you like to serve gzip file for your Rust Rocket or other web application.

You may include code snippet below and test them.

#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;
Enter fullscreen mode Exit fullscreen mode

You can verify it work with

$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
Enter fullscreen mode Exit fullscreen mode

and the result will be much better and easier than do it without Nginx.

If you managed to serve gzip files on your own with Rust or whatever language, you can use

$find . | gzip *.ext
$find . | gzip -d *.gz
Enter fullscreen mode Exit fullscreen mode

to compress and decompress files in a target folder to serve.

You do not need Webpack compressor or else to do that.

4. Save your project in your virtual machine

Your virtual machine was almost empty but you could edit and save the files with Vim.

You could also use git to download files for they are already pre-installed.

You may download your project files from you GitHub repository with command like

$git clone https://github.com/steadylearner/Rust-Web-App.git.
Enter fullscreen mode Exit fullscreen mode

You can use whatever you want to save files in your virtual machine instead.

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

You know better what you are doing than others. It is just repeating what you have done to build the entire project. The only difference is paths to serve and link files and directories.

If you are using Rust Rocket for this example,

  1. Download the files in your virtual machine

  2. Use $cargo check first to verify everything works fine first.

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

  4. Then, we will use systemd service to automate the process in the next part

Wanna update files later after you deploy your website?

  1. You have to repeat the command $cargo run --release whenever you tweaked your Rust files.

  2. For static files such as HTML, CSS, JavaScript, Images and other simple files. You just substitute them and they will work.

The difference is that Rust is a compiled language and others are not.

5. Create systemd service to serve your web application

You almost made it. We will refer to the Rocket for development environment to use it for systemd files.

It explains that there are development, staging and production environment and will be similar in other web frameworks.

For we are dealing with production files and ready to deploy it to the web, only care for production part.

When you use Rocket, it already has its own default configuration and you would not need to edit that much.

Read its documentation and find those parts in description will be used in systemd service later.

If you want to learn more about what service mean here, you may refer to

"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 here.

Then, make /etc/systemd/system/your-domain.tld.service and write content in it similar to

[Unit]
Description=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
Enter fullscreen mode Exit fullscreen mode

You should find the right path for your project and everything is ready.

Test in your virtual machine console with

$sudo systemctl start your-domain.tld.service.
Enter fullscreen mode Exit fullscreen mode

That will make your Rocket or any web framework you use to compile production files and serve them to port instead of you.

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

If you want, you can save the command similar to

alias verifywebsite="curl curl https://www.steadylearner.com"
Enter fullscreen mode Exit fullscreen mode

in your ~/.bashrc file or you can use $ping instead if you are familiar with Linux Commands.

The result will be response from Nginx or your production web pages if you could make it work.

You can verify the real example at Steadylearner.

Hope you made it.

You may write more alias in your ~/.bashrc similar to

# 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"
Enter fullscreen mode Exit fullscreen mode

That was all to deploy your Rust Web application to the web with Nginx and systemd service in Linux Virtual Machine.

You may use other web frameworks also. You just need to edit the paths and configuration parts for it.

If you want to allow HTTPS for your website also, please follow the next part.

6. HTTPS for your website

What we need to enable https for our website are just a few lines of commands.

$sudo certbot --nginx # 1.
$sudo certbot renew --dry-run # 2.
Enter fullscreen mode Exit fullscreen mode
  1. Refer to the official documentation from cerbot.

  2. Read the documentation from DigitalOcean about renew --dry -run command

From the first process with $sudo certbot --nginx, you will see the processes similar to

https-cert

https-enable

It would have shown certificate will expire later and you have to do some process for that.

We are ready for it. You just need to use $sudo certbot renew --dry-run.

https-renew

You can see that it is just simulating the renewal process in the description.

Then, you can visit your website and https is enabled for it.

7. Conclusion

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.

You can deploy a web application made with Rust.

I felt that there is nothing special in using Rust for web development with Nginx and Linux.

Only ports to serve files would be different from others and the rest of the process will be similar. You may do the same for other programming languages and frameworks also.

What you learnt is how to use Nginx and systemld for whatever web frameworks written in any programming languages.

It was the sum of the previous posts I wrote before.

You may visit one of them if you have problem with this post or you may search How to deploy Rust.

Follow me if you want more posts for Rust, React, Node, Python, Haskell, Solidity, Polkadot etc.

If you need to hire a developer, you can contact me.

Thanks and please share this post with others.

Discussion (2)

Collapse
gealber profile image
Gealber Morales

I was wondering I this was possible. Thanks for sharing it, it is very helpful 👍

Collapse
steadylearner profile image
Steadylearner Author

I am thinking of posting other articles also. Thanks for the feedback.

Forem Open with the Forem app