はじめに
Rustアプリケーションを本番環境にデプロイするとき、Dockerコンテナと自動化されたCI/CDパイプラインを組み合わせることで、品質を保ちながら素早くリリースできます。
この記事では、RustアプリをDockerコンテナ化して、GitHub Actionsでビルド・テスト・Docker Hubへのイメージプッシュを自動化する方法をステップごとに解説します。
プロジェクト構成
まず、簡単なRustプロジェクトを用意します。
cargo new rust-ci-demo
cd rust-ci-demo
src/main.rs を以下のように編集します。
fn add(a: i32, b: i32) -> i32 {
a + b
}
fn main() {
println!("Hello from Rust CI/CD!");
println!("1 + 2 = {}", add(1, 2));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add() {
assert_eq!(add(1, 2), 3);
}
#[test]
fn test_add_negative() {
assert_eq!(add(-1, 1), 0);
}
}
Dockerfileの作成
Rustアプリにはマルチステージビルドが効果的です。ビルド環境と実行環境を分けることで、軽量なイメージを作成できます。
# ---- ビルドステージ ----
FROM rust:1.78-slim AS builder
WORKDIR /app
# 依存関係を先にコピーしてキャッシュを活用する
COPY Cargo.toml Cargo.lock ./
RUN mkdir src && echo "fn main() {}" > src/main.rs
RUN cargo build --release
RUN rm -f target/release/deps/rust_ci_demo*
# ソースコードをコピーして本番ビルド
COPY src ./src
RUN cargo build --release
# ---- 実行ステージ ----
FROM debian:bookworm-slim AS runtime
RUN apt-get update && apt-get install -y \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY --from=builder /app/target/release/rust-ci-demo .
EXPOSE 8080
CMD ["./rust-ci-demo"]
ポイント
Cargo.tomlとCargo.lockを先にコピーすることで、ソースコードが変わっても依存関係のビルドキャッシュが有効になります。- 実行ステージは
debian:bookworm-slimを使い、不要なツールを含めません。
.dockerignore も忘れずに作成しましょう。
target/
.git/
.github/
GitHub Actionsワークフローの作成
.github/workflows/ci.yml を作成します。
name: Rust CI/CD
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
DOCKER_IMAGE: ${{ secrets.DOCKERHUB_USERNAME }}/rust-ci-demo
jobs:
# ---- テスト・静的解析ジョブ ----
test:
name: Test & Lint
runs-on: ubuntu-latest
steps:
- name: コードをチェックアウト
uses: actions/checkout@v4
- name: Rustツールチェーンのセットアップ
uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- name: Cargoキャッシュの設定
uses: Swatinem/rust-cache@v2
- name: フォーマットチェック
run: cargo fmt --check
- name: Clippyで静的解析
run: cargo clippy -- -D warnings
- name: テスト実行
run: cargo test
# ---- Dockerビルド・プッシュジョブ ----
docker:
name: Docker Build & Push
runs-on: ubuntu-latest
needs: test
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
steps:
- name: コードをチェックアウト
uses: actions/checkout@v4
- name: Docker Buildxのセットアップ
uses: docker/setup-buildx-action@v3
- name: Docker Hubにログイン
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: イメージのビルドとプッシュ
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
${{ env.DOCKER_IMAGE }}:latest
${{ env.DOCKER_IMAGE }}:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
ワークフローの流れ
testジョブ:cargo fmt・cargo clippy・cargo testを実行し、品質を検証します。dockerジョブ:testジョブが成功し、かつmainブランチへのプッシュのときのみ実行されます。
GitHub Secretsの設定
Docker Hubの認証情報をGitHubリポジトリのSecretsに登録します。
- GitHubリポジトリの Settings → Secrets and variables → Actions を開く
- 以下の2つを追加する
| Secret名 | 値 |
|---|---|
DOCKERHUB_USERNAME | Docker Hubのユーザー名 |
DOCKERHUB_TOKEN | Docker HubのAccess Token |
Docker HubのAccess Tokenは、Docker Hub → Account Settings → Security から作成できます。
動作確認
コードを main ブランチにプッシュすると、ワークフローが自動で実行されます。
git add .
git commit -m "feat: add CI/CD pipeline"
git push origin main
GitHubリポジトリの Actions タブからジョブの実行状況を確認できます。すべてのジョブが緑になれば、Docker Hubにイメージがプッシュされています。
まとめ
この記事では以下の内容を解説しました。
- マルチステージDockerfile でRustアプリを軽量コンテナ化する
- GitHub Actions でフォーマット・Clippy・テストを自動化する
needsを使ってジョブを直列につなぎ、テスト通過後のみDockerイメージをプッシュするcache-from/cache-toでDockerビルドキャッシュを活用して高速化する
CI/CDパイプラインを整えることで、コードの品質を保ちながら自信を持ってリリースできる環境が整います。ぜひ自分のRustプロジェクトに取り入れてみてください!