あっぽログ
← 記事一覧に戻る

RustのDockerコンテナ化でGitHub Actionsを使ったCI/CDパイプラインを構築する

はじめに

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.tomlCargo.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

ワークフローの流れ

  1. test ジョブcargo fmtcargo clippycargo test を実行し、品質を検証します。
  2. docker ジョブtest ジョブが成功し、かつ main ブランチへのプッシュのときのみ実行されます。

GitHub Secretsの設定

Docker Hubの認証情報をGitHubリポジトリのSecretsに登録します。

  1. GitHubリポジトリの Settings → Secrets and variables → Actions を開く
  2. 以下の2つを追加する
Secret名
DOCKERHUB_USERNAMEDocker Hubのユーザー名
DOCKERHUB_TOKENDocker 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プロジェクトに取り入れてみてください!

← 記事一覧に戻る