Application can now run as Docker container.
This commit is contained in:
Generated
+1
@@ -3235,6 +3235,7 @@ dependencies = [
|
||||
"lettre",
|
||||
"log",
|
||||
"pwhash",
|
||||
"rand",
|
||||
"regex",
|
||||
"rust_decimal",
|
||||
"serde",
|
||||
|
||||
@@ -41,6 +41,7 @@ leptos-captcha = "0.2.0"
|
||||
charts-rs = { version = "0.3.5", optional = true}
|
||||
#image = { version = "0.24.8", optional = true }
|
||||
base64 = "0.22.0"
|
||||
rand = "0.8.5"
|
||||
|
||||
[features]
|
||||
csr = ["leptos/csr", "leptos_meta/csr", "leptos_router/csr"]
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
FROM rust:1.86.0-bookworm AS builder
|
||||
|
||||
# Install cargo-binstall, which makes it easier to install other
|
||||
# cargo extensions like cargo-leptos
|
||||
RUN wget https://github.com/cargo-bins/cargo-binstall/releases/latest/download/cargo-binstall-x86_64-unknown-linux-musl.tgz
|
||||
RUN tar -xvf cargo-binstall-x86_64-unknown-linux-musl.tgz
|
||||
RUN cp cargo-binstall /usr/local/cargo/bin
|
||||
|
||||
# Install required tools
|
||||
RUN apt-get update -y \
|
||||
&& apt-get install -y --no-install-recommends clang
|
||||
|
||||
# Install cargo-leptos
|
||||
RUN cargo binstall cargo-leptos -y
|
||||
|
||||
RUN rustup default stable
|
||||
|
||||
# Add the WASM target
|
||||
RUN rustup target add wasm32-unknown-unknown
|
||||
#RUN rustup target add wasm32-unknown-unknown --toolchain nightly
|
||||
|
||||
|
||||
# Make an /app dir, which everything will eventually live in
|
||||
RUN mkdir -p /app
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
|
||||
# Build the app
|
||||
#RUN cargo leptos build --release -vv
|
||||
RUN LEPTOS_OUTPUT_NAME="rezervator-$(tr -dc a-z0-9 </dev/urandom | head -c 10)" cargo leptos build -r -P
|
||||
|
||||
FROM debian:bookworm-slim AS runtime
|
||||
WORKDIR /app
|
||||
RUN apt-get update -y \
|
||||
&& apt-get install -y --no-install-recommends openssl ca-certificates \
|
||||
&& apt-get autoremove -y \
|
||||
&& apt-get clean -y \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Copy the server binary to the /app directory
|
||||
COPY --from=builder /app/target/release/rezervator /app/
|
||||
|
||||
# /target/site contains our JS/WASM/CSS, etc.
|
||||
COPY --from=builder /app/target/site /app/target/site
|
||||
|
||||
# Set any required env variables and
|
||||
EXPOSE 3000
|
||||
|
||||
# -- NB: update binary name from "leptos_start" to match your app name in Cargo.toml --
|
||||
# Run the server
|
||||
CMD ["/app/rezervator", "-c /app/target/site/data/config.toml"]
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE appearance ADD css_name VARCHAR;
|
||||
@@ -6,6 +6,7 @@ use crate::components::data_form::ForValidation;
|
||||
|
||||
cfg_if! { if #[cfg(feature = "ssr")] {
|
||||
|
||||
use std::fs;
|
||||
use actix_web::{post, Responder};
|
||||
use actix_multipart::Multipart;
|
||||
use actix_session::Session;
|
||||
@@ -20,6 +21,8 @@ cfg_if! { if #[cfg(feature = "ssr")] {
|
||||
use actix_web::web::Data;
|
||||
use crate::backend::AppData;
|
||||
use regex::Regex;
|
||||
use rand::Rng;
|
||||
use rand::distributions::Alphanumeric;
|
||||
|
||||
pub async fn check_appearance(pool: &PgPool) -> Result<(), AppError> {
|
||||
let count: (i64,) = query_as("SELECT COUNT(id) FROM appearance")
|
||||
@@ -32,6 +35,11 @@ cfg_if! { if #[cfg(feature = "ssr")] {
|
||||
.await?;
|
||||
}
|
||||
|
||||
let app = query_as::<_, Appearance>("SELECT * FROM appearance").fetch_one(pool).await?;
|
||||
if let None = app.css_name {
|
||||
query("UPDATE appearance SET css_name = 'banner.css'").execute(pool).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -44,8 +52,8 @@ cfg_if! { if #[cfg(feature = "ssr")] {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn modify_style(file_name: &str) -> Result<(), AppError> {
|
||||
let mut css_file = File::open("target/site/banner.css")?;
|
||||
async fn modify_style(file_name: &str, pool: &PgPool) -> Result<(), AppError> {
|
||||
let mut css_file = File::open("target/site/data/banner.css")?;
|
||||
let mut css_str= String::new();
|
||||
css_file.read_to_string(&mut css_str)?;
|
||||
|
||||
@@ -56,8 +64,26 @@ cfg_if! { if #[cfg(feature = "ssr")] {
|
||||
css_str = re.replace(&css_str, &format!("background-image: url('{}')", file_name)).to_string();
|
||||
}
|
||||
|
||||
let mut css_file = File::create("target/site/banner.css")?;
|
||||
let old_css: (String,) = query_as("SELECT css_name FROM appearance")
|
||||
.fetch_one(pool)
|
||||
.await?;
|
||||
|
||||
if old_css.0 != "banner.css" {
|
||||
fs::remove_file(format!("target/site/data/{}", old_css.0))?;
|
||||
}
|
||||
|
||||
let s: String = rand::thread_rng()
|
||||
.sample_iter(&Alphanumeric)
|
||||
.take(5)
|
||||
.map(char::from)
|
||||
.collect();
|
||||
let css_name = format!("banner-{}.css", s);
|
||||
let mut css_file = File::create(format!("target/site/data/{}", css_name))?;
|
||||
css_file.write_all(css_str.as_bytes())?;
|
||||
query("UPDATE appearance SET css_name = $1")
|
||||
.bind(css_name)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -84,14 +110,14 @@ cfg_if! { if #[cfg(feature = "ssr")] {
|
||||
return Redirect::to("/admin/appearance").see_other();
|
||||
}
|
||||
|
||||
let mut file = File::create(format!("target/site/{}", file_name)).unwrap();
|
||||
let mut file = File::create(format!("target/site/data/{}", file_name)).unwrap();
|
||||
let _name = field.name();
|
||||
while let Some(chunk) = field.next().await {
|
||||
let c = chunk.unwrap();
|
||||
let _ = file.write_all(&c);
|
||||
}
|
||||
let _ = set_banner_name(&file_name, &app_data.db_pool).await;
|
||||
let _ = modify_style(&file_name).await;
|
||||
let _ = modify_style(&file_name, &app_data.db_pool).await;
|
||||
}
|
||||
|
||||
Redirect::to("/admin/appearance").see_other()
|
||||
@@ -149,7 +175,7 @@ pub async fn delete_banner() -> Result<ApiResponse<()>, ServerFnError> {
|
||||
.await?;
|
||||
|
||||
if let Some(f) = appearance.banner {
|
||||
fs::remove_file(format!("target/site/{}", f))?;
|
||||
fs::remove_file(format!("target/site/data/{}", f))?;
|
||||
}
|
||||
|
||||
Ok(ApiResponse::Data(()))
|
||||
|
||||
+2
-1
@@ -719,7 +719,8 @@ pub struct Appearance {
|
||||
id: i32,
|
||||
pub banner: Option<String>,
|
||||
pub text: Option<String>,
|
||||
pub title: Option<String>
|
||||
pub title: Option<String>,
|
||||
pub css_name: Option<String>
|
||||
}
|
||||
|
||||
impl Appearance {
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
use leptos::*;
|
||||
use leptos_meta::*;
|
||||
use crate::app::DialogHelper;
|
||||
use crate::backend::appearance::get_appearance;
|
||||
use crate::components::user_menu::MenuOpener;
|
||||
|
||||
#[component]
|
||||
pub fn Header() -> impl IntoView {
|
||||
let drawer = use_context::<MenuOpener>().expect("No drawer opener");
|
||||
let dlg_helper = use_context::<DialogHelper>().expect("No dialog helper");
|
||||
//let banner_css = create_signal(String::new());
|
||||
let appearance = create_blocking_resource(||(), |_| get_appearance());
|
||||
|
||||
view! {
|
||||
<Html
|
||||
@@ -39,7 +40,14 @@ pub fn Header() -> impl IntoView {
|
||||
<Link rel="stylesheet" href="/vendor/css/core.css" />
|
||||
<Link rel="stylesheet" href="/vendor/css/theme-default.css" />
|
||||
<Link rel="stylesheet" href="/css/demo.css" />
|
||||
<Link rel="stylesheet" href="/banner.css" />
|
||||
<Transition fallback=move || view! {""}>
|
||||
{
|
||||
appearance.get().map(|a| match a {
|
||||
Ok(a) => view! {<Link rel="stylesheet" href={format!("/data/{}", a.css_name.unwrap_or_default())} />},
|
||||
Err(_) => view! {<Link rel="stylesheet" href="/data/banner.css" />}
|
||||
})
|
||||
}
|
||||
</Transition>
|
||||
<Link rel="stylesheet" href="/vendor/css/control.css" />
|
||||
|
||||
//<!-- Vendors CSS -->
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ async fn main() -> std::io::Result<()> {
|
||||
Pow::init_random().expect("Cannot init captcha");
|
||||
|
||||
let cfg_path = matches.opt_str("c").unwrap_or("config.toml".to_string());
|
||||
let srv_conf = load_config(&cfg_path);
|
||||
let srv_conf = load_config(cfg_path.trim());
|
||||
|
||||
env_logger::Builder::from_env(Env::default().default_filter_or(srv_conf.logging().severity())).init();
|
||||
info!("Starting server");
|
||||
|
||||
Reference in New Issue
Block a user