From 597edf6a5966ccc1802909a867ef7350e2a4390b Mon Sep 17 00:00:00 2001 From: tobinio Date: Tue, 28 Jul 2026 14:30:17 +0200 Subject: [PATCH] add env config --- README.md | 3 +++ backend/.env | 1 + backend/Cargo.lock | 7 +++++++ backend/Cargo.toml | 2 ++ backend/src/config.rs | 35 +++++++++++++++++++++++++++++++++++ backend/src/lib.rs | 17 ++++++++++------- backend/src/main.rs | 12 +++++++++--- backend/src/web/mod.rs | 6 +++--- 8 files changed, 70 insertions(+), 13 deletions(-) create mode 100644 backend/.env create mode 100644 backend/src/config.rs diff --git a/README.md b/README.md index 511d96a..4d2c158 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,10 @@ systemd.services.lightcontrol = { ExecStart = "${inputs.lightcontrol.packages.${pkgs.system}.backend}/bin/backend"; Environment = [ + "DEVICE_STORAGE_PATH=/srv/lightcontrol/devices" "STATIC_FILES_DIR=${inputs.lightcontrol.packages.${pkgs.system}.frontend}" + "WEB_PORT=8080" + "TCP_PORT=1234" ]; }; }; diff --git a/backend/.env b/backend/.env new file mode 100644 index 0000000..2e160c2 --- /dev/null +++ b/backend/.env @@ -0,0 +1 @@ +WEB_PORT=8081 diff --git a/backend/Cargo.lock b/backend/Cargo.lock index d4614ac..fdec7e2 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -81,6 +81,7 @@ version = "0.1.0" dependencies = [ "axum", "color-eyre", + "dotenvy", "packets", "serde", "serde_json", @@ -151,6 +152,12 @@ dependencies = [ "tracing-error", ] +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + [[package]] name = "eyre" version = "0.6.12" diff --git a/backend/Cargo.toml b/backend/Cargo.toml index bcde211..1cc7470 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -18,3 +18,5 @@ tracing = "0.1.44" tracing-subscriber = "0.3.23" serde = { version = "1.0.228", features = ["derive"] } serde_json = "1.0.150" + +dotenvy = "0.15.7" diff --git a/backend/src/config.rs b/backend/src/config.rs new file mode 100644 index 0000000..483a41b --- /dev/null +++ b/backend/src/config.rs @@ -0,0 +1,35 @@ +use std::env; + +use color_eyre::eyre::Result; +use dotenvy::dotenv; + +pub struct Config { + pub device_storage_path: String, + pub static_files_dir: String, + pub web_port: u16, + pub tcp_port: u16, +} + +impl Config { + pub fn load() -> Result { + let _ = dotenv(); + + let device_storage_path = + env::var("DEVICE_STORAGE_PATH").unwrap_or("./devices.json".to_string()); + let static_files_dir = + env::var("STATIC_FILES_DIR").unwrap_or("../frontend/dist".to_string()); + let web_port = env::var("WEB_PORT") + .map(|v| v.parse()) + .unwrap_or(Ok(8080))?; + let tcp_port = env::var("TCP_PORT") + .map(|v| v.parse()) + .unwrap_or(Ok(1234))?; + + Ok(Self { + device_storage_path, + static_files_dir, + web_port, + tcp_port, + }) + } +} diff --git a/backend/src/lib.rs b/backend/src/lib.rs index a178232..9479c57 100644 --- a/backend/src/lib.rs +++ b/backend/src/lib.rs @@ -2,6 +2,7 @@ use color_eyre::eyre; use tokio::net::TcpListener; use tracing::info; +use crate::config::Config; use crate::device_storage::DeviceStorage; use crate::tcp::receive_device_update_events; use crate::tcp::registration::receive_register_events; @@ -12,15 +13,17 @@ pub mod tcp; pub mod time; pub mod web; +pub mod config; + #[derive(Clone)] pub struct AppState { pub device_storage: DeviceStorage, pub device_change_events: tokio::sync::broadcast::Sender, } -pub async fn run_tcp(state: AppState) -> eyre::Result<()> { - info!("Starting TCP Server"); - let listener = TcpListener::bind("0.0.0.0:1234".to_string()).await?; +pub async fn run_tcp(state: AppState, config: &Config) -> eyre::Result<()> { + info!("Starting TCP Server - port {}", config.tcp_port); + let listener = TcpListener::bind(format!("0.0.0.0:{}", config.tcp_port)).await?; tokio::try_join!( receive_register_events(listener, state.clone()), @@ -30,11 +33,11 @@ pub async fn run_tcp(state: AppState) -> eyre::Result<()> { Ok(()) } -pub async fn run_http(state: AppState) -> eyre::Result<()> { - let app = app(state).await?; +pub async fn run_http(state: AppState, config: &Config) -> eyre::Result<()> { + let app = app(state, config).await?; - info!("Starting Web Server"); - let listener = TcpListener::bind("0.0.0.0:8080".to_string()) + info!("Starting Web Server - port {}", config.web_port); + let listener = TcpListener::bind(format!("0.0.0.0:{}", config.web_port)) .await .expect("failed to bind listener"); diff --git a/backend/src/main.rs b/backend/src/main.rs index deb80b6..bb388f2 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -1,19 +1,25 @@ use std::path::Path; -use backend::{AppState, device_storage::DeviceStorage, run_http, run_tcp}; +use backend::{AppState, config::Config, device_storage::DeviceStorage, run_http, run_tcp}; use color_eyre::eyre; use tracing::Level; #[tokio::main] async fn main() -> eyre::Result<()> { + let config = Config::load()?; + tracing_subscriber::fmt().with_max_level(Level::INFO).init(); let (device_change_events, _) = tokio::sync::broadcast::channel(8); let state = AppState { - device_storage: DeviceStorage::load(Path::new("./devices.json").to_path_buf()).await?, + device_storage: DeviceStorage::load(Path::new(&config.device_storage_path).to_path_buf()) + .await?, device_change_events, }; - tokio::try_join!(run_http(state.clone()), run_tcp(state.clone()))?; + tokio::try_join!( + run_http(state.clone(), &config), + run_tcp(state.clone(), &config) + )?; Ok(()) } diff --git a/backend/src/web/mod.rs b/backend/src/web/mod.rs index fa26072..1b4eecc 100644 --- a/backend/src/web/mod.rs +++ b/backend/src/web/mod.rs @@ -13,15 +13,15 @@ use tower_http::{ trace::TraceLayer, }; -use crate::{AppState, device_storage::Mode}; +use crate::{AppState, config::Config, device_storage::Mode}; -pub async fn app(state: AppState) -> eyre::Result { +pub async fn app(state: AppState, config: &Config) -> eyre::Result { let app = Router::new() .route("/api/health", get(health_check)) .route("/api/devices", get(get_devices)) .route("/api/device", post(update_device)) .with_state(state) - .fallback_service(ServeDir::new("../frontend/dist")) + .fallback_service(ServeDir::new(&config.static_files_dir)) .layer( ServiceBuilder::new() .layer(TraceLayer::new_for_http()) -- 2.51.2