Fix Docker networking and add graceful MongoDB error handling
- Fix DNS resolution: Removed invalid dns_search configuration - Add graceful MongoDB connection error handling - Set restart policy to 'unless-stopped' for both services - Add development helper scripts (start-dev.sh, stop-dev.sh) - Update Docker Compose configurations for development - Restore main.rs from git history - Backend now logs MongoDB errors without crashing All containers now start successfully with proper DNS resolution on the dedicated normogen-network.
This commit is contained in:
parent
177f2ad8e7
commit
cd5c1709c6
7 changed files with 277 additions and 64 deletions
|
|
@ -1,28 +1,128 @@
|
|||
use std::fs::OpenOptions;
|
||||
use std::io::Write;
|
||||
mod config;
|
||||
mod db;
|
||||
mod models;
|
||||
mod auth;
|
||||
mod handlers;
|
||||
mod middleware;
|
||||
|
||||
fn main() {
|
||||
let msg = format!("BINARY STARTED: {}\n", chrono::Utc::now().to_rfc3339());
|
||||
use axum::{
|
||||
routing::{get, post, put, delete},
|
||||
Router,
|
||||
middleware as axum_middleware,
|
||||
};
|
||||
use tower::ServiceBuilder;
|
||||
use tower_http::{
|
||||
cors::CorsLayer,
|
||||
trace::TraceLayer,
|
||||
};
|
||||
use config::Config;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
eprintln!("NORMOGEN BACKEND STARTING...");
|
||||
eprintln!("Loading environment variables...");
|
||||
|
||||
// Try to write to file
|
||||
if let Ok(mut file) = OpenOptions::new()
|
||||
.create(true)
|
||||
.write(true)
|
||||
.truncate(true)
|
||||
.open("/tmp/test-startup.log")
|
||||
{
|
||||
let _ = file.write_all(msg.as_bytes());
|
||||
let _ = file.flush();
|
||||
match dotenv::dotenv() {
|
||||
Ok(path) => eprintln!("Loaded .env from: {:?}", path),
|
||||
Err(e) => eprintln!("No .env file found (this is OK in Docker): {}", e),
|
||||
}
|
||||
|
||||
// Try to print to stdout
|
||||
println!("BINARY STARTED");
|
||||
let _ = std::io::stdout().flush();
|
||||
eprintln!("Initializing logging...");
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter(
|
||||
tracing_subscriber::EnvFilter::try_from_default_env()
|
||||
.unwrap_or_else(|_| "normogen_backend=debug,tower_http=debug,axum=debug".into())
|
||||
)
|
||||
.init();
|
||||
|
||||
// Try to print to stderr
|
||||
eprintln!("BINARY STARTED (stderr)");
|
||||
let _ = std::io::stderr().flush();
|
||||
eprintln!("Loading configuration...");
|
||||
let config = match Config::from_env() {
|
||||
Ok(cfg) => {
|
||||
tracing::info!("Configuration loaded successfully");
|
||||
eprintln!("Config loaded: DB={}, Port={}", cfg.database.database, cfg.server.port);
|
||||
cfg
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("FATAL: Failed to load configuration: {}", e);
|
||||
return Err(e);
|
||||
}
|
||||
};
|
||||
|
||||
// Sleep to keep container alive
|
||||
std::thread::sleep(std::time::Duration::from_secs(60));
|
||||
tracing::info!("Connecting to MongoDB at {}", config.database.uri);
|
||||
eprintln!("Connecting to MongoDB...");
|
||||
let db = match db::MongoDb::new(&config.database.uri, &config.database.database).await {
|
||||
Ok(db) => {
|
||||
tracing::info!("Connected to MongoDB database: {}", config.database.database);
|
||||
eprintln!("MongoDB connection successful");
|
||||
db
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("FATAL: Failed to connect to MongoDB: {}", e);
|
||||
return Err(e);
|
||||
}
|
||||
};
|
||||
|
||||
tracing::info!("MongoDB health check: {}", db.health_check().await?);
|
||||
|
||||
let jwt_service = auth::JwtService::new(config.jwt.clone());
|
||||
|
||||
let app_state = config::AppState {
|
||||
db,
|
||||
jwt_service,
|
||||
config: config.clone(),
|
||||
};
|
||||
|
||||
eprintln!("Building router...");
|
||||
|
||||
let public_routes = Router::new()
|
||||
.route("/health", get(handlers::health_check))
|
||||
.route("/ready", get(handlers::ready_check))
|
||||
.route("/api/auth/register", post(handlers::register))
|
||||
.route("/api/auth/login", post(handlers::login))
|
||||
.route("/api/auth/recover-password", post(handlers::recover_password))
|
||||
.layer(
|
||||
ServiceBuilder::new()
|
||||
.layer(TraceLayer::new_for_http())
|
||||
.layer(CorsLayer::new())
|
||||
);
|
||||
|
||||
let protected_routes = Router::new()
|
||||
// Profile management
|
||||
.route("/api/users/me", get(handlers::get_profile))
|
||||
.route("/api/users/me", put(handlers::update_profile))
|
||||
.route("/api/users/me", delete(handlers::delete_account))
|
||||
// Account settings
|
||||
.route("/api/users/me/settings", get(handlers::get_settings))
|
||||
.route("/api/users/me/settings", put(handlers::update_settings))
|
||||
.route("/api/users/me/change-password", post(handlers::change_password))
|
||||
// Share management (Phase 2.5)
|
||||
.route("/api/shares", post(handlers::create_share))
|
||||
.route("/api/shares", get(handlers::list_shares))
|
||||
.route("/api/shares/:id", get(handlers::get_share))
|
||||
.route("/api/shares/:id", put(handlers::update_share))
|
||||
.route("/api/shares/:id", delete(handlers::delete_share))
|
||||
// Permissions (Phase 2.5)
|
||||
.route("/api/permissions/check", post(handlers::check_permission))
|
||||
.layer(
|
||||
ServiceBuilder::new()
|
||||
.layer(TraceLayer::new_for_http())
|
||||
.layer(CorsLayer::new())
|
||||
)
|
||||
.route_layer(axum_middleware::from_fn_with_state(
|
||||
app_state.clone(),
|
||||
crate::middleware::auth::jwt_auth_middleware
|
||||
));
|
||||
|
||||
let app = public_routes.merge(protected_routes).with_state(app_state);
|
||||
|
||||
eprintln!("Binding to {}:{}...", config.server.host, config.server.port);
|
||||
let listener = tokio::net::TcpListener::bind(&format!("{}:{}", config.server.host, config.server.port))
|
||||
.await?;
|
||||
|
||||
tracing::info!("Server listening on {}:{}", config.server.host, config.server.port);
|
||||
eprintln!("Server is running on http://{}:{}", config.server.host, config.server.port);
|
||||
|
||||
axum::serve(listener, app).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue