mirror of
https://github.com/actix/actix-website
synced 2024-11-24 00:41:07 +01:00
Add hosting instructions for Shuttle (#334)
* Add hosting instructions for Shuttle * move shuttle sample code to examples dir --------- Co-authored-by: Rob Ede <robjtede@icloud.com>
This commit is contained in:
parent
411a64afd3
commit
e72b12218a
43
docs/shuttle.md
Normal file
43
docs/shuttle.md
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
---
|
||||||
|
title: Hosting on Shuttle
|
||||||
|
---
|
||||||
|
|
||||||
|
import CodeBlock from '@site/src/components/code_block.js';
|
||||||
|
|
||||||
|
# Hosting on Shuttle
|
||||||
|
|
||||||
|
<img width="300" src="https://raw.githubusercontent.com/shuttle-hq/shuttle/master/assets/logo-rectangle-transparent.png"/>
|
||||||
|
|
||||||
|
> [**Shuttle**](https://www.shuttle.rs) is a Rust-native cloud development platform that lets you deploy your Rust apps for free.
|
||||||
|
|
||||||
|
Shuttle has out-of-the-box support for Actix Web. Follow these steps to host your web service on Shuttle:
|
||||||
|
|
||||||
|
1. Add Shuttle dependencies to `Cargo.toml`:
|
||||||
|
|
||||||
|
<CodeBlock example="shuttle" file="manifest" section="shuttle-deps" language="toml" />
|
||||||
|
|
||||||
|
2. Add the `#[shuttle_runtime::main]` annotation and update the `main` function as follows:
|
||||||
|
|
||||||
|
<CodeBlock example="shuttle" section="shuttle-hello-world" />
|
||||||
|
|
||||||
|
3. Install `cargo-shuttle`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cargo install cargo-shuttle
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Create your project on the Shuttle platform:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cargo shuttle project start
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Deploy! 🚀
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cargo shuttle deploy
|
||||||
|
```
|
||||||
|
|
||||||
|
You can run `cargo shuttle run` to test your application locally.
|
||||||
|
|
||||||
|
Check out some complete Actix Web examples [here](https://github.com/shuttle-hq/shuttle-examples/tree/main/actix-web).
|
@ -19,6 +19,7 @@ members = [
|
|||||||
"responder-trait",
|
"responder-trait",
|
||||||
"responses",
|
"responses",
|
||||||
"server",
|
"server",
|
||||||
|
"shuttle",
|
||||||
"static-files",
|
"static-files",
|
||||||
"testing",
|
"testing",
|
||||||
"url-dispatch",
|
"url-dispatch",
|
||||||
|
12
examples/shuttle/Cargo.toml
Normal file
12
examples/shuttle/Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[package]
|
||||||
|
name = "shuttle"
|
||||||
|
version = "1.0.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# <shuttle-deps>
|
||||||
|
[dependencies]
|
||||||
|
actix-web = "4"
|
||||||
|
shuttle-actix-web = "0.30"
|
||||||
|
shuttle-runtime = "0.30"
|
||||||
|
tokio = "1"
|
||||||
|
# </shuttle-deps>
|
19
examples/shuttle/src/main.rs
Normal file
19
examples/shuttle/src/main.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#[get("/")]
|
||||||
|
async fn hello_world() -> impl actix_web::Responder {
|
||||||
|
"hello world"
|
||||||
|
}
|
||||||
|
|
||||||
|
// <shuttle-hello-world>
|
||||||
|
use actix_web::{get, web::ServiceConfig};
|
||||||
|
use shuttle_actix_web::ShuttleActixWeb;
|
||||||
|
|
||||||
|
#[shuttle_runtime::main]
|
||||||
|
async fn main() -> ShuttleActixWeb<impl FnOnce(&mut ServiceConfig) + Send + Clone + 'static> {
|
||||||
|
let config = move |cfg: &mut ServiceConfig| {
|
||||||
|
// set up your service here, e.g.:
|
||||||
|
cfg.service(hello_world);
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(config.into())
|
||||||
|
}
|
||||||
|
// </shuttle-hello-world>
|
@ -18,7 +18,7 @@ module.exports = {
|
|||||||
'static-files',
|
'static-files',
|
||||||
],
|
],
|
||||||
Protocols: ['websockets', 'http2'],
|
Protocols: ['websockets', 'http2'],
|
||||||
Patterns: ['autoreload', 'databases'],
|
Patterns: ['autoreload', 'databases', 'shuttle'],
|
||||||
Diagrams: ['http_server_init', 'conn_lifecycle'],
|
Diagrams: ['http_server_init', 'conn_lifecycle'],
|
||||||
Actix: [
|
Actix: [
|
||||||
'actix/sec-0-quick-start',
|
'actix/sec-0-quick-start',
|
||||||
|
@ -1,27 +1,37 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import RenderCodeBlock from '@theme/CodeBlock';
|
import RenderCodeBlock from '@theme/CodeBlock';
|
||||||
|
|
||||||
const CodeBlock = ({ example, file, section }) => {
|
const CodeBlock = ({ example, file, section, language }) => {
|
||||||
const [code, setCode] = useState("");
|
const [code, setCode] = useState('');
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let isMounted = true;
|
let isMounted = true;
|
||||||
import(`!!raw-loader!@site/examples/${example}/src/${file || "main.rs"}`)
|
|
||||||
.then(source => {
|
const path =
|
||||||
source = source
|
file === 'manifest' ? 'Cargo.toml' : `src/${file ?? 'main.rs'}`;
|
||||||
.default
|
|
||||||
.match(new RegExp(`\/\/ <${section}>\n([\\s\\S]*)\/\/ <\/${section}>`))[1];
|
import(`!!raw-loader!@site/examples/${example}/${path}`)
|
||||||
if (isMounted) setCode(source)
|
.then((source) => {
|
||||||
|
source = source.default.match(
|
||||||
|
new RegExp(
|
||||||
|
`(?:\/\/|#) <${section}>\n([\\s\\S]*)(?:\/\/|#) <\/${section}>`
|
||||||
|
)
|
||||||
|
)[1];
|
||||||
|
|
||||||
|
if (isMounted) setCode(source);
|
||||||
})
|
})
|
||||||
.catch(err => console.log(err));
|
.catch((err) => console.log(err));
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
isMounted = false;
|
isMounted = false;
|
||||||
}
|
};
|
||||||
}, [])
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RenderCodeBlock className="language-rust">{code}</RenderCodeBlock>
|
<RenderCodeBlock className={`language-${language ?? 'rust'}`}>
|
||||||
)
|
{code}
|
||||||
}
|
</RenderCodeBlock>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default CodeBlock;
|
export default CodeBlock;
|
||||||
|
Loading…
Reference in New Issue
Block a user