Building a Simple Web Server with Alire on Zorin OS: A Deep Dive and Comparison to Rust
If you're diving into programming on Zorin OS—a sleek, user-friendly Ubuntu-based distro—Alire is an excellent tool for Ada enthusiasts. Alire serves as Ada's package manager, akin to Cargo in Rust or pip in Python, streamlining dependency management, builds, and project setup. In this comprehensive guide, I'll walk you through installing Alire on Zorin (noting that apt doesn't work out of the box), explain its usefulness, demonstrate building a simple web server using the Ada Web Server (AWS) crate, troubleshoot common issues like warnings, and compare the approach to Rust's Axum framework. We'll even include a full Rust equivalent for side-by-side analysis. This is perfect for beginners or those exploring safe, reliable languages.
Why Use Alire and Ada on Zorin OS?
Ada is a language engineered for safety, reliability, and maintainability, with features like strong typing, runtime checks, and support for formal verification via SPARK. It's ideal for critical systems (e.g., satellites, aviation) but also shines in everyday apps like web servers. Alire makes Ada accessible by handling crates (packages), toolchains, and builds—much like how Cargo revolutionized Rust.
On Zorin OS, Alire is useful for:
- Ease of Setup: No manual compiler hunts; Alire installs GNAT and dependencies automatically.
- Safety Focus: Ada's checks prevent bugs that plague C/C++ or even Rust in some cases.
- Cross-Platform: Build for Linux, bare-metal (e.g., Raspberry Pi), or embedded systems.
- Community Crates: Access vetted libraries like AWS for web serving, without the "pull unvetted code" risks of larger ecosystems.
Compared to Rust, Ada prioritizes provable correctness over performance (though it's fast), with a smaller but high-quality ecosystem. Rust excels in concurrency and has massive community support, but Ada feels "safer" for mission-critical work.
Installing Alire on Zorin OS: The Gotchas
Zorin 17.3 (based on Ubuntu 22.04 "Jammy") doesn't include Alire in its default apt repositories—attempting sudo apt install alire will fail with "Unable to locate package alire." Even enabling the universe repo won't help for older versions. Instead, grab the latest binary (v2.1.0 as of November 2025) from GitHub. This method is quick and reliable.
Open a terminal and run:
wget https://github.com/alire-project/alire/releases/download/v2.1.0/alr-2.1.0-bin-x86_64-linux.zip
unzip alr-2.1.0-bin-x86_64-linux.zip
sudo mv alr /usr/local/bin/
sudo chmod +x /usr/local/bin/alr
Verify: alr version. If PATH issues arise, add export PATH="/usr/local/bin:$PATH" to ~/.bashrc and reload with source ~/.bashrc.
Next, set up the toolchain: alr toolchain --select. Choose gnat_native (latest stable, e.g., 15.2.1). This downloads ~500 MB but ensures a fresh compiler.
Troubleshooting:
- Proxy Issues: Set
export http_proxy=http://your-proxy:portandexport https_proxy=http://your-proxy:portbefore commands. - Missing Deps: If GNAT isn't found, install via
sudo apt install gnat gprbuild. - Older Zorin: If on Zorin 16 or earlier, build from source: Clone
git clone https://github.com/alire-project/alire.git, thencd alire; make; sudo make install.
Creating a Simple Web Server with Alire
We'll use the AWS crate for a basic HTTP server with routes, uptime display, and 404 handling. Ada/AWS is synchronous but robust for secure apps.
- Create project:
alr init --bin ada_web_demo; cd ada_web_demo - Add dep:
alr with aws(downloads ~2-3 min first time). - Edit
src/ada_web_demo.adb:
with Ada.Text_IO; use Ada.Text_IO;
with AWS.Server;
with AWS.Response;
with AWS.Status;
with Ada.Calendar; use Ada.Calendar;
procedure Ada_Web_Demo is
Web_Server : AWS.Server.HTTP;
Start_Time : constant Time := Clock;
function Callback (Request : AWS.Status.Data) return AWS.Response.Data is
URI : constant String := AWS.Status.URI (Request);
begin
if URI = "/" or else URI = "/index.html" then
return AWS.Response.Build (
"text/html",
"<h1>Hello from Ada/AWS on Zorin Linux!</h1>" &
"<p>Uptime: " & Duration'Image (Clock - Start_Time) & " seconds</p>" &
"<p>Running on port 8080 - try <a href=""/about"">/about</a></p>"
);
elsif URI = "/about" then
return AWS.Response.Build ("text/plain",
"This is a simple Ada web server!");
else
return AWS.Response.Build ("text/plain",
"404 - Not Found");
end if;
end Callback;
begin
AWS.Server.Start (
Web_Server,
Name => "Zorin Ada Server",
Callback => Callback'Unrestricted_Access,
Port => 8080
);
Put_Line ("Ada web server running at http://localhost:8080");
Put_Line ("Press Ctrl+C to stop");
loop
delay 3600.0;
end loop;
end Ada_Web_Demo;
Build/run: alr build; alr run. Visit http://localhost:8080.
Handling Warnings and Errors
You might see C warnings from zlib (old-style functions)—harmless legacy code. Suppress in GPR: Add for Default_Switches ("C") use ("-Wno-old-style-definition");. For Ada line-length warnings, split strings or raise limit with -gnatyM100.
Common errors: "aws_config not found"—run alr clean --all && alr update. "Subprogram depth"—use 'Unrestricted_Access for callbacks.
Comparing Ada/Alire to Rust/Cargo
Ada/Alire emphasizes safety (provable no overflows) with a small, vetted ecosystem. Rust/Cargo offers async concurrency, huge crates (150k+ vs Ada's 700), and easier talent. Ada for critical apps; Rust for web/performance. Both memory-safe, but Ada has formal proofs.
A Simple Web Server in Rust with Axum
Axum is Rust's async web framework. Install Rust: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh. Create: cargo new rust_web_demo; cd rust_web_demo. Cargo.toml:
[dependencies]
axum = "0.7.5"
tokio = { version = "1.41.0", features = ["full"] }
src/main.rs:
use axum::{routing::get, Router, response::Html};
use std::time::{Instant, Duration};
use std::net::SocketAddr;
#[tokio::main]
async fn main() {
let start = Instant::now();
let app = Router::new()
.route("/", get(move || root(start)))
.route("/about", get(about));
let addr = SocketAddr::from(([127, 0, 0, 1], 8080));
println!("Rust web server running at http://localhost:8080");
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
async fn root(start: Instant) -> Html {
let uptime = Instant::now() - start;
Html(format!(
"<h1>Hello from Rust/Axum on Zorin!</h1>
<p>Uptime: {} seconds</p>
<p>Running on port 8080 - try <a href='/about'>/about</a></p>",
uptime.as_secs()
))
}
async fn about() -> &'static str {
"This is a simple Rust web server!"
}
Run: cargo run. Similar, but async for better scalability.
Pros/Cons
- Ada: Safer for errors, verbose but readable. Cons: Smaller community.
- Rust: Faster, async. Cons: Borrow checker learning curve.
Final Thoughts
Alire on Zorin opens doors to safe coding; try it for web or embedded. Rust complements for performance-heavy tasks. Experiment and see!