summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunitexe <unitexe70@gmail.com>2026-01-27 23:39:15 -0600
committerunitexe <unitexe70@gmail.com>2026-01-27 23:39:35 -0600
commitcdac69878b058dcd1a150d768e2627d41af211c2 (patch)
tree91c2e84728c9e08cb5d0a787e1688e9d4c1bde83
Initial commit
-rw-r--r--.gitignore22
-rw-r--r--Cargo.toml9
-rw-r--r--Containerfile31
-rw-r--r--LICENSE21
-rw-r--r--README.md2
-rw-r--r--src/main.rs25
6 files changed, 110 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ab951f8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,22 @@
+# ---> Rust
+# Generated by Cargo
+# will have compiled files and executables
+debug/
+target/
+
+# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
+# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
+Cargo.lock
+
+# These are backup files generated by rustfmt
+**/*.rs.bk
+
+# MSVC Windows builds of rustc generate these, which store debugging information
+*.pdb
+
+# RustRover
+# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
+# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
+# and can be added to the global gitignore or merged into this file. For a more nuclear
+# option (not recommended) you can uncomment the following to ignore the entire idea folder.
+#.idea/
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..94c5179
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,9 @@
+[package]
+name = "banner-rs"
+version = "0.1.0"
+edition = "2024"
+
+[dependencies]
+axum = "0.8.8"
+sd-notify = "0.4.5"
+tokio = { version = "1.49.0", features = ["macros", "net", "rt-multi-thread", "time"] }
diff --git a/Containerfile b/Containerfile
new file mode 100644
index 0000000..1494828
--- /dev/null
+++ b/Containerfile
@@ -0,0 +1,31 @@
+#
+# Build stage
+#
+
+FROM rust:1.91-alpine3.23 AS builder
+
+RUN apk add --no-cache musl-dev
+
+WORKDIR /app
+
+COPY Cargo.toml Cargo.lock* ./
+
+COPY src ./src
+
+RUN cargo build --release
+
+#
+# Run stage
+#
+
+FROM alpine:latest
+
+RUN apk add --no-cache libgcc
+
+WORKDIR /app
+
+COPY --from=builder /app/target/release/banner-rs /app/banner
+
+EXPOSE 8080
+
+CMD ["/app/banner"]
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..52686ad
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2025 Closed Circuit Consulting
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE. \ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e7ffe6a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,2 @@
+# banner-rs
+A single route banner HTTP server.
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..69b2841
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,25 @@
+use axum::{Router, routing::get};
+
+const BANNER: &str = r#"
+ ###### ###### ######
+ ## ## ## ## ## ##
+ ## ## ##
+ ## ## ##
+ ## ## ##
+ ## ## ## ## ## ##
+ ###### ###### ######
+
+"#;
+
+#[tokio::main]
+async fn main() {
+ let app = Router::new().route("/", get(|| async { BANNER }));
+ let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await.unwrap();
+ let server_handle = tokio::spawn(async move { axum::serve(listener, app).await });
+ tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
+ if !server_handle.is_finished() {
+ let _ = sd_notify::notify(true, &[sd_notify::NotifyState::Ready]);
+ }
+
+ server_handle.await.unwrap().unwrap();
+}