mirror of
https://github.com/Xevion/time-banner.git
synced 2025-12-06 01:16:36 -06:00
Prepare dockerized build for Railway
This commit is contained in:
17
Cargo.lock
generated
17
Cargo.lock
generated
@@ -137,6 +137,21 @@ version = "0.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8d7439c3735f405729d52c3fbbe4de140eaf938a1fe47d227c27f8254d4302a5"
|
checksum = "8d7439c3735f405729d52c3fbbe4de140eaf938a1fe47d227c27f8254d4302a5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dotenvy"
|
||||||
|
version = "0.15.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "envy"
|
||||||
|
version = "0.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f47e0157f2cb54f5ae1bd371b30a2ae4311e1c028f575cd4e81de7353215965"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fdeflate"
|
name = "fdeflate"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
@@ -897,6 +912,8 @@ name = "time-banner"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"axum",
|
"axum",
|
||||||
|
"dotenvy",
|
||||||
|
"envy",
|
||||||
"futures",
|
"futures",
|
||||||
"png",
|
"png",
|
||||||
"resvg",
|
"resvg",
|
||||||
|
|||||||
@@ -15,3 +15,5 @@ tracing = "0.1"
|
|||||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||||
futures = "0.3.28"
|
futures = "0.3.28"
|
||||||
png = "0.17.9"
|
png = "0.17.9"
|
||||||
|
dotenvy = "0.15.7"
|
||||||
|
envy = "0.4.2"
|
||||||
|
|||||||
43
Dockerfile
Normal file
43
Dockerfile
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# Build Stage
|
||||||
|
FROM rust:1.68.0 as builder
|
||||||
|
|
||||||
|
RUN USER=root cargo new --bin time-banner
|
||||||
|
WORKDIR ./time-banner
|
||||||
|
ENV CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse
|
||||||
|
COPY ./Cargo.toml ./Cargo.toml
|
||||||
|
# Build empty app with downloaded dependencies to produce a stable image layer for next build
|
||||||
|
RUN cargo build --release
|
||||||
|
|
||||||
|
# Build web app with own code
|
||||||
|
RUN rm src/*.rs
|
||||||
|
ADD . ./
|
||||||
|
RUN rm ./target/release/deps/time-banner*
|
||||||
|
RUN cargo build --release
|
||||||
|
|
||||||
|
|
||||||
|
FROM debian:buster-slim
|
||||||
|
ARG APP=/usr/src/app
|
||||||
|
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y ca-certificates tzdata \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
ENV TZ=Etc/UTC \
|
||||||
|
APP_USER=appuser
|
||||||
|
|
||||||
|
RUN groupadd $APP_USER \
|
||||||
|
&& useradd -g $APP_USER $APP_USER \
|
||||||
|
&& mkdir -p ${APP}
|
||||||
|
|
||||||
|
COPY --from=builder /time-banner/target/release/time-banner ${APP}/time-banner
|
||||||
|
|
||||||
|
RUN chown -R $APP_USER:$APP_USER ${APP}
|
||||||
|
|
||||||
|
USER $APP_USER
|
||||||
|
WORKDIR ${APP}
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
ENV PORT 3000
|
||||||
|
|
||||||
|
|
||||||
|
CMD ["./time-banner"]
|
||||||
57
src/config.rs
Normal file
57
src/config.rs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
use serde::Deserialize;
|
||||||
|
use tracing::Level;
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
pub enum Environment {
|
||||||
|
Production,
|
||||||
|
Development,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
pub struct Configuration {
|
||||||
|
#[serde(default = "default_env")]
|
||||||
|
pub env: Environment,
|
||||||
|
|
||||||
|
#[serde(default = "default_port")]
|
||||||
|
pub port: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_port() -> u16 {
|
||||||
|
3000
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_env() -> Environment {
|
||||||
|
Environment::Development
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Configuration {
|
||||||
|
pub fn socket_addr(&self) -> [u8; 4] {
|
||||||
|
match self.env {
|
||||||
|
Environment::Production => {
|
||||||
|
let socket = [0, 0, 0, 0];
|
||||||
|
tracing::info!(
|
||||||
|
"Starting Production on {:?}:{}",
|
||||||
|
socket.as_slice(),
|
||||||
|
self.port
|
||||||
|
);
|
||||||
|
socket
|
||||||
|
}
|
||||||
|
Environment::Development => {
|
||||||
|
let socket = [127, 0, 0, 1];
|
||||||
|
tracing::info!(
|
||||||
|
"Starting Development on {:?}:{}",
|
||||||
|
socket.as_slice(),
|
||||||
|
self.port
|
||||||
|
);
|
||||||
|
socket
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn log_level(&self) -> Level {
|
||||||
|
match self.env {
|
||||||
|
Environment::Production => Level::INFO,
|
||||||
|
Environment::Development => Level::DEBUG,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
28
src/main.rs
28
src/main.rs
@@ -1,3 +1,5 @@
|
|||||||
|
mod config;
|
||||||
|
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
use axum::{http::StatusCode, Json, response::IntoResponse, Router, routing::{get, post}};
|
use axum::{http::StatusCode, Json, response::IntoResponse, Router, routing::{get, post}};
|
||||||
@@ -5,21 +7,33 @@ use axum::body::{Bytes, Full};
|
|||||||
use axum::extract::ConnectInfo;
|
use axum::extract::ConnectInfo;
|
||||||
use axum::http::header;
|
use axum::http::header;
|
||||||
use axum::response::Response;
|
use axum::response::Response;
|
||||||
|
use dotenvy::dotenv;
|
||||||
|
use config::Configuration;
|
||||||
|
|
||||||
mod svg;
|
mod svg;
|
||||||
|
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
// initialize tracing
|
// Parse dotenv files and expose them as environment variables
|
||||||
tracing_subscriber::fmt::init();
|
dotenv().ok();
|
||||||
|
|
||||||
let app = Router::new()
|
// envy uses our Configuration struct to parse environment variables
|
||||||
.route("/", get(root));
|
let config = envy::from_env::<Configuration>().expect("Please provide PORT env var");
|
||||||
|
|
||||||
|
// initialize tracing
|
||||||
|
tracing_subscriber::fmt()
|
||||||
|
// With the log_level from our config
|
||||||
|
.with_max_level(config.log_level())
|
||||||
|
.init();
|
||||||
|
|
||||||
|
// build our application with a route
|
||||||
|
let app = Router::new().route("/", get(root_handler));
|
||||||
|
|
||||||
// run our app with hyper
|
// run our app with hyper
|
||||||
// `axum::Server` is a re-export of `hyper::Server`
|
// `axum::Server` is a re-export of `hyper::Server`
|
||||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
let addr = SocketAddr::from((config.socket_addr(), config.port));
|
||||||
tracing::debug!("listening on {}", addr);
|
|
||||||
axum::Server::bind(&addr)
|
axum::Server::bind(&addr)
|
||||||
.serve(app.into_make_service_with_connect_info::<SocketAddr>())
|
.serve(app.into_make_service_with_connect_info::<SocketAddr>())
|
||||||
.await
|
.await
|
||||||
@@ -27,7 +41,7 @@ async fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// basic handler that responds with a static string
|
// basic handler that responds with a static string
|
||||||
async fn root(connect_info: ConnectInfo<SocketAddr>) -> impl IntoResponse {
|
async fn root_handler(connect_info: ConnectInfo<SocketAddr>) -> impl IntoResponse {
|
||||||
let raw_image = svg::get();
|
let raw_image = svg::get();
|
||||||
|
|
||||||
if raw_image.is_err() {
|
if raw_image.is_err() {
|
||||||
|
|||||||
@@ -29,8 +29,6 @@ pub fn get() -> Result<Vec<u8>, RenderError> {
|
|||||||
fontdb.load_system_fonts();
|
fontdb.load_system_fonts();
|
||||||
|
|
||||||
let svg_data = std::fs::read("test.svg").unwrap();
|
let svg_data = std::fs::read("test.svg").unwrap();
|
||||||
// print bytes as string
|
|
||||||
println!("{:?}", String::from_utf8(svg_data.clone()).unwrap());
|
|
||||||
|
|
||||||
let mut tree_result = usvg::Tree::from_data(&svg_data, &opt);
|
let mut tree_result = usvg::Tree::from_data(&svg_data, &opt);
|
||||||
if tree_result.is_err() { return Err(RenderError { message: Some("Failed to parse".to_string()) }); }
|
if tree_result.is_err() { return Err(RenderError { message: Some("Failed to parse".to_string()) }); }
|
||||||
|
|||||||
Reference in New Issue
Block a user