Rust アプリケーションのデプロイ
Zeabur は原則としてすべての種類の Rust アプリケーションをサポートします。デフォルトでは実行ファイルを自動的に検索します。プロジェクトに複数の実行ファイルがある場合、「Service 名称」欄(または ZBPACK_RUST_ENTRY を使用)で実行するファイル名を指定できます。
プロジェクトが手元にない場合は、zeabur/axum-template リポジトリを GitHub アカウントにフォークして、Zeabur でデプロイを試すことができます。
サポートされているプロジェクトタイプ
- 単一実行ファイルプロジェクト:
src/main.rsだけがエントリーポイントの Rust プロジェクト。Zeabur はcargo install後に生成された最初の実行ファイルを自動的に検索します。 - 複数実行ファイルプロジェクト:
src/main.rsの他にsrc/binにも実行ファイルがある場合は、「Service 名称」欄に最終的に実行する成果物の名称を記入するか、zbpack.jsonで設定を行います環境変数{ "rust": { "entry": "your-entry" } }ZBPACK_RUST_ENTRYを使用して同じ効果を得ることもできます。 - Cargo Workspace モノレポ:プロジェクトが複数のクレートで構成されている場合は、「Service 名称」欄に最終的に実行する成果物の名称を記入します。デフォルトでは、ワークスペース下の すべてのプロジェクト を 
cargo installします。上記のZBPACK_RUST_ENTRY方法で実行ファイル名を指定する以外に、zbpack.jsonでこのアプリケーションワークスペースの位置を直接指定することもできます。アプリケーションがリポジトリのルートディレクトリのrest-apiフォルダにある場合、次のように記入します:環境変数{ "rust": { "app_dir": "rest-api" } }ZBPACK_RUST_APP_DIRを使用して同じ効果を得ることもできます。 
指定された実行ファイルが存在しない場合は、自動検索モードに切り替わります。「自動検索」では、コンパイルされたすべての実行ファイルを検索し、最初に見つかったファイルを実行します。このモードは複数プロジェクトのシナリオでは間違えやすいため、複雑なプロジェクトシナリオ(複数実行ファイルプロジェクトなど)では、正しい「Service 名称」を記入することをお勧めします。
最終成果物の名前を探す
最終成果物はプロジェクトの target/release にあります。具体的な探し方:
- 
プロジェクトをコンパイルするには Rust ツールチェーンが必要です。Rust 公式サイト からダウンロードできます。
 - 
デプロイするプロジェクトをクローンし、プロジェクトディレクトリに移動します。
 - 
cargo build --releaseを実行してプロジェクトをコンパイルします。$ cargo run --release Compiling zeabur v0.1.0 (/project) Finished release [optimized] target(s) in 0.65s Running `target/release/zeabur` - 
Running
target/release/zeaburという行を見つけ、最後の実行ファイル名(zeabur)を抽出します。 - 
Service 名称または
ZBPACK_RUST_ENTRYにzeaburを記入します。 
設定の最終成果物は最後に /app/main という名前になります。
他のファイルのコピー
実行ファイル以外にもコードベースの他のファイルに依存している場合。例えば:
*
|`-- public  <-- プログラムはこのフォルダに依存しています
|`-- src
|  `-- main.rs
|`-- Cargo.toml
|`-- Cargo.lock
`--- config.toml   <-- プログラムはこのファイルに依存していますzbpack.json に rust.assets を記入し、保持したいフォルダやファイルをリストします。フォルダは / で終わる必要があります。例:
{
  "rust": {
    "assets": [
      "public/",
      "config.toml"
    ]
  }
}カスタムコンパイルと起動コマンド
Zeabur は Rust で「コンパイルコマンド」、「起動コマンド」、および「起動前コマンド」を提供しており、Rust プロジェクトの各構築段階で必要な依存関係を挿入したり、必要なファイルを書き込んだりすることができます。
コンパイルコマンド
ZBPACK_BUILD_COMMAND を使用して コンパイル前に実行するコマンド を指定できます。例えば:
ZBPACK_BUILD_COMMAND=apt update && apt install -y sqlite3 && rm -rf /var/lib/apt/lists/*また、zbpack.json を使用して指定することもできます:
{
  "build_command": "apt update && apt install -y sqlite3 && rm -rf /var/lib/apt/lists/*"
}起動コマンド
ZBPACK_START_COMMAND を使用して、Zeabur がデフォルトで指定する起動コマンドを上書きできます。例えば:
ZBPACK_START_COMMAND="/app/main --debug"また、zbpack.json を使用して指定することもできます:
{
  "start_command": "/app/main --debug"
}起動前コマンド
起動前に依存関係をインストールする必要がある場合、ZBPACK_PRE_START_COMMAND を使用して起動前に実行するコマンドを指定できます:
ZBPACK_PRE_START_COMMAND="apt update && apt install -y sqlite3 && rm -rf /var/lib/apt/lists/*"また、zbpack.json を使用して指定することもできます:
{
  "pre_start_command": "apt update && apt install -y sqlite3 && rm -rf /var/lib/apt/lists/*"
}ZBPACK_START_COMMAND と比べて、これは持続的に実行され、再起動時に再実行されないため、速度が向上します。
自動依存関係インストール
プロジェクトが OpenSSL に依存しており、Cargo.toml に明示的に依存関係が記載されている場合(または Cargo.lock で間接的に依存している場合)、Zeabur は openssl ランタイムライブラリを自動的にインストールします。
実行環境
Zeabur は現在 rust:1-silm を実行イメージとして使用しています。実行ファイルは /app ディレクトリに配置され、作業ディレクトリは /(ルートディレクトリ)です。
rust.assets 内のファイルは、実行ファイルと同じディレクトリである /app ディレクトリに配置されます。アセットを読み取る必要がある場合、実務上は通常、実行ファイルのパスに対して相対的なパス からファイルを読み取ります。以下の例では、images アセットの場所を取得します。
use std::env;
use std::path::Path;
 
fn main() {
    let exe_path = env::current_exe().expect("Failed to get current executable path");
    let exe_dir = exe_path.parent().expect("Failed to get executable directory");
    let relative_path = exe_dir.join("images");
 
    println!("config.toml path: {:?}", relative_path);
}注意点として、設定ファイルの場合、実務上は通常、実行ディレクトリから取得します。実行ディレクトリがルートディレクトリであることを考慮し、Config Editor を使用して設定ファイルを追加する際には、/config.toml(/app/config.toml ではなく)を指定し、実行ディレクトリからファイルを読み取ってください。
use std::env;
use std::fs::File;
use std::io::{self, Read};
use std::path::PathBuf;
 
fn main() -> io::Result<()> {
    let current_dir = env::current_dir()?;
    let config_path: PathBuf = current_dir.join("config.toml");
 
    // デシリアライズには serde の使用が推奨されます。ここではデモのため read_to_string を使用します。
    let mut file = File::open(config_path)?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;
 
    println!("Config file contents:\n{}", contents);
 
    Ok(())
}