アーティファクトの構築

GitBeginner
オンラインで実践に進む

はじめに

前の実験では、「品質管理」(CI)について学びました。次は、その次のステップであるパッケージ化に進みます。

ソフトウェアを工場で作られる製品だと考えてみましょう。すべての品質テストに合格した後、顧客へ出荷する前に箱に入れ、封をして、ラベルを付ける必要があります。ソフトウェアの世界では、この「箱」に当たるものが、一般的にDocker コンテナです。

このようにパッケージ化した成果物をアーティファクトと呼びます。構築したアーティファクトは、後のデプロイなどのステージで同じビルドを取得できるよう、レジストリに保存する必要があります。

この再現性が重要な考え方です。デプロイでは、対象マシンごとにコードを異なる方法で再ビルドするのではなく、内容が明確なビルド成果物を使うべきです。

GitHub は、GitHub Container Registry(GHCR)というレジストリを提供しています。

この実験では、ロボットアシスタントに次の作業を教えます。

  • アプリケーションを Docker コンテナにパッケージ化する。
  • バージョンタグを付ける。
  • GitHub の倉庫へ自動的に出荷(プッシュ)する。

前提条件

引き続き github-actions-basics リポジトリを使用します。

Dockerfile を作成する

ロボットがアプリケーションをパッケージ化するには、手順が必要です。Docker では、その手順を Dockerfile という専用ファイルに記述します。

プロジェクトディレクトリへ移動します。

cd ~/project
git clone https://github.com/your-username/github-actions-basics.git
cd github-actions-basics

注:your-username を実際の GitHub ユーザー名に置き換えてください。

Dockerfile という名前のファイルを作成し、次の内容を記述します。ファイル名の D は大文字で、拡張子は付けません。

cat > Dockerfile << EOF
FROM node:16-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "index.js"]
EOF

このパッケージ化の手順は、ロボットに次の作業を指示しています。

  • FROM node:16-alpine: Node.js がすでにインストールされた軽量なベースシステムを使用します。
  • WORKDIR /app: コンテナ内に作業フォルダーを作成します。
  • COPY ...: プロジェクトファイルをコンテナ内にコピーします。
  • RUN npm install: 必要な依存関係をコンテナ内にインストールします。
  • CMD ...: このコンテナを起動したときに、アプリケーションを開始します。

次に、このファイルをリポジトリに追加して GitHub へプッシュします。

git add Dockerfile
git commit -m "Add Dockerfile"
git push

Publish ワークフローを作成する

ここでは、パッケージ化と出荷を処理する新しいワークフローを作成します。ファイル名は docker-publish.yml とします。

ファイルを作成します。

touch .github/workflows/docker-publish.yml

nano でファイルを開きます。

nano .github/workflows/docker-publish.yml

次の設定を追加します。ここでは、permissions という新しい概念を導入します。

name: Docker Publish

on:
  push:
    branches: ["master", "main"]

permissions:
  contents: read
  packages: write

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

なぜ permissions が必要なのでしょうか?

セキュリティ上の理由から、デフォルトではロボットのアクセス権限は制限されています。ロボットに GitHub アカウントの「packages」セクションへファイルをアップロードさせるには、倉庫へ入るための鍵を明示的に与える必要があります。これを指定するのが packages: write です。

これは、パイプライン設計における最小権限のよい例です。ワークフローには、実行するジョブに必要な権限だけを付与します。

nano を保存して終了します(Ctrl+X、Y、Enter)。

ビルドとプッシュのステップを追加する

次に、最も重要な部分である実際のビルドとプッシュを確認します。

Docker が提供する 2 つの公式ツール(actions)を使用します。

  1. docker/login-action: 倉庫にサインインします。
  2. docker/build-push-action: コンテナを構築して出荷します。

このステージによって、CI と配信がつながります。テストに合格すると、パイプラインはバージョン付きのアーティファクトを作成します。他のシステムは、ソースから再ビルドせずに、そのアーティファクトを後でデプロイできます。

もう一度 .github/workflows/docker-publish.yml を開きます。

nano .github/workflows/docker-publish.yml

build-and-push ジョブに、次のステップを追加します。

- name: Log in to the Container registry
  uses: docker/login-action@v2
  with:
    registry: ghcr.io
    username: ${{ github.actor }}
    password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push Docker image
  uses: docker/build-push-action@v4
  with:
    context: .
    push: true
    tags: ghcr.io/${{ github.repository }}/app:latest

特殊な変数を理解する

  • ghcr.io: GitHub の「倉庫」のアドレスです。
  • ${{ github.actor }}: GitHub のユーザー名を自動的に設定する変数です。
  • ${{ secrets.GITHUB_TOKEN }}: GitHub がロボット用に作成する一時的な特殊パスワードです。特別な操作は必要ありません。そのまま機能します。このトークンにより、パスワードを入力せずにロボットが安全にログインできます。
  • tags: コンテナに付けるラベルを作成します。形式は 倉庫のアドレス / あなたの名前 / リポジトリ名 / アプリ名 : バージョン です。

nano を保存して終了します。

次に、このワークフローを GitHub へプッシュして処理を開始します。

git add .
git commit -m "Add Docker publishing workflow"
git push

アーティファクトを確認する

ロボットが作業を開始しました。サーバーを準備し、ログインし、コンテナを構築して、アップロードしています。

  1. GitHub でリポジトリを開きます。
  2. Actions タブをクリックします。
  3. 「Docker Publish」ワークフローの実行をクリックします。
  4. 各ステップが緑色になることを確認します。

Docker Publish

「Build and push Docker image」ステップが正常に完了すると、パッケージが倉庫に保存されています。実際に確認してみましょう。

  1. リポジトリのメインページ(Code タブ)へ移動します。
  2. 右側のサイドバーを確認します。Packages というセクションが表示されます。
  3. そこに新しいパッケージが一覧表示されています。

パッケージ名をクリックすると、詳細を確認できます。これが完成したアーティファクトです。リポジトリへのアクセス権を持つユーザーは、このイメージを使ってアプリケーションをダウンロードし、実行できます。リポジトリがパブリックの場合は、一般公開されます。

GitHub Packages

まとめ

この実験では、完全な配信パイプラインを構築しました。

次のことを学びました。

  • パッケージ化: Dockerfile を記述して、アプリケーションをコンテナに入れる方法。
  • 権限: ワークフローにパッケージへの書き込みアクセス権を与える方法。
  • 保管: GitHub Container Registry(GHCR)を使ってイメージを保存する方法。
  • 自動化: 標準の actions を使って、コードを自動的にビルドして出荷する方法。

これで、ロボットアシスタントはコードをチェック(CI)し、コードを出荷(アーティファクト)できるようになりました。次の実験では、パスワードなどの機密情報を安全に扱う方法を学びます。