From 1b489776c53c437cb41c51642d6f8ac4e6e39bc0 Mon Sep 17 00:00:00 2001 From: Lewis Date: Thu, 18 Jun 2026 09:09:58 +0300 Subject: [PATCH] server healthcheck in-bin Lewis: May this revision serve well! --- crates/tranquil-server/Cargo.toml | 1 + crates/tranquil-server/src/main.rs | 37 ++++++++++++++++++++++++++++++ docker-compose.prod.yaml | 2 +- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/crates/tranquil-server/Cargo.toml b/crates/tranquil-server/Cargo.toml index 86173ce..f31f0df 100644 --- a/crates/tranquil-server/Cargo.toml +++ b/crates/tranquil-server/Cargo.toml @@ -26,6 +26,7 @@ http = { workspace = true } hyper = { workspace = true } hyper-util = { workspace = true } quinn = { workspace = true } +reqwest = { workspace = true } rustls = { workspace = true } rustls-pemfile = { workspace = true } thiserror = { workspace = true } diff --git a/crates/tranquil-server/src/main.rs b/crates/tranquil-server/src/main.rs index d13514f..8525d7c 100644 --- a/crates/tranquil-server/src/main.rs +++ b/crates/tranquil-server/src/main.rs @@ -34,6 +34,7 @@ enum Command { ignore_secrets: bool, }, ConfigTemplate, + Healthcheck, } #[tokio::main] @@ -44,6 +45,7 @@ async fn main() -> ExitCode { if let Some(command) = &cli.command { return match command { + Command::Healthcheck => healthcheck(cli.config.as_ref()).await, Command::ConfigTemplate => { print!("{}", tranquil_config::template()); ExitCode::SUCCESS @@ -101,6 +103,41 @@ async fn main() -> ExitCode { } } +async fn healthcheck(config: Option<&PathBuf>) -> ExitCode { + let cfg = match tranquil_config::load(config) { + Ok(cfg) => cfg, + Err(e) => { + eprintln!("Failed to load configuration: {e:#}"); + return ExitCode::FAILURE; + } + }; + let tls = cfg.server.tls.material().is_some(); + let scheme = if tls { "https" } else { "http" }; + let url = format!("{scheme}://localhost:{}/xrpc/_health", cfg.server.port); + let client = match reqwest::Client::builder() + .danger_accept_invalid_certs(tls) + .timeout(std::time::Duration::from_secs(5)) + .build() + { + Ok(client) => client, + Err(e) => { + eprintln!("Failed to build healthcheck client: {e}"); + return ExitCode::FAILURE; + } + }; + match client.get(&url).send().await { + Ok(response) if response.status().is_success() => ExitCode::SUCCESS, + Ok(response) => { + eprintln!("Healthcheck returned {}", response.status()); + ExitCode::FAILURE + } + Err(e) => { + eprintln!("Healthcheck request failed: {e}"); + ExitCode::FAILURE + } + } +} + async fn run() -> Result<(), Box> { let shutdown = CancellationToken::new(); diff --git a/docker-compose.prod.yaml b/docker-compose.prod.yaml index f03a204..2176aeb 100644 --- a/docker-compose.prod.yaml +++ b/docker-compose.prod.yaml @@ -13,7 +13,7 @@ services: db: condition: service_healthy healthcheck: - test: ["CMD", "wget", "-q", "--spider", "http://localhost:3000/xrpc/_health"] + test: ["CMD", "tranquil-pds", "healthcheck"] interval: 30s timeout: 10s retries: 3