GitHub ActionsでDockerイメージを作成し、そのイメージを使ってローカルのDockerでコンテナを起動する
最初に
ローカルでdocker build
するとマシンのメモリが食われるて他の作業ができなくなったり、時間もかかるし環境変数とかたくさん渡してると設定も大変なので GitHub Actions でできるといいなと思ったのでやってみました。
Dockerファイルとワークフローファイルを用意する
テスト用に簡単なDockerfileを用意します。
FROM ubuntu
CMD ["echo", "hello"]
続いてワークフローのファイルです。
name: GENERATE-DOCKER-IMAGE
on:
workflow_dispatch:
jobs:
generate-docker-image:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: BuildImage
uses: docker/build-push-action@v5
with:
context: ./
file: ./Dockerfile
outputs: type=tar,dest=docker-image.tar
push: false
tags: "my-docker-image"
- name: UploadArtifact
uses: actions/upload-artifact@v4
with:
name: docker-build-output
path: ./docker-image.tar
ワークフローでは以下のステップを実行します。
- ブランチのチェックアウト
- DockerfileからDockerイメージを作成してカレントディレクトリに配置
- ビルドしたDockerイメージをGitHubのストレージにアップロード
イメージ作成には docker/build-push-action を使用します。
また、actions/upload-artifact を使うとワークフローで作成した成果物をGitHubのストレージにアップロードして保存することができます。(参考: ワークフロー データを成果物として保存する - GitHub Docs)
イメージのビルド部分について
属性 | 説明 |
---|---|
context | ビルドコンテキストにカレントディレクトリを指定 |
file | ビルドで使うDockerfileのパスを指定 |
outputs | tar形式で、"docker-image.tar"というファイル名で出力する |
push | pushはしないのでfalseを指定 |
tags | イメージ名を"my-docker-image"と指定 |
これでカレントディレクトリにdocker-image.tar
というファイルが生成されます。
- name: BuildImage
uses: docker/build-push-action@v5
with:
context: ./
file: ./Dockerfile
outputs: type=tar,dest=docker-image.tar
push: false
tags: "my-docker-image"
ワークフローを実行する
ワークフローのトリガーをworkflow_dispatch
にしてあるので画面上からブランチを選択して実行できます。
on:
workflow_dispatch:
「Run workflow」を押して実行します。
成功すると、Artifactsにdocker-image
が作成されます。
生成したDockerイメージをダウンロードする
docker-image
をクリックするとzipファイルに圧縮されてダウンロードされます。
ダウンロードフォルダに移動して確認します。
Downloads $ ls
docker-image.zip
現状はzip形式以外でダウンロードする方法はないようでした。
Zipped Artifact Downloads
現在のところ、ワークフロー実行終了後にアーティファクトをZIP以外の形式でダウンロードしたり、アーティファクトのコンテンツを個別にダウンロードしたりする方法はない。この制限の結果として、ワークフロー実行中にzipがアップロードされ、その後UIからダウンロードされた場合、二重のzipが作成されることになる。
解凍する
unzip
コマンドで解凍します。
ダブルクリックで解凍するとtarファイルまで解凍されてしまのでコマンドでやります。
Downloads $ unzip docker-image.zip
Archive: docker-image.zip
inflating: docker-image.tar
ローカルのDockerにインポートする
actionsの画面でdocker/build-push-action@v5
のログを見ると#6 exporting to client tarball
とあります。
saveではなくexportされたものなのでloadではなくimportでローカルのDockerにイメージを取り込みます。注意が必要なのは、exportはDockerのメタ情報などは無視され、ファイルシステムのみが保存されるため、CMDの指定が無くなります。そのためimportする際に--change 'CMD ["echo", "test"]'
で再度付与してやる必要があります。
Downloads $ docker import --change 'CMD ["echo", "test"]' docker-image.tar my-docker-image:latest
sha256:199e1cd44c7a2e4334084ecbc8b161e1a9346f3bd515ad1315dc4463cd672451
イメージが登録されているか確認します。
Downloads $ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-docker-image latest b05b852df1b8 8 seconds ago 77.9MB
ローカルでコンテナを起動する
docker run
でコンテナを作成して起動します。
CMD ["echo", "test"]
も実行されていることがわかります。
Downloads $ docker run my-docker-image
test
ちなみに、importする際に--change 'CMD ["echo", "test"]'
を付けずにやった場合、docker run
でイメージ名の後ろに実行コマンドを渡してやらないと下記のようにエラーになります。
Downloads $ docker run my-docker-image
docker: Error response from daemon: no command specified.
See 'docker run --help'.
この場合は、イメージにecho "test"
を渡して実行すればうまくいきます。
Downloads $ docker run my-docker-image echo "test"
test
Discussion