Ubuntu 24.04 LTS で Rust の axum フレームワークを使い、高性能な Webサーバーを構築する手順をまとめました。
実際に Docker コンテナ上でビルドを行い、デバッグビルドで 3分7秒、リリースビルドで 1分59秒 という計測結果が出ています。
axum は非同期ランタイム tokio をベースにしており、Express や Flask と比べて非常に少ないリソース消費で高スループットを実現できます。
本記事では cargo の使い方から systemd サービス登録まで一通り解説します。
この記事のポイント
- Ubuntu 24.04 の apt に含まれる rustc は
1.75.0(古い)。axum 開発にはrustupで1.96.0以降を入れること - Axum 0.7.9 + tokio のデバッグビルドは約
3分7秒、バイナリ40MB。リリースビルドは1分59秒、5.7MB - HTTP レスポンス速度は実測
2.9ms(localhost curl)。シンプルなルートなら体感でもほぼ瞬間的に返ってくる - 本番運用は
cargo build --releaseでビルドし、systemdサービスとして登録して自動起動させる - VPS で動かす場合は sysbench CPU 実測(14,175 events/sec 平均)が目安になる
目次
- axum とは何か
- 前提環境と検証結果
- Rust のインストール(rustup)
- axum プロジェクトの作成
- Hello World サーバーの実装
- ビルドと起動確認
- リリースビルドとバイナリサイズ
- systemd サービスとして登録する
- よくあるエラーと解決策
- まとめ
axum とは何か
axum は Tokio チームが開発する、Rust 向けの非同期 Web フレームワークです。
tokio の非同期ランタイムと hyper の HTTP 実装を組み合わせており、
Node.js の Express や Python の FastAPI に相当する「ルーティング + ミドルウェア + ハンドラ」の仕組みを持っています。
特徴は3点です。
まず、型安全なルーティング—パスパラメータや JSON 本文をコンパイル時に型チェックするため、ランタイムエラーが起きにくい。
次に、非同期ハンドラ—すべてのリクエスト処理が async/await で書けるため、I/O 待ちの多い API でも 1スレッドで大量リクエストをさばける。
最後に、tower エコシステム—ロギング・レート制限・タイムアウトなどのミドルウェアを tower の ServiceBuilder で簡単に組み合わせられます。
前提環境と検証結果
本記事の手順はすべて以下の環境で動作確認しています。
| 項目 | 値 |
|---|---|
| OS | Ubuntu 24.04 LTS(Noble Numbat) |
| Rust(rustup 経由) | 1.96.0(2026-05-25 リリース) |
| axum | 0.7.9 |
| tokio | 1.52.3 |
| build-essential(apt) | 12.10ubuntu1 |
| libssl-dev(apt) | 3.0.13-0ubuntu3.11 |
| 検証日 | 2026-06-14 |
Ubuntu 24.04 の apt 版 Rust は古い
まず押さえてほしいのが apt で入る Rust のバージョンです。
実際に apt-cache policy rustc cargo を実行したところ、以下の結果でした。
rustc:
Installed: (none)
Candidate: 1.75.0+dfsg0ubuntu1-0ubuntu7.4
cargo:
Installed: (none)
Candidate: 1.75.0+dfsg0ubuntu1-0ubuntu7.4
apt が提供する Rust は 1.75.0(2023年12月リリース)で、Ubuntu 22.04 と 24.04 で同じバージョンです。
axum 0.7 を快適に使うには 1.75.0 以降であれば動作しますが、現在の Rust 最新安定板(1.96.0)と比べて機能面・最適化面で大きく差があります。
本記事では rustup による最新版インストールを強く推奨します。

Rust のインストール(rustup)
手順1:依存パッケージをインストールする
まず Rust のコンパイルに必要な build-essential(gcc・make・ld など)と、一部のクレートが依存する pkg-config・libssl-dev をインストールします。
Reading package lists… Done
Building dependency tree… Done
The following NEW packages will be installed:
build-essential pkg-config libssl-dev curl
build-essential is already the newest version (12.10ubuntu1).
注意
libssl-dev は OpenSSL のヘッダーファイルです。reqwest(HTTP クライアントクレート)など TLS を使うクレートをプロジェクトに追加すると、libssl-dev がないとコンパイルエラーになります。axum 単体なら必須ではありませんが、先に入れておくと後でトラブルになりません。
手順2:rustup で Rust をインストールする
公式のインストーラー rustup を使います。このコマンド 1つで rustc・cargo・rustup の3点セットが入ります。
info: downloading installer
info: profile set to ‘default’
info: default host triple is aarch64-unknown-linux-gnu
info: latest update on 2026-05-25, rust version 1.96.0
stable-aarch64-unknown-linux-gnu installed – rustc 1.96.0 (ac68faa20 2026-05-25)
Rust is installed now. Great!
インストール後、cargo にパスを通します。
$ rustc –version
rustc 1.96.0 (ac68faa20 2026-05-25)
$ cargo –version
cargo 1.96.0 (2af8a43e0 2026-05-15)
~/.bashrc(または ~/.zshrc)の末尾に source "$HOME/.cargo/env" の1行を追加しておけば、次回ログイン時から自動でパスが通ります。

axum プロジェクトの作成
手順3:cargo new でプロジェクトを作る
Created binary (application) `myapp` package
手順4:axum と tokio を Cargo.toml に追加する
cargo add コマンドで依存クレートを追加します。
tokio の full フィーチャーフラグを指定するのがポイントです(省略すると非同期ランタイムが有効になりません)。
Updating crates.io index
Adding axum v0.7.9 to dependencies
$ cargo add tokio –features full
Adding tokio v1.52.3 to dependencies
Features:
+ full
追加後の Cargo.toml は次のようになります。
name = “myapp”
version = “0.1.0”
edition = “2021”
[dependencies]
axum = “0.7”
tokio = { version = “1”, features = [“full”] }
Hello World サーバーの実装
手順5:src/main.rs を書く
src/main.rs を次のように書き換えます。/ にアクセスすると “Hello from Axum on Ubuntu!” と返す最小構成です。
async fn hello() -> &’static str {
“Hello from Axum on Ubuntu!”
}
#[tokio::main]
async fn main() {
let app = Router::new().route(“/”, get(hello));
let listener = tokio::net::TcpListener::bind(“0.0.0.0:3000”).await.unwrap();
println!(“Axum server listening on http://0.0.0.0:3000”);
axum::serve(listener, app).await.unwrap();
}
コードのポイントを説明します。
Router::new().route("/", get(hello))—/への GET リクエストをhello関数で処理するルートを登録するtokio::net::TcpListener::bind("0.0.0.0:3000")— ポート 3000 で待ち受ける。VPS や Docker コンテナからアクセスするなら0.0.0.0の指定が必要(127.0.0.1だとローカルのみ)axum::serve(listener, app).await.unwrap()— axum 0.7 系の起動方法。旧バージョン(0.6 以前)とは API が変わっている
ビルドと起動確認
手順6:cargo build でデバッグビルドする
cargo build(オプションなし)でデバッグビルドが作られます。
初回は依存クレートのダウンロードとコンパイルが走るため、環境によって時間がかかります。
実際に計測した結果、Axum 0.7.9 + tokio の初回デバッグビルドは 3分7秒 でした。
Compiling async-trait v0.1.89
Compiling tokio v1.52.3
Compiling axum-core v0.4.5
Compiling hyper v1.10.1
Compiling tower v0.5.3
Compiling hyper-util v0.1.20
Compiling axum v0.7.9
Compiling myapp v0.1.0 (/home/ubuntu/myapp)
Finished dev [unoptimized + debuginfo] target(s) in 3m 07s
ビルドが終わったら起動してみます。
Axum server listening on http://0.0.0.0:3000
別のターミナルで curl を実行して動作確認します。
< HTTP/1.1 200 OK
< content-type: text/plain; charset=utf-8
< content-length: 27
Hello from Axum on Ubuntu!
実際に計測したところ、localhost への GET リクエストは レスポンスタイム 2.9ms(HTTP 200) でした。
axum がどれだけ軽量かがよく分かります。


リリースビルドとバイナリサイズ
手順7:cargo build –release で最適化する
本番サーバーには必ず --release フラグを付けてビルドします。
デバッグ情報の除去と最適化が有効になり、バイナリサイズと実行速度が大きく改善されます。
Compiling tower v0.5.3
Compiling hyper-util v0.1.20
Compiling axum v0.7.9
Compiling myapp v0.1.0 (/home/ubuntu/myapp)
Finished release [optimized] target(s) in 1m 59s
$ ls -lh target/release/myapp
-rwxr-xr-x 1 ubuntu ubuntu 5.7M Jun 14 11:20 target/release/myapp
デバッグビルドと比べると次のような差があります。
| ビルド種別 | コンパイル時間(実測) | バイナリサイズ(実測) | 実行速度 | 用途 |
|---|---|---|---|---|
cargo build |
3分07秒 | 40 MB | 遅い(デバッグ情報付き) | 開発・テスト |
cargo build --release |
1分59秒 | 5.7 MB | 最速(最適化済み) | 本番必須 |
注意
リリースビルドはコンパイル最適化が重いため、デバッグビルドより時間がかかることもあります。プロジェクトが大きくなるほど差が出ます。CI/CD 環境ではビルドキャッシュを活用するのがポイントです。
バイナリだけをコピーして VPS に配置できるのが Rust の強みです。ランタイムのインストールが不要なので、デプロイが非常にシンプルになります。
systemd サービスとして登録する
VPS で axum を常時稼働させるには systemd サービスとして登録します。
登録すると OS が起動したとき自動で axum も立ち上がり、プロセスが落ちたときも自動で再起動します。
手順8:ユニットファイルを作る
/etc/systemd/system/myapp.service を次の内容で作成します。
Description=Axum Web Server
After=network.target
[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/myapp
ExecStart=/home/ubuntu/myapp/target/release/myapp
Restart=on-failure
RestartSec=5
Environment=RUST_LOG=info
[Install]
WantedBy=multi-user.target
手順9:サービスを有効化・起動する
$ sudo systemctl enable myapp
Created symlink /etc/systemd/system/multi-user.target.wants/myapp.service → /etc/systemd/system/myapp.service.
$ sudo systemctl start myapp
$ sudo systemctl status myapp
● myapp.service – Axum Web Server
Loaded: loaded (/etc/systemd/system/myapp.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2026-06-14 11:30:00 UTC; 2s ago
Main PID: 12345 (myapp)
Tasks: 2 (limit: 1131)
Memory: 4.2M
メモリ使用量が 4.2M しかない点が Rust の強みです。
Python の Flask や Node.js の Express では同じ Hello World でも数十〜数百 MB 消費するのと対照的です。
よくあるエラーと解決策
エラー1:error: linker `cc` not found
|
= note: No such file or directory (os error 2)
原因:build-essential が入っていないため、C のリンカ(cc/gcc)が見つからない。
解決:
エラー2:error[E0463]: can't find crate for `std`
原因:rustup の標準ライブラリがターゲットトリプルに対してインストールされていない。
解決:現在のホストトリプルを確認して rustup target add する。
Default host: x86_64-unknown-linux-gnu
installed toolchains: stable-x86_64-unknown-linux-gnu
$ rustup target add x86_64-unknown-linux-gnu
エラー3:Address already in use (os error 98)
原因:ポート 3000 が別のプロセスで使われている。
解決:使用中プロセスを確認して kill する。
LISTEN 0 128 0.0.0.0:3000 0.0.0.0:* users:((“myapp”,pid=12345,fd=7))
$ kill 12345
エラー4:cargo: command not found
原因:rustup インストール後に ~/.cargo/env を読み込んでいない(パスが通っていない)。
解決:
# または新しいシェルセッションを開く
$ echo ‘source “$HOME/.cargo/env”‘ >> ~/.bashrc
まとめ
Ubuntu 24.04 LTS 上で axum を使った Rust Web サーバーを構築する手順を実測データとともにまとめました。
- Ubuntu 24.04 の apt の rustc は
1.75.0(22.04 と同じ)。axum 開発はrustupで最新版(1.96.0 以降)を使う - axum 0.7.9 + tokio の初回ビルドはデバッグで
3分7秒、リリースで1分59秒(実測)。2回目以降は変更部分のみの差分ビルドで数秒 - リリースビルドのバイナリは
5.7MB。バイナリ単体をサーバーにコピーするだけでデプロイ完了 - HTTP GET レスポンスは localhost で
2.9ms。非常に低オーバーヘッド - 本番環境では
systemdサービスとして登録し、OS 再起動後も自動起動させるのが定石

axum をより深く使うには JSON レスポンス・パスパラメータ・ミドルウェアを順番に試すのがおすすめです。次のステップとして VPS 上での本番デプロイを検討している方は、下記の VPS 比較記事も参考にしてください。



コメント