# Source: https://docs.upsun.com/languages/rust.md

# Rust


p:last-child]:mb-0 [&>h3]:mt-0 rounded-lg" >

### Note
You can now use composable image to install runtimes and tools in your application container. To find out more, see the [Composable image](https://docs.upsun.com/create-apps/app-reference/composable-image.md) topic.

Upsun supports building and deploying applications written in Rust.

## Supported versions

You can select the major version. But the latest compatible minor version is applied automatically and can’t be overridden.

Patch versions are applied periodically for bug fixes and the like. When you deploy your app, you always get the latest available patches.

   - 1

## Dependencies

The recommended way to handle Rust dependencies on Upsun is using Cargo.
Commit a `Cargo.toml` and a `Cargo.lock` file in your repository
so the system automatically downloads dependencies using Cargo.

## Building and running your app

Assuming your `Cargo.toml` and `Cargo.lock` files are present in your repository,
you can build your app using the `cargo build` command to produce a working executable.

You can then start it from the `web.commands.start` directive.
Note that the start command _must_ run in the foreground.
If the program terminates for any reason it is automatically restarted.

The following basic [app configuration](https://docs.upsun.com../../create-apps.md) is sufficient to run most Rust apps.
See the [complete example](#complete-example) below for more details.

```yaml  {location=".upsun/config.yaml"}
applications:
  # The app's name, which must be unique within the project.
  myapp:

    # The language and version for your app.
    type: 'rust:1'

    hooks:
      build:
        cargo build

    web:
      commands:
        # Customize the start command with your own target.
        start: './target/debug/hello'

      locations:
        /:
          # Route all requests to the Rust app, unconditionally.
          allow: false
          passthru: true
```

Note that there is still an Nginx proxy server sitting in front of your application. If desired, certain paths may be served directly by Nginx without hitting your application (for static files, primarily) or you may route all requests to the Rust app unconditionally, as in the example above.

## Built-in variables

Upsun exposes relationships and other configuration as [environment variables](https://docs.upsun.com../development/variables.md).

To get the `PORT` environment variable (the port on which your app is supposed to listen),
use the following snippet:

```rust
let port : String = env::var("PORT").unwrap_or(String::from("8888"));
```

Note that some of the environment variables are in JSON format and are base64 encoded.
For example, to decode the `PLATFORM_RELATIONSHIPS` environment variable,
use the following snippet:

```rust
use base64::{Engine as _, engine::{general_purpose}};
use serde_json::Value;

let bytes = general_purpose::STANDARD.decode(env::var("PLATFORM_RELATIONSHIPS").unwrap_or(String::new())).unwrap();
let psh_config: Value = serde_json::from_slice(&bytes).unwrap();
println!("{}", psh_config["database"]);
```

## Complete example

Here is a basic hello world app to illustrate how you can use Rust with Upsun.
It builds from a `hello.rs` file to serve a static `index.html`.
Follow these steps:

1. [Install Rust and Cargo](https://www.rust-lang.org/tools/install).

2. Create a repository for your app and add the following `Cargo.toml` file:

   ```toml
   [package]
   name = "hello_world"
   version = "0.1.0"
   edition = "2021"

   [[bin]]
   name = "hello"
   path = "hello.rs"

   [dependencies]
   time = "0.1.12"
   regex = "0.1.41"
   base64 = "0.21.0"
   serde = { version = "1.0", features = ["derive"] }

   serde_json = "1.0"
   ```

3. Add the following [app configuration](https://docs.upsun.com../../create-apps/_index.md):

    ```yaml  {location=".upsun/config.yaml"}
    applications:
      # The app's name, which must be unique within the project.
      myapp:

        # The language and version for your app.
        type: 'rust:1'

        hooks:
          build:
            cargo build

        web:
          commands:
            # Customize the start command with your own target.
            start: './target/debug/hello'

        locations:
          /:
            # Route all requests to the Rust app, unconditionally.
            allow: false
            passthru: true
    ```
4. To generate a `Cargo.lock` file,
   run the following command:

   ```bash
   cargo generate-lockfile
   ```

5. Add the following `hello.rs` file:

   ```rust
   /* Simple HTTP Server */
   /* Author : Ramesh Vyas */
   use std::io::prelude::*;
   use std::net::TcpListener;
   use std::net::TcpStream;
   use std::fs;
   use std::env;

   fn main() {

       /* Creating a Local TcpListener at Port 8888 */
       const HOST : &str ="127.0.0.1";
       let port : String = env::var("PORT").unwrap_or(String::from("8888"));

       /* Concating Host address and Port to Create Final Endpoint */
       let end_point : String = HOST.to_owned() + ":" +  &port;

       /*Creating TCP Listener at our end point */
       let listener = TcpListener::bind(end_point).unwrap();

       println!("Web server is listening at port {}",port);

       /* Connecting to any incoming connections */
       for stream in listener.incoming() {
           let _stream = stream.unwrap();
           // Call Function to process any incomming connections
           handle_connection(_stream);
       }

   }

   fn handle_connection(mut stream: TcpStream) {
       let mut buffer = [0; 1024];
       stream.read(&mut buffer).unwrap();

       let get = b"GET / HTTP/1.1\r\n";

       if buffer.starts_with(get) {
           let contents = fs::read_to_string("index.html").unwrap();

           let response = format!(
               "HTTP/1.1 200 OK\r\nContent-Length: {}\r\n\r\n{}",
               contents.len(),
               contents
           );

           stream.write(response.as_bytes()).unwrap();
           stream.flush().unwrap();
       } else {
           // some other request
       }
   }
   ```