🐡

デプロイ時のURLにコミットメッセージを表示して、修正が反映されているかを自動確認する方法(備忘録)

2024/08/01に公開

デプロイ時のURLにコミットメッセージを表示して、修正が反映されているかを自動確認する方法

はじめに

APIのデプロイ時にエラーの修正を行ったものの、現在サーバーで動いているコードが修正前のものなのか後のものなのかわからないことってありませんか?そんなときに、デプロイ日時とコミットメッセージを自動で記録し、サーバーに表示できれば、現在稼働中のコードが最新のものであるか一目で確認できます。本記事では、デプロイ日時とコミットメッセージを自動的に記録し、表示する方法を紹介します。

使用環境

  • Docker: コンテナ化技術
  • Docker Compose: 複数のコンテナアプリケーションを定義し実行するツール
  • GitHub Actions: CI/CDパイプラインの自動化ツール
  • FastAPI: 高速なAPI用のPythonフレームワーク

手順概要

  1. GitHub Actionsでコミットメッセージとデプロイ日時を取得
  2. Dockerfileに環境変数として渡す
  3. FastAPIアプリケーションで環境変数を読み込み、エンドポイントで表示

Step 1: GitHub Actionsでコミットメッセージとデプロイ日時を取得

まず、GitHub Actionsを使用して、デプロイ時のコミットメッセージとデプロイ日時を取得します。以下のYAMLファイルは、デプロイ時にこれらの情報を環境変数として設定するものです。

name: Build and deploy container app to Azure Web App

on:
  push:
    branches:
      - main
  workflow_dispatch:

env:
  DOCKER_REGISTRY: your_docker_registry

jobs:
  build:
    runs-on: 'ubuntu-latest'

    steps:
    - uses: actions/checkout@v2

    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v2

    - name: Log in to registry
      uses: docker/login-action@v2
      with:
        registry: ${{ env.DOCKER_REGISTRY }}
        username: ${{ fromJson(secrets.AZURE_CREDENTIALS).acrUsername }}
        password: ${{ fromJson(secrets.AZURE_CREDENTIALS).acrPassword }}

    - name: Set environment variables
      run: |
        echo "APP_VERSION=$(date +'%Y.%m.%d.%H.%M')" >> $GITHUB_ENV
        echo "DEPLOYMENT_TIME=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV
        COMMIT_MESSAGE=$(git log -1 --pretty=%B)
        echo "COMMIT_MESSAGE=${COMMIT_MESSAGE}" >> $GITHUB_ENV
        echo "Commit message: ${COMMIT_MESSAGE}"

    - name: Build and push container image to registry
      uses: docker/build-push-action@v3
      with:
        push: true
        tags: ${{ env.DOCKER_REGISTRY }}/${{ secrets.DOCKER_IMAGE_NAME }}:${{ github.sha }}
        file: ./Dockerfile
        build-args: |
          APP_VERSION=${{ env.APP_VERSION }}
          DEPLOYMENT_TIME=${{ env.DEPLOYMENT_TIME }}
          COMMIT_MESSAGE=${{ env.COMMIT_MESSAGE }}

  deploy:
    runs-on: ubuntu-latest
    needs: build
    environment:
      name: 'production'
      url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}

    steps:
    - name: Log in to Azure
      uses: azure/login@v1
      with:
        creds: ${{ secrets.AZURE_CREDENTIALS }}

    - name: Deploy to Azure Web App
      id: deploy-to-webapp
      uses: azure/webapps-deploy@v2
      with:
        app-name: ${{ secrets.DOCKER_IMAGE_NAME }}
        slot-name: 'production'
        publish-profile: ${{ secrets.AzureAppService_PublishProfile }}
        images: ${{ env.DOCKER_REGISTRY }}/${{ secrets.DOCKER_IMAGE_NAME }}:${{ github.sha }}

Step 2: Dockerfileに環境変数として渡す

次に、Dockerfileを修正して、GitHub Actionsで取得した環境変数をコンテナに渡します。

FROM mcr.microsoft.com/playwright:focal

RUN apt-get update && apt-get -y install x11vnc websockify novnc python3 python3-pip

WORKDIR /app

COPY requirements.txt requirements.txt
RUN pip3 install --no-cache-dir -r requirements.txt
RUN pip3 install playwright
RUN playwright install

COPY . .

ARG APP_VERSION
ARG DEPLOYMENT_TIME
ARG COMMIT_MESSAGE
ENV APP_VERSION=$APP_VERSION
ENV DEPLOYMENT_TIME=$DEPLOYMENT_TIME
ENV COMMIT_MESSAGE=$COMMIT_MESSAGE

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]

Step 3: FastAPIアプリケーションで環境変数を読み込み、エンドポイントで表示

最後に、FastAPIアプリケーションで環境変数を読み込み、エンドポイントで表示します。

import os
from datetime import datetime, timedelta
from fastapi import FastAPI

app = FastAPI()

APP_VERSION = os.environ.get("APP_VERSION", "Unknown")
DEPLOYMENT_TIME = os.environ.get("DEPLOYMENT_TIME", "Unknown")
COMMIT_MESSAGE = os.environ.get("COMMIT_MESSAGE", "No commit message")

@app.get("/")
def read_root():
    def format_time(time_str):
        if time_str and time_str != "Unknown":
            try:
                deploy_time = datetime.strptime(time_str, "%Y-%m-%dT%H:%M:%SZ")
                deploy_time_jst = deploy_time + timedelta(hours=9)
                return deploy_time_jst.strftime("デプロイ : %-m/%-d %-H:%M")
            except ValueError:
                return time_str
        return "不明"
    
    return {
        "最終デプロイ日時": format_time(DEPLOYMENT_TIME),
        "コミットメッセージ": COMMIT_MESSAGE
    }

Docker Composeを使用する場合

もし複数のサービスをまとめて管理する場合、Docker Composeを使用すると便利です。以下に、docker-compose.ymlの例を示します。

version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
      args:
        APP_VERSION: ${APP_VERSION}
        DEPLOYMENT_TIME: ${DEPLOYMENT_TIME}
        COMMIT_MESSAGE: ${COMMIT_MESSAGE}
    environment:
      - APP_VERSION=${APP_VERSION}
      - DEPLOYMENT_TIME=${DEPLOYMENT_TIME}
      - COMMIT_MESSAGE=${COMMIT_MESSAGE}
    ports:
      - "80:80"

結論

これで、デプロイ日時とコミットメッセージを自動的に記録し、サーバーに表示する方法が完成しました。この方法を使えば、現在サーバーで動いているコードが最新のものであるかどうかを簡単に確認できます。これにより、デプロイ後の混乱を防ぎ、開発プロセスをスムーズに進めることができます。

Discussion