use anyhow::Result; use axum::middleware::from_fn; use bollard::Docker; use clap::Parser; use std::net::SocketAddr; use crate::http::response::response_interceptor; mod http; mod route; mod stack; /// GitOps+WebUI for arion-based stacks #[derive(Parser, Debug)] #[command(author, version, about, long_about = None)] struct Args { /// Path to root of stacks #[arg(short = 'd', long = "stack-dir", env = "STAX_DIR")] stack_dir: String, /// Address:port to bind #[arg(short, long, default_value = "0.0.0.0:3000", env = "STAX_BIND")] bind: SocketAddr, } #[derive(Clone)] pub struct AppState { pub stack_dir: String, pub docker: Docker, } #[tokio::main] async fn main() -> Result<()> { // Initialize logging and env _ = dotenvy::dotenv(); tracing_subscriber::fmt::init(); // Try to connect to docker server let docker = Docker::connect_with_local_defaults()?; // Ping to make sure it works let version = docker.version().await?; tracing::info!("docker version: {}", version.version.unwrap()); // Parse args let args = Args::parse(); tracing::info!("listening on {}", &args.bind); let state = AppState { stack_dir: args.stack_dir, docker, }; let app = route::router() .with_state(state) .layer(from_fn(response_interceptor)); axum::Server::bind(&args.bind) .serve(app.into_make_service()) .await?; Ok(()) }