Templates: embed the templates in-binary

Rocket's templating is not exactly friendly when it comes to embedding
in-binary. Rocket's template fairing requires a `template_dir` directory
pointing to the directory containing templates.
A quick workaround to this would be to have custom fairings with
`template_dir` merged with the value `.`
But in bare-metal scenarios like what docker's scratch image mimics, we
don't exactly have a '.' file, so instead for this very project, I have
to point the `template_dir` to the `upload` folder, which is created by
`bin` on execution. Checkout the Dockerfile for more info

Signed-off-by: Gunwant Jain <mail@wantguns.dev>
This commit is contained in:
Gunwant Jain
2022-01-18 21:33:03 +05:30
parent 78b4213c62
commit 3a541aed23
3 changed files with 46 additions and 20 deletions

View File

@@ -2,8 +2,6 @@
FROM rust as builder
WORKDIR /app
COPY . .
# scratch does not have the mkdir binary, so we create a folder here
RUN mkdir -p empty_upload
ARG ARCH
RUN __ARCH="$(dpkg --print-architecture)"; \
@@ -24,15 +22,11 @@ RUN cargo clean
###### Runner Image
FROM scratch as runner
COPY --from=builder /app/empty_upload upload
COPY ./contrib/cli/client upload/client
COPY ./templates templates
COPY ./static static
COPY ./themes themes
COPY --from=builder /usr/local/cargo/bin/bin .
ENV ROCKET_ADDRESS=0.0.0.0
ENV ROCKET_PORT=6162
ENV BIN_ADDRESS=0.0.0.0
# Some hax required since we are running on scratch
ENV BIN_TEMPLATE_DIR=upload
EXPOSE 6162
CMD ["./bin"]

View File

@@ -4,9 +4,9 @@ services:
image: wantguns/bin
container_name: pastebin
ports:
- 127.0.0.1:6162:6162
- 127.0.0.1:6163:6163
environment:
- ROCKET_PORT=6162
- ROCKET_LIMITS={form="16 MiB"}
- BIN_PORT=6163
- BIN_LIMITS={form="16 MiB"}
volumes:
- ./upload:/app/upload # upload folder will have your pastes
- ./upload:/upload # upload folder will have your pastes

View File

@@ -3,12 +3,35 @@ extern crate rocket;
use std::{fs, net::IpAddr, path::PathBuf};
use clap::Parser;
use rocket::shield::{NoSniff, Shield};
use rocket_dyn_templates::Template;
use rocket::{shield::{NoSniff, Shield}, figment::{providers::Env, Figment}};
use rocket_dyn_templates::{tera::Tera, Template};
use rust_embed::RustEmbed;
mod models;
mod routes;
#[derive(RustEmbed)]
#[folder = "templates/"]
struct EmbeddedTemplates;
fn setup_tera_engine(tera: &mut Tera) {
// Register templates
let base_html = EmbeddedTemplates::get("base.html.tera").unwrap();
let index_html = EmbeddedTemplates::get("index.html.tera").unwrap();
let pretty_html = EmbeddedTemplates::get("pretty.html.tera").unwrap();
// and shove them in the tera instance
tera.add_raw_templates(vec![
("base", std::str::from_utf8(&base_html.data).unwrap()),
("index", std::str::from_utf8(&index_html.data).unwrap()),
(
"pretty",
std::str::from_utf8(&pretty_html.data).unwrap(),
),
])
.expect("Could not add raw templates to the tera instance");
}
/// A minimal, opinionated pastebin
#[derive(Parser, Debug)]
#[clap(author, version, about, long_about=None)]
@@ -22,7 +45,7 @@ pub struct Args {
port: u16,
/// Address on which the webserver runs
#[clap(short, long, default_value = "0.0.0.0")]
#[clap(short, long, default_value = "127.0.0.1")]
address: IpAddr,
/// Binary uploads file size limit (in MiB)
@@ -40,14 +63,21 @@ pub fn get_upload_dir() -> PathBuf {
#[launch]
fn rocket() -> _ {
let shield = Shield::default().disable::<NoSniff>();
let args = get_parsed_args();
// Custom Fairings and Providers
let shield = Shield::default().disable::<NoSniff>();
let figment = Figment::from(rocket::Config::default())
.merge(("port", args.port))
.merge(("address", args.address))
.merge(("template_dir", ".")) // Required if embedding templates
.merge(Env::prefixed("BIN_").global());
// create the upload directory, if not already created
fs::create_dir_all(args.upload)
.expect("Could not create the upload directory");
rocket::build()
rocket::custom(figment)
.mount(
"/",
routes![
@@ -62,5 +92,7 @@ fn rocket() -> _ {
],
)
.attach(shield)
.attach(Template::fairing())
.attach(Template::custom(|engines| {
setup_tera_engine(&mut engines.tera)
}))
}