GithubActionsを使ったDockerImageのDeploy
はじめに
アプリケーションを開発する際に、Developerには開発環境一式としてDockerのimageを配布することがある。
DockerのimageをRegistryから引っ張ってくれば、開発者側はアプリケーションを開発するための環境準備を特別に行うことなく、実行することができる。
また、ユーザー間での環境の差分をなくすことができるので、環境起因によるデバッグの時間を減らすことが可能だ。
開発環境提供側は、開発環境の中身のUpdateがある度にDocker imageをUpdateする必要があるが、そこで手動の作業が発生すると、従来のイメージとは違った環境を提供してしまう可能性がある。できる限り自動化をすることで、開発者への環境のDeployもシームレスに行っていくことが求められている。
今回は、GithubActionsを使用して、Docker imageの作成とDocker hubへのPushまでを自動化してみる。
構築環境全体像
GithubとDockerHubへのアクセスができることを前提条件とする。
ベースイメージから、「docker run」コマンドでDockerコンテナを立ち上げる。
ここで特定の操作をコンテナ上で行い、環境のセットアップをすることも可能である。
「docker commit」コマンドで、Dockerコンテナ内でセットアップされた環境を反映した形でDockerImageを作成する。
その後、DockerFileを用いて「docker build」を行い最終的なDockerImageを作成する。
作成したDockerImageは、DockerHubへPushされDeveloperはそのDockerImageを用いることで、開発環境をセットアップすることができる。
Script
ディレクトリ構成は下記の通り。
|--.git
|--.github
| |--workflows
| | |--create-docker-image.yaml
|--Dockerfile
|--README.md
|--test.txt
※ディレクトリ構成を表示するのに便利なコマンド(treeコマンドがない環境)
pwd;find . | sort | sed '1d;s/^\.//;s/\/\([^/]*\)$/|--\1/;s/\/[^/|]*/| /g'
create-docker-image.yamlファイルは下記の通り。
.github/workflows/create-docker-image.yaml
---
name: create-docker-image
on:
push:
workflow_dispatch:
jobs:
create-docker-image:
runs-on: ubuntu-latest
steps:
- name: checkout-repository
uses: actions/checkout@v3
with:
path: docker-sample
ref: feature/add-creation-docker-image
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: docker-run
id: check-container-id
run: |
docker run -dit --name my-apache-app -p 8080:80 -v "${{ github.workspace }}":/usr/local/apache2/htdocs/ httpd:2.4
echo "::set-output name=container-id::$(docker ps | grep my-apache-app | awk '{print $1}')"
- name: docker-commit
id: check-image-id
run: |
echo "${{ steps.check-container-id.outputs.container-id }}"
docker commit ${{ steps.check-container-id.outputs.container-id }} created-image-step1
echo docker images | grep created-image-step1 | awk '{print $3}'
echo "::set-output name=image-id::$(docker images | grep created-image-step1 | awk '{print $3}')"
docker images
- name: docker-build
run: |
echo "${{ steps.check-image-id.outputs.image-id }}"
sed -i '1s/^/FROM ${{ steps.check-image-id.outputs.image-id }}\n/' docker-sample/Dockerfile
echo "check Dockerfile"
cat docker-sample/Dockerfile
docker build -t ${host}/image-sample -f docker-sample/Dockerfile .
docker images
docker ps -a
docker push ${host}/image-sample
confirm-docker:
runs-on: ubuntu-latest
needs: [create-docker-image]
container: #起動するコンテナイメージを指定
image: ${host}/image-sample #指定のdockerイメージを使用
steps: #dockerコンテナ内でステップを実行
- name: confirm-inside-docker
run: |
cat /usr/local/apache2/htdocs/test.txt
コンテナを立ち上げたら、「docker ps」コマンドと「grep」コマンドを駆使してコンテナidやイメージidをパースし、ステップ間でパースした値を渡している。
「docker build」や「docker push」を実行してくれるactionsがあったが、今回はできる限りコマンドを直打ちして実現した。(本当はできる限りactionsを使ってメンテナンス性を上げる必要があるが、今回は動作を理解するためにあえてハードコーディングした。)
ポイントは、パースしたimage idをsedでDockerfileに追記している点。
Dockerfileは、下記の通りCOPYコマンドだけ記載。(workflowの中でFROM ${image id}を追記。)
COPY docker-sample/test.txt /usr/local/apache2/htdocs/
また、test.txtファイルには下記の通りsampleのコメントを記載。
sample file to incorporate in docker image
実行結果
実行ファイルからもわかる通り、「confirm-docker」jobを作成し、Dockerfileに記載した通りにimageの中にtest.txtが反映されているかを確認した。
Workflow全体
create-docker-image job
confirm-docker job
confirm-docker jobの実行結果より、作成したimageの中に意図通りtest.txtがが格納されていることが確認できた。
まとめ
今回は、GithubActionsとDockerを組み合わせることによって、開発環境のDeployの自動化を簡易バージョンで作成しました。
あらゆる場面で、多少やり方は違えど同じように環境を作成し、提供する現場が多いと思います。
基本をしっかりと押さえて、開発に活用していきたいと思います。
ディスカッション
コメント一覧
まだ、コメントがありません