GitHub ActionsからDocker Hubに自動プッシュ

作成日：2024年9月15日(日)

## １．はじめに

Dify APIをChatbot UIから利用するために[fatwang2/dify2openai](https://github.com/fatwang2/dify2openai)を使用してDify APIのOpenAI APIゲートウェイを検証をしているのですが、2024年9月12日に[yinheli](https://www.notion.so/4f24d81d9f7e43eda9c76f9adb1b8bb3?pvs=21)氏の「[yinheli/dify2openai](https://github.com/yinheli/dify2openai/tree/main)」からのpull requestsである
「[chore(CI): Setup GitHub Actions workflow for Docker image build and push #](https://github.com/fatwang2/dify2openai/pull/6)6」が上手く動いていないように見受けられます。
（2024年9月12日の[fatwang2](https://github.com/fatwang2)氏のコメント(1 check failed)を見ての判断です）
GitHub Actionsについては以前から興味があるし、今後、会社でGitHubを契約できたら、使いたい機能なので、これを機に少し調べてみることにしました。

## ２．推定原因

[fatwang2](https://github.com/fatwang2)氏のGitHub Actionsが正しく動作しない原因は[[fatwang2/dify2openai](https://github.com/fatwang2/dify2openai)]⇒[Actions]⇒[Merge pull request #6 from yinheli/main]⇒[Summary]⇒[build.yaml]⇒[build]を見ると「Error: Username and Password required」とあるので、恐らく「[chore(CI): Setup GitHub Actions workflow for Docker image build and push #](https://github.com/fatwang2/dify2openai/pull/6)6」の「**Requirements**」に記載されている「The repository owner needs to configure secrets, including DOCKER_USERNAME and DOCKER_PASSWORD.」を設定していないことだと思える。

![Error Username and Password required.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764962/2ba29f2e-57e7-dd62-7275-c8990fc64f83.png)


## ３．推定原因の考察

実際にDOCKER_USERNAMEとDOCKER_PASSWORDだけが原因なのか、それともそもそもDocker Hubのリポジトリも作成しないといけないのかを調べるために[[fatwang2/dify2openai](https://github.com/fatwang2/dify2openai)]の.github/workflows/build.yamlのコードを調べてみた。

```bash
name: Build

on:
  push:
    branches:
      - main
    tags:
      - 'v*'

  pull_request:
    branches:
      - main
      - develop

  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4

    - uses: docker/setup-buildx-action@v3
      with:
        platforms: linux/amd64,linux/arm64
    
    - name: Login to Docker DockerHub
      uses: docker/login-action@v3
      if: ${{ github.event_name != 'pull_request' }}
      with:
        username: ${{ secrets.DOCKER_USERNAME }}
        password: ${{ secrets.DOCKER_PASSWORD }}

    - name: Prepare Docker tags
      run: |
        TAG=latest
        if [[ $GITHUB_REF == refs/tags/* ]]; then
          TAG=${GITHUB_REF#refs/tags/}
        fi
        echo "TAG=${TAG}" >> $GITHUB_ENV

    - name: Build and push Docker image
      uses: docker/build-push-action@v4
      with:
        push: ${{ github.event_name != 'pull_request' }}
        platforms: linux/amd64,linux/arm64
        labels: |
          org.opencontainers.image.source=https://github.com/${{ github.repository }}
          org.opencontainers.image.revision=${{ github.sha }}
        tags: |
          ${{ secrets.DOCKER_USERNAME }}/dify2openai:${{ env.TAG }}
```

このコードを見る限りGitHubにpushやpull_requestした際にDockerイメージをbuildして、DockerイメージをDockerHubにプッシュしているだけなのだが、tagsを見ると「 ${{ secrets.DOCKER_USERNAME }}/dify2openai:${{ env.TAG }}」となっているので、DockerHubにはsecrets.DOCKER_USERNAMEのアカウントとdify2openaiリポジトリが必要と思われます。

このことから、GitHub ActionsでDockerイメージを自動ビルドしてDockerHubにプッシュするには以下の２つの条件が前提になりそうです。

| No | 条件 | 説明 |
| --- | --- | --- |
| 1 | DockerHubにはsecrets.DOCKER_USERNAMEのアカウントが必要 | こちらのコードではDockerHubのタグをsecrets.DOCKER_USERNAMEから作成しているため |
| 2 | DockerHubにはdify2openaiというリポジトリが必要 | DockerHubのタグを作成するさいにdify2openaiとハードコーディングしているため |

## ３．fatwang2氏のDockerHubアカウントの調査

推定原因と仮説が正しいかを検証するためにまずはDockerHubにfatwang2氏のアカウントがあるか調べてみました。

[fatwang2's Profile | Docker Hub](https://hub.docker.com/u/fatwang2)というアカウントはありますが、dify2openaiというリポジトリは作成していないようです。


![fatwang2's profile.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764962/83a46ac0-2828-79fb-2c24-8845de8ad559.png)


## ４．再現

「Error: Username and Password required」を再現するために[[fatwang2/dify2openai](https://github.com/fatwang2/dify2openai)]を私のGitHubの[[potofo/difyopenai](https://github.com/potofo/dify2openai)]リポジトリにフォークしてGitHub Actionを実行してみます。
GitHub Actionsの手動実行は[Actions]⇒[Build]⇒[This workflow has a workflow_dispatch event trigger.]の「Run workflow」で実行するようです。

![reproduce_error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764962/c6b36ed1-830d-0602-41f7-322969827bcc.png)


実行すると直ぐに再現できました

![reproduce.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764962/afabb6e7-2d66-9ea4-fb34-b77d98386f08.png)


## ５．対策の検証

対策の検証はDockerHubへのプッシュ時にリポジトリが自動作成されるかも気になるため、以下の２ステップで実施します。

①「secrets.DOCKER_USERNAME」と「secrets.DOCKER_PASSWORD」を設定
　　dify2openaiリポジトリを作成せず「secrets.DOCKER_USERNAME」と「secrets.DOCKER_PASSWORD」を設定してdify2openaiリポジトリが自動作成されるかを検証
　　「secrets.DOCKER_USERNAME」と「secrets.DOCKER_PASSWORD」設定はいろいろな方法があるようですが、
　　[potofo/dify2openai]⇒[Settings]⇒[Secrets and variables]から「New repository secret」から環境変数を設定するのがよさそうです。

![Actions secrets and variables.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764962/99aeb336-630a-4219-d390-e0870da9668c.png)

私のDockerHubリポジトリは「[potofo's Profile | Docker Hub](https://hub.docker.com/u/potofo)」を使用して試してみます。

![empty my dockerhub.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764962/25404b19-d49e-6ea9-4a48-48d03b2398e1.png)

![Setting Environment variables.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764962/768dcc84-4fb8-b205-cafa-4e71ee454dc5.png)


secretsを設定したあとに[potofo/dify2openai]⇒[Actions]⇒[Build]⇒[Run workflow]を実行します。

ワークフローを実行した結果、見事に成功しました。

![build workflow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764962/a8ce8552-9fe4-db87-d492-ef211f7d1e38.png)

ちゃんとDockerHubにもプッシュされています。

![Confirm DockerHUB.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764962/5b304911-97fe-da48-4f81-b50333d52b2f.png)

※「[GitHub Actions のシークレット情報と変数の設定方法 (Qiita）](https://qiita.com/mkin/items/75a4928a1fafe5eacd17)」記事参照

②dify2openaiリポジトリを作成し#1を実施
　①の結果よりdify2openaiリポジトリの作成は不要ですので

## ６．Commitを対トリガーとしてBuild&Pushされるか

念のため確認しておきます。

せっかくなので、本家が修正していないreadme.mdを修正してビルドしてみます。
Pull requests用にDocker_image_instructuonsというブランチを作成して作業して、mainブランチに変更入れてみます。

```diff
 readme.md | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/readme.md b/readme.md
index 499e8ed..e6fc10a 100644
--- a/readme.md
+++ b/readme.md
@@ -100,6 +100,25 @@ services:
 
 Please change the environment variables according to your needs.See [Environment Variable](#environment-variable) for more information.
 
+### Docker Image Deployment
+Prepared a Docker image for those who find it difficult to build.
+
+- Run the container
+```bash
+docker run -d  \
+    --network=bridge \
+    -p 3000:3000 \
+    -e DIFY_API_URL=https://api.dify.ai/v1 \
+    -e BOT_TYPE=Chat \
+    --restart always
+    fatwang2/dify2openai:latest
+```
+
+- Run the container with docker-compose-image.yml
+```bash
+docker compose -f docker-compose-image.yml up -d
+```
+
 ## Environment Variable
 This project provides some additional configuration items set with environment variables:
 

```

```diff
 docker-compose-image.yml | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/docker-compose-image.yml b/docker-compose-image.yml
new file mode 100644
index 0000000..95c87cf
--- /dev/null
+++ b/docker-compose-image.yml
@@ -0,0 +1,14 @@
+version: '3.5'
+services:
+  # dify2openai API relay service
+  dify2openai:
+    image: fatwang2/dify2openai:latest
+    container_name: dify2openai
+    network_mode: bridge
+    ports:
+      - "3010:3000"
+    restart: always
+    environment: 
+      - DIFY_API_URL=http://localhost/v1
+      - BOT_TYPE=Chat
+      - MODELS_NAME=dify
\ No newline at end of file

```

きちんの再ビルドされているようです。

![Confirm rebuild.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3764962/8b35513a-53d7-28e5-3ac2-782d16663856.png)

## ７．Pull requests

[Add Docker Image Instructions #7](https://github.com/fatwang2/dify2openai/pull/7)でreadme.mdの修正を依頼しておきました。