Runtime Adapters and TLS
Runtime Adapters
Let's talk a little more about that trillium_smol::run
line we've
been writing. Trillium itself is built on futures
(futures-lite
,
specifically). In order to run it, it needs an adapter to an async
runtime. There there are four of these
currently:
Although we've been using the smol adapter in these docs thus far, you should use whichever runtime you prefer. If you expect to have a dependency on async-std or tokio anyway, you might as well use the adapter for that runtime. If you're new to async rust or don't have an opinion, I recommend starting with trillium_smol. It is easy to switch trillium between runtimes at any point.
12-Factor by default, but overridable
Trillium seeks to abide by a 12 factor approach to configuration, accepting configuration from the environment wherever possible. The number of configuration points that can be customized through environment variables will likely increase over time.
To run trillium on a different host or port, either provide a HOST
and/or PORT
environment variables, or compile the specific values
into the application as follows:
pub fn main() {
trillium_smol::config()
.with_port(1337)
.with_host("127.0.0.1")
.run(|conn: trillium::Conn| async move { conn.ok("hello world") })
}
In addition to accepting the HOST
and PORT
configuration from the environment, on cfg(unix) systems, trillium will also pick up a LISTEN_FD
environment variable for use with catflap/systemfd. On cfg(unix)
systems, if the HOST
begins with .
, /
, or ~
, it is interpreted as a path and bound as a unix domain socket.
For more documentation on the default values and what configuration can be chained onto config(), see trillium_server_common::Config.
TLS / HTTPS
With the exception of aws lambda, which provides its own tls
termination at the load balancer, each of the above servers can be
combined with either rustls or native-tls, or with trillium-acme
to register
a certificate automatically with an ACME certificate provider like Let's
Encrypt.
Rustls:
use trillium::Conn;
use trillium_rustls::RustlsAcceptor;
const KEY: &[u8] = include_bytes!("./key.pem");
const CERT: &[u8] = include_bytes!("./cert.pem");
pub fn main() {
env_logger::init();
trillium_smol::config()
.with_acceptor(RustlsAcceptor::from_single_cert(CERT, KEY))
.run(|conn: Conn| async move { conn.ok("ok") });
}
Native tls:
use trillium::Conn;
use trillium_native_tls::NativeTlsAcceptor;
pub fn main() {
env_logger::init();
let acceptor = NativeTlsAcceptor::from_pkcs12(include_bytes!("./identity.p12"), "changeit");
trillium_smol::config()
.with_acceptor(acceptor)
.run(|conn: Conn| async move { conn.ok("ok") });
}
Automatic HTTPS via Let's Encrypt:
See the trillium-acme
documentation for examples.