Introduction
\n\nYou've written a cool application in Rust. It's fast, safe, and doesn't crash. But how do you make it run 24/7 on a remote server and be accessible to users? Deploying a Rust application on a VPS (Virtual Private Server) is a process that includes compiling the binary, setting up the environment, running it as a system service, and often setting up a reverse proxy.
\n\nIn this article, we will go through the entire path from zero to a fully working Rust application deployed on a VPS with Ubuntu. You will learn how to prepare the server, build the project, set up auto-start, and ensure security. This guide is suitable for both web servers (Actix-web, Axum, Rocket) and any other Rust daemons.
\n\nLet's get started.
\n\n1. Server and Environment Preparation
\n\nBefore deploying the code, you need to prepare the "ground". We will use Ubuntu 22.04 LTS, but the instructions are also suitable for Debian.
\n\nConnecting to the Server and Basic Setup
\n\nConnect to your VPS via SSH:
\n\nssh root@your-server-ip\n\nUpdate packages and create a user (working as root is bad practice):
\n\napt update && apt upgrade -y\nadduser deployer\nusermod -aG sudo deployer\n\nConfigure SSH keys for the new user so you don't have to enter a password every time.
\n\nInstalling Rust on the Server
\n\nThe most reliable way is to use the official rustup script. Switch to the deployer user and run:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n\nAfter installation, reload the shell or run:
\n\nsource $HOME/.cargo/env\n\nCheck the version:
\n\nrustc --version\n\nFor a production build, we will need static linking (so the binary works on any Linux without extra libraries). Install musl-tools:
\n\nsudo apt install musl-tools -y\nrustup target add x86_64-unknown-linux-musl\n\n2. Building and Transferring the Binary to the Server
\n\nIt's better to build the application on your local machine (or in CI/CD) and then copy the ready binary to the server. This is faster and doesn't load the VPS.
\n\nBuilding the Production Version
\n\nOn your local computer, in the project folder, run:
\n\ncargo build --release --target x86_64-unknown-linux-musl\n\nThis will create a statically linked binary with no dependencies on glibc. The size will be larger, but it will run on any Linux.
\n\nExample of a simple web server using Actix-web for testing (file src/main.rs):
use actix_web::{web, App, HttpServer, Responder};\n\nasync fn hello() -> impl Responder {\n "Hello from Rust on VPS!"\n}\n\n#[actix_web::main]\nasync fn main() -> std::io::Result<()> {\n HttpServer::new(|| {\n App::new().route("/", web::get().to(hello))\n })\n .bind("0.0.0.0:8080")?\n .run()\n .await\n}\n\nCopying to the Server
\n\nUse scp for secure copying:
scp ./target/x86_64-unknown-linux-musl/release/your_project deployer@your-server-ip:/home/deployer/\n\nOn the server, move the binary to /usr/local/bin:
sudo mv /home/deployer/your_project /usr/local/bin/my-rust-app\nsudo chmod +x /usr/local/bin/my-rust-app\n\n3. Setting up systemd for Auto-start
\n\nTo make the application start on system boot, restart after a crash, and run in the background, we will create a systemd service.
\n\nCreate the service file:
\n\nsudo nano /etc/systemd/system/rust-app.service\n\nPaste the following config (replace deployer with your user):
[Unit]\nDescription=Rust Application\nAfter=network.target\n\n[Service]\nType=simple\nUse