feat: initial server config & Dockerfile

This commit is contained in:
Ryan Walters
2025-09-16 22:13:35 -05:00
parent 7ede82cc5d
commit f69a5c7d52
9 changed files with 2389 additions and 42 deletions
+67
View File
@@ -0,0 +1,67 @@
use figment::{providers::Env, value::UncasedStr, Figment};
use serde::{Deserialize, Deserializer};
#[derive(Debug, Deserialize)]
pub struct Config {
// Database URL
pub database_url: String,
// Discord Credentials
#[serde(deserialize_with = "deserialize_string_from_any")]
pub discord_client_id: String,
pub discord_client_secret: String,
// GitHub Credentials
#[serde(deserialize_with = "deserialize_string_from_any")]
pub github_client_id: String,
pub github_client_secret: String,
// S3 Credentials
pub s3_access_key: String,
pub s3_secret_access_key: String,
pub s3_endpoint: String,
pub s3_region: String,
// Server Details
#[serde(default = "default_port")]
pub port: u16,
#[serde(default = "default_host")]
pub host: std::net::IpAddr,
#[serde(default = "default_shutdown_timeout")]
pub shutdown_timeout_seconds: u32,
}
fn default_host() -> std::net::IpAddr {
"0.0.0.0".parse().unwrap()
}
fn default_port() -> u16 {
3000
}
fn default_shutdown_timeout() -> u32 {
5
}
fn deserialize_string_from_any<'de, D>(deserializer: D) -> Result<String, D::Error>
where
D: Deserializer<'de>,
{
use serde_json::Value;
let value = Value::deserialize(deserializer)?;
match value {
Value::String(s) => Ok(s),
Value::Number(n) => Ok(n.to_string()),
_ => Err(serde::de::Error::custom("Expected string or number")),
}
}
pub fn load_config() -> Config {
Figment::new()
.merge(Env::raw().map(|key| {
if key == UncasedStr::new("RAILWAY_DEPLOYMENT_DRAINING_SECONDS") {
"SHUTDOWN_TIMEOUT".into()
} else {
key.into()
}
}))
.extract()
.expect("Failed to load config")
}
+1
View File
@@ -0,0 +1 @@
+22 -2
View File
@@ -1,3 +1,23 @@
fn main() {
println!("Hello, world!");
use axum::Router;
use crate::config::Config;
mod config;
#[tokio::main]
async fn main() {
// Load environment variables
#[cfg(debug_assertions)]
dotenvy::from_path(format!("{}.env", env!("CARGO_MANIFEST_DIR"))).ok();
#[cfg(not(debug_assertions))]
dotenvy::dotenv().ok();
// Load configuration
let config: Config = config::load_config();
let app = Router::new().fallback(|| async { "Hello, World!" });
let addr = std::net::SocketAddr::new(config.host, config.port);
let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
axum::serve(listener, app).await.unwrap();
}