Build a High‑Performance Rust Media Server with Actix‑Web and Docker
This step‑by‑step tutorial shows how to create a low‑latency Rust and Actix‑Web media server, configure Docker, stream MP4 videos, and build a simple front‑end, enabling full control over media hosting and easy extensions such as authentication, database integration, transcoding, and CDN acceleration.
This article guides you step‑by‑step to create a high‑performance media server using Rust and Actix‑Web, enabling low‑latency video delivery and full control over media hosting.
Download Sample Video 🎥💾
First, download a sample MP4 video from https://sample-videos.com.
Create docker-compose.yml 📄
Create a file named docker-compose.yml with the following content:
version: '3.5'
services:
rust:
image: rust:latest
container_name: rust
ports:
- 8080:8080
tty: true
volumes:
- .:/app
working_dir: /app
command: bash
networks:
default:
name: rustRun the container:
$ docker-compose upSet Up Rust Server 🦀🖥️
Enter the Rust container (via CLI or VSCode). Create a new Rust project: cargo new mp4_server Add the following to Cargo.toml:
[package]
name = "mp4_server"
version = "0.1.0"
edition = "2021"
[dependencies]
reqwest = { version = "0.12.7", features = ["json"] }
tokio = { version = "1.40.0", features = ["full"] }
serde = { version = "1.0.210", features = ["derive"] }
actix-web = "4.9.0"
actix-cors = "0.7.0"Replace the contents of src/main.rs with:
use actix_web::{web, App, HttpServer, HttpResponse};
use tokio::fs::File;
use tokio::io::{AsyncReadExt, BufReader};
use actix_cors::Cors;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.wrap(Cors::permissive())
.route("/stream", web::get().to(stream_video))
})
.bind("0.0.0.0:8080")?
.run()
.await
}
async fn stream_video() -> HttpResponse {
let file_path = "/app/mp4_server/test.mp4"; // MP4 file path
let file = File::open(file_path).await;
match file {
Ok(mut f) => {
let mut buffer = Vec::new();
let mut reader = BufReader::new(f);
let mut content = Vec::new();
while let Ok(n) = reader.read_to_end(&mut buffer).await {
if n == 0 { break; }
content.extend_from_slice(&buffer[..n]);
}
HttpResponse::Ok()
.content_type("video/mp4")
.body(content)
}
Err(_) => HttpResponse::NotFound().body("Video not found"),
}
}Replace /app/mp4_server/test.mp4 with the actual path to your MP4 file, then run:
cargo runCreate Simple Frontend 💻🎨
Create a file named mp4.html with the following content:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Stream MP4 Video</title>
</head>
<body>
<h1>Stream MP4 Video</h1>
<video width="640" height="360" controls>
<source src="http://localhost:8080/stream" type="video/mp4">
Your browser does not support the video tag.
</video>
</body>
</html>Summary 🎉👨💻
You have now built a high‑performance MP4 streaming server with Rust and Actix‑Web, ready for further customization.
Extensions:
Add authentication and authorization: Control access to your media server.
Store video metadata in a database: Use a database for titles, descriptions, tags, etc.
Implement video transcoding: Use third‑party libraries or services to support various formats and resolutions.
Accelerate delivery with a CDN: Improve user experience by using a CDN.
Further learning:
Actix‑Web documentation: https://actix.rs/docs/
Rust book: https://doc.rust-lang.org/book/
Tokio docs: https://docs.rs/tokio
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Architecture Development Notes
Focused on architecture design, technology trend analysis, and practical development experience sharing.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
