Add Docker build
This commit is contained in:
@@ -38,6 +38,7 @@ thiserror = "1.0"
|
||||
anyhow = "1.0"
|
||||
http = "0.2.0"
|
||||
config = "0.12.0"
|
||||
actix-files = "0.6.0"
|
||||
|
||||
[dev-dependencies]
|
||||
proptest = "1.0.0"
|
||||
|
||||
@@ -1 +1,8 @@
|
||||
extend = "../Makefile.toml"
|
||||
|
||||
[tasks.run]
|
||||
clear = true
|
||||
install_crate = { crate_name = "bunyan", binary = "bunyan" }
|
||||
env = { "TASKRC" = "$PWD/taskrc" }
|
||||
command = "bash"
|
||||
args = ["-c", "cargo run | bunyan"]
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
port = 8000
|
||||
# See https://docs.rs/tracing-subscriber/latest/tracing_subscriber/struct.EnvFilter.html
|
||||
log_directive = "info"
|
||||
api_path = ""
|
||||
front_base_url = "http://localhost:8080"
|
||||
|
||||
[taskwarrior]
|
||||
data_location = "/tmp"
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
[application]
|
||||
log_directive = "debug"
|
||||
static_dir = "../web/dist"
|
||||
api_path = "/api"
|
||||
static_path = ""
|
||||
|
||||
@@ -12,6 +12,10 @@ pub struct Settings {
|
||||
pub struct ApplicationSettings {
|
||||
pub port: u16,
|
||||
pub log_directive: String,
|
||||
pub front_base_url: String,
|
||||
pub api_path: String,
|
||||
pub static_path: Option<String>,
|
||||
pub static_dir: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@@ -23,13 +27,21 @@ pub struct TaskwarriorSettings {
|
||||
impl Settings {
|
||||
pub fn new_from_file(file: Option<String>) -> Result<Self, ConfigError> {
|
||||
let config_file_required = file.is_some();
|
||||
let config_file =
|
||||
file.unwrap_or_else(|| env::var("CONFIG").unwrap_or_else(|_| "dev".into()));
|
||||
let config_path = env::var("CONFIG_PATH").unwrap_or_else(|_| "config".into());
|
||||
let config_file = file.unwrap_or_else(|| {
|
||||
env::var("CONFIG_FILE").unwrap_or_else(|_| format!("{}/dev", &config_path).into())
|
||||
});
|
||||
|
||||
let default_config_file = format!("{}/default", config_path);
|
||||
let local_config_file = format!("{}/local", config_path);
|
||||
println!(
|
||||
"Trying to load {:?} config files",
|
||||
vec![&default_config_file, &local_config_file, &config_file]
|
||||
);
|
||||
|
||||
let config = Config::builder()
|
||||
.add_source(File::with_name(&format!("{}/default", config_path)))
|
||||
.add_source(File::with_name(&format!("{}/local", config_path)).required(false))
|
||||
.add_source(File::with_name(&default_config_file))
|
||||
.add_source(File::with_name(&local_config_file).required(false))
|
||||
.add_source(File::with_name(&config_file).required(config_file_required))
|
||||
.add_source(Environment::with_prefix("cs"))
|
||||
.build()?;
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
use actix_files as fs;
|
||||
use actix_web::{dev::Server, http, middleware, web, App, HttpServer};
|
||||
use configuration::Settings;
|
||||
use core::time::Duration;
|
||||
use std::env;
|
||||
use std::net::TcpListener;
|
||||
use tracing::info;
|
||||
use tracing_actix_web::TracingLogger;
|
||||
|
||||
#[macro_use]
|
||||
@@ -12,30 +14,55 @@ pub mod contextswitch;
|
||||
pub mod observability;
|
||||
pub mod routes;
|
||||
|
||||
pub fn run(listener: TcpListener) -> Result<Server, std::io::Error> {
|
||||
let cs_front_base_url =
|
||||
env::var("CS_FRONT_BASE_URL").unwrap_or_else(|_| "http://localhost:8080".to_string());
|
||||
pub fn run(listener: TcpListener, settings: &Settings) -> Result<Server, std::io::Error> {
|
||||
let api_path = settings.application.api_path.clone();
|
||||
let front_base_url = settings.application.front_base_url.clone();
|
||||
let static_path = settings.application.static_path.clone();
|
||||
let static_dir = settings
|
||||
.application
|
||||
.static_dir
|
||||
.clone()
|
||||
.unwrap_or_else(|| ".".to_string());
|
||||
|
||||
let server = HttpServer::new(move || {
|
||||
App::new()
|
||||
.wrap(TracingLogger::default())
|
||||
.wrap(middleware::Compress::default())
|
||||
info!(
|
||||
"Mounting API on {}",
|
||||
if api_path.is_empty() { "/" } else { &api_path }
|
||||
);
|
||||
let api_scope = web::scope(&api_path)
|
||||
.wrap(
|
||||
middleware::DefaultHeaders::new()
|
||||
.add(("Access-Control-Allow-Origin", cs_front_base_url.as_bytes()))
|
||||
.add(("Access-Control-Allow-Origin", front_base_url.as_bytes()))
|
||||
.add((
|
||||
"Access-Control-Allow-Methods",
|
||||
"POST, GET, OPTIONS".as_bytes(),
|
||||
))
|
||||
.add(("Access-Control-Allow-Headers", "content-type".as_bytes())),
|
||||
)
|
||||
.route("/ping", web::get().to(routes::ping))
|
||||
.route("/tasks", web::get().to(routes::list_tasks))
|
||||
.route("/tasks", web::post().to(routes::add_task))
|
||||
.route("/tasks/{task_id}", web::put().to(routes::update_task))
|
||||
.route(
|
||||
"/tasks",
|
||||
web::method(http::Method::OPTIONS).to(routes::option_task),
|
||||
)
|
||||
);
|
||||
|
||||
let mut app = App::new()
|
||||
.wrap(TracingLogger::default())
|
||||
.wrap(middleware::Compress::default())
|
||||
.route("/ping", web::get().to(routes::ping))
|
||||
.service(api_scope);
|
||||
if let Some(path) = &static_path {
|
||||
info!(
|
||||
"Mounting static files on {}",
|
||||
if path.is_empty() { "/" } else { &path }
|
||||
);
|
||||
let static_scope = fs::Files::new(&path, &static_dir)
|
||||
.use_last_modified(true)
|
||||
.index_file("index.html");
|
||||
app = app.service(static_scope);
|
||||
}
|
||||
app
|
||||
})
|
||||
.keep_alive(http::KeepAlive::Timeout(Duration::from_secs(60)))
|
||||
.shutdown_timeout(60)
|
||||
|
||||
@@ -13,5 +13,5 @@ async fn main() -> std::io::Result<()> {
|
||||
|
||||
let listener = TcpListener::bind(format!("0.0.0.0:{}", settings.application.port))
|
||||
.expect("Failed to bind port");
|
||||
run(listener)?.await
|
||||
run(listener, &settings)?.await
|
||||
}
|
||||
|
||||
@@ -12,12 +12,12 @@ fn setup_tracing(settings: &Settings) {
|
||||
init_subscriber(subscriber);
|
||||
}
|
||||
|
||||
fn setup_server() -> String {
|
||||
fn setup_server(settings: &Settings) -> String {
|
||||
info!("Setting up server");
|
||||
let listener = TcpListener::bind("127.0.0.1:0").expect("Failed to bind random port");
|
||||
let port = listener.local_addr().unwrap().port();
|
||||
|
||||
let server = contextswitch_api::run(listener).expect("Failed to bind address");
|
||||
let server = contextswitch_api::run(listener, &settings).expect("Failed to bind address");
|
||||
let _ = tokio::spawn(server);
|
||||
format!("http://127.0.0.1:{}", port)
|
||||
}
|
||||
@@ -38,6 +38,7 @@ pub fn app_address() -> String {
|
||||
let settings = Settings::new_from_file(Some("config/test".to_string()))
|
||||
.expect("Cannot load test configuration");
|
||||
setup_tracing(&settings);
|
||||
let address = setup_server(&settings);
|
||||
setup_taskwarrior(settings);
|
||||
setup_server()
|
||||
address
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user