diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..2f87986
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "naas"
+version = "1.0.0"
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..15b3456
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+name = "naas"
+version = "1.0.0"
+edition = "2021"
+
+[dependencies]
+
+[profile.release]
+opt-level = "z"
+lto = true
+codegen-units = 1
+strip = true
+panic = "abort"
\ No newline at end of file
diff --git a/Containerfile b/Containerfile
new file mode 100644
index 0000000..0fc69ff
--- /dev/null
+++ b/Containerfile
@@ -0,0 +1,56 @@
+# Build stage
+FROM docker.io/rust:1-alpine AS builder
+
+# Install build dependencies
+RUN apk add --no-cache musl-dev
+
+WORKDIR /app
+
+# Copy manifests
+COPY Cargo.toml ./
+
+# Create dummy main.rs for dependency caching
+RUN mkdir src && echo "fn main() {}" > src/main.rs
+
+# Build dependencies
+RUN cargo build --release
+RUN rm -rf src
+
+# Copy source code
+COPY src ./src
+
+# Touch main.rs to ensure rebuild
+RUN touch src/main.rs
+
+# Build the application
+RUN cargo build --release
+
+# Runtime stage
+FROM docker.io/alpine:latest
+
+# Install runtime dependencies
+RUN apk add --no-cache ca-certificates
+
+# Create non-root user
+RUN adduser -D -u 1000 naas
+
+WORKDIR /app
+
+# Copy binary from builder
+COPY --from=builder /app/target/release/naas /app/naas
+RUN chmod +x /app/naas
+
+# Change ownership
+RUN chown -R naas:naas /app
+
+USER naas
+
+# Expose port
+EXPOSE 8080
+
+# Health check
+HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
+ CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1
+
+# Run the application
+CMD ["./naas"]
\ No newline at end of file
diff --git a/naas.service b/naas.service
new file mode 100644
index 0000000..b8d3182
--- /dev/null
+++ b/naas.service
@@ -0,0 +1,50 @@
+[Unit]
+Description=No as a Service (NaaS)
+After=network-online.target
+Wants=network-online.target
+
+[Service]
+Type=simple
+Restart=always
+RestartSec=10
+TimeoutStopSec=30
+
+# User configuration (adjust as needed)
+User=naas
+Group=naas
+
+# Environment configuration
+Environment="PORT=8080"
+Environment="BUILDAH_FORMAT=docker"
+
+# Container management
+ExecStartPre=/usr/bin/podman rm -f naas-container 2>/dev/null || true
+ExecStartPre=/usr/bin/podman build -t naas:latest /opt/naas
+
+ExecStart=/usr/bin/podman run \
+ --name naas-container \
+ --rm \
+ --network=host \
+ --read-only \
+ --security-opt no-new-privileges \
+ --cap-drop ALL \
+ --cap-add NET_BIND_SERVICE \
+ -e PORT=8080 \
+ naas:latest
+
+ExecStop=/usr/bin/podman stop naas-container
+ExecStopPost=/usr/bin/podman rm -f naas-container 2>/dev/null || true
+
+# Security settings
+NoNewPrivileges=true
+PrivateTmp=true
+ProtectSystem=strict
+ProtectHome=true
+ReadWritePaths=
+
+# Resource limits
+MemoryLimit=256M
+CPUQuota=50%
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..8ff749a
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,372 @@
+use std::io::prelude::*;
+use std::net::{TcpListener, TcpStream};
+use std::thread;
+
+const HTML_FRONTEND: &str = r#"
+
+
+
+
+ No as a Service
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click a button to test the API
+
+
+
+
+
API Endpoints
+
+ - GET /api/no - Returns "no"
+ - GET /api/no?format=json - Returns JSON
+ - GET /api/no?format=bool - Returns boolean
+ - GET /api/no?format=xml - Returns XML
+ - GET /api/no?format=yaml - Returns YAML
+ - GET /health - Health check
+
+
+
+
+
+
+"#;
+
+fn main() {
+ let port = std::env::var("PORT").unwrap_or_else(|_| "8080".to_string());
+ let addr = format!("0.0.0.0:{}", port);
+
+ let listener = TcpListener::bind(&addr).expect("Failed to bind to address");
+ println!("No as a Service running on http://{}", addr);
+
+ for stream in listener.incoming() {
+ match stream {
+ Ok(stream) => {
+ thread::spawn(|| {
+ handle_connection(stream);
+ });
+ }
+ Err(e) => {
+ eprintln!("Connection failed: {}", e);
+ }
+ }
+ }
+}
+
+fn handle_connection(mut stream: TcpStream) {
+ let mut buffer = [0; 1024];
+ if let Err(e) = stream.read(&mut buffer) {
+ eprintln!("Failed to read from stream: {}", e);
+ return;
+ }
+
+ let request = String::from_utf8_lossy(&buffer[..]);
+ let request_line = request.lines().next().unwrap_or("");
+
+ let (status, content_type, body) = route_request(request_line);
+
+ let response = format!(
+ "HTTP/1.1 {}\r\n\
+ Content-Type: {}\r\n\
+ Content-Length: {}\r\n\
+ Access-Control-Allow-Origin: *\r\n\
+ Access-Control-Allow-Methods: GET, OPTIONS\r\n\
+ Access-Control-Allow-Headers: Content-Type\r\n\
+ \r\n\
+ {}",
+ status,
+ content_type,
+ body.len(),
+ body
+ );
+
+ if let Err(e) = stream.write_all(response.as_bytes()) {
+ eprintln!("Failed to write response: {}", e);
+ }
+
+ if let Err(e) = stream.flush() {
+ eprintln!("Failed to flush stream: {}", e);
+ }
+}
+
+fn route_request(request_line: &str) -> (&str, &str, String) {
+ let parts: Vec<&str> = request_line.split_whitespace().collect();
+ if parts.len() < 2 {
+ return ("400 Bad Request", "text/plain", "Bad Request".to_string());
+ }
+
+ let method = parts[0];
+ let path = parts[1];
+
+ if method == "OPTIONS" {
+ return ("200 OK", "text/plain", "".to_string());
+ }
+
+ if method != "GET" {
+ return ("405 Method Not Allowed", "text/plain", "Method Not Allowed".to_string());
+ }
+
+ match path {
+ "/" => ("200 OK", "text/html; charset=utf-8", HTML_FRONTEND.to_string()),
+ "/health" => ("200 OK", "text/plain", "OK".to_string()),
+ path if path.starts_with("/api/no") => handle_api_no(path),
+ _ => ("404 Not Found", "text/plain", "Not Found".to_string()),
+ }
+}
+
+fn handle_api_no(path: &str) -> (&'static str, &'static str, String) {
+ let format = if let Some(query_start) = path.find('?') {
+ let query = &path[query_start + 1..];
+ parse_query_param(query, "format")
+ } else {
+ None
+ };
+
+ match format.as_deref() {
+ Some("json") => (
+ "200 OK",
+ "application/json",
+ r#"{"answer":"no"}"#.to_string()
+ ),
+ Some("bool") => (
+ "200 OK",
+ "application/json",
+ "false".to_string()
+ ),
+ Some("xml") => (
+ "200 OK",
+ "application/xml",
+ r#"no"#.to_string()
+ ),
+ Some("yaml") => (
+ "200 OK",
+ "text/yaml",
+ "answer: no\n".to_string()
+ ),
+ _ => (
+ "200 OK",
+ "text/plain",
+ "no".to_string()
+ ),
+ }
+}
+
+fn parse_query_param(query: &str, param_name: &str) -> Option {
+ for pair in query.split('&') {
+ let mut parts = pair.split('=');
+ if let (Some(key), Some(value)) = (parts.next(), parts.next()) {
+ if key == param_name {
+ return Some(value.to_string());
+ }
+ }
+ }
+ None
+}
\ No newline at end of file