Skip to content
This repository has been archived by the owner on Oct 21, 2024. It is now read-only.

Commit

Permalink
rust docker container example (#966)
Browse files Browse the repository at this point in the history
* init rust project

* init basic axum app

* init docker stuff

* init base sst ion

* working docker example

* update docs
  • Loading branch information
judegiordano authored Oct 7, 2024
1 parent 18dcf42 commit d1d16f1
Show file tree
Hide file tree
Showing 11 changed files with 183 additions and 0 deletions.
24 changes: 24 additions & 0 deletions examples/aws-rust-cluster/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# rust
/target

# dotfiles
*.env
.git
.gitignore
.dockerignore
.build

# misc
Dockerfile
docker-compose.yml
README.md

# node
node_modules
package.json
package-lock.json
tsconfig.json

# sst
sst.config.ts
.sst
6 changes: 6 additions & 0 deletions examples/aws-rust-cluster/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# sst
.sst

# rust
Cargo.lock
target/
10 changes: 10 additions & 0 deletions examples/aws-rust-cluster/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "aws_rust_cluster"
version = "0.1.0"
edition = "2021"

[dependencies]
anyhow = "1.0.86"
axum = "0.7.5"
serde = { version = "1.0.209", features = ["derive"] }
tokio = { version = "1.40.0", features = ["rt-multi-thread", "macros", "net"] }
28 changes: 28 additions & 0 deletions examples/aws-rust-cluster/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
FROM rust:slim AS chef

# install build tools
RUN apt-get update -y && \
apt-get install -y pkg-config make g++ libssl-dev && \
rustup target add x86_64-unknown-linux-gnu

# add cargo chef (this installs only once on first build)
RUN cargo install cargo-chef
WORKDIR /app

FROM chef AS planner
COPY . .
RUN cargo chef prepare --recipe-path recipe.json

FROM chef AS builder
COPY --from=planner /app/recipe.json recipe.json
# build docker caching layer
RUN cargo chef cook --release --recipe-path recipe.json

# build binary
COPY . .
RUN cargo build --release --target x86_64-unknown-linux-gnu

# distroless image; launch app
FROM gcr.io/distroless/cc
COPY --from=builder /app/target/x86_64-unknown-linux-gnu/release/aws_rust_cluster /bin/aws_rust_cluster
ENTRYPOINT [ "/bin/aws_rust_cluster" ]
13 changes: 13 additions & 0 deletions examples/aws-rust-cluster/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Rust Docker Service

A simple example of running a slim rust docker image on ion. Of course the Dockerfile can be configured to do anything, but
in this example it utilizes [cargo chef](https://github.com/LukeMathWalker/cargo-chef) to make use of Docker layers to speed up
the builds.

You will need docker running for this example to work. Also included is a `docker-compose.yml` for convenience of running the image locally, but it is not needed for deploying via sst.

Simply using the typical
```sh
sst deploy --stage production
```
will deploy the image
9 changes: 9 additions & 0 deletions examples/aws-rust-cluster/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
services:
api:
build:
context: .
dockerfile: ./Dockerfile
ports:
- 80:80
expose:
- 80
19 changes: 19 additions & 0 deletions examples/aws-rust-cluster/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "aws-rust-cluster",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"@types/aws-lambda": "8.10.145",
"sst": "^3.0.80",
"sst-linux-x64": "^3.0.80"
},
"dependencies": {
"sst": "3.0.80"
}
}
29 changes: 29 additions & 0 deletions examples/aws-rust-cluster/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use anyhow::Result;
use axum::{http::StatusCode, response::IntoResponse, routing::get, Json, Router};
use serde::Serialize;
use tokio::net::TcpListener;

#[derive(Serialize)]
pub struct Ping {
message: &'static str,
}

pub async fn ping() -> impl IntoResponse {
(
StatusCode::IM_A_TEAPOT,
Json(Ping {
message: "hello from rust :)",
}),
)
}

#[tokio::main]
async fn main() -> Result<()> {
let api = Router::new().route("/", get(ping));
let addr = match cfg!(debug_assertions) {
true => "0.0.0.0:3000",
false => "0.0.0.0:80",
};
let listener = TcpListener::bind(addr).await?;
Ok(axum::serve(listener, api).await?)
}
8 changes: 8 additions & 0 deletions examples/aws-rust-cluster/sst-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* tslint:disable */
/* eslint-disable */
import "sst"
declare module "sst" {
export interface Resource {
}
}
export {}
36 changes: 36 additions & 0 deletions examples/aws-rust-cluster/sst.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/// <reference path="./.sst/platform/config.d.ts" />

export default $config({
app(input) {
return {
name: "aws-rust-cluster",
removal: input?.stage === "production" ? "retain" : "remove",
home: "aws",
providers: {
aws: { region: "us-east-1" }
},
};
},
async run() {
const vpc = new sst.aws.Vpc("MyVpc", { nat: "gateway" });
const cluster = new sst.aws.Cluster("MyCluster", { vpc });

const service = cluster.addService("MyService", {
image: {
context: "./",
dockerfile: "Dockerfile",
},
public: {
domain: "rust.dockerfile.dev.sst.dev",
ports: [
{ listen: "80/http" },
{ listen: "443/https", forward: "80/http" }
],
},
});

return {
url: service.url
}
}
});
1 change: 1 addition & 0 deletions examples/aws-rust-cluster/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}

0 comments on commit d1d16f1

Please sign in to comment.