CodespacesをDockerfileでカスタマイズする
この記事について
ZennブログはGitHubリポジトリと連携可能!
なので、GitHub Codespacesを使った執筆も可能となります。
記事公開までの大まかな流れは以下の通り。
- Zenn CLIで記事の雛形を作成(Markdownファイル)
- Markdownファイルを更新
- Zenn CLIで作成した記事のプレビューを確認
- リポジトリにpushするとZenn側で記事が新規作成される
上記のように、GitHub連携した状態で記事を作成するにはZenn CLIをインストールした環境が必要です。
まぁ、インストール自体は簡単なんですが、せっかくなのでこれを題材として
Dockerfileで定義してCodespacesの環境をカスタマイズしてみよう!
といった内容になります。
Dockerfile化のメリット
環境の情報をDockerfileに記述することで、以下のようなメリットがあります。
- 公式イメージをベースにカスタマイズできる
- OS環境構成(カーネル除く)をコードで可視化できる
- GitでOS環境構成(カーネル除く)の変更履歴を管理しやすい
そして僕が一番推している点は、自分以外の他のメンバーでも、コンテナ実行環境さえあればDockerfileからその環境をすぐに構築可能ということです!
Zennブログ執筆環境の構築
GitHubとの連携
こちらの手順に従い設定を進めます。
ただし、リポジトリを作成する際Add a README file
にチェックを入れるなどして初期化していたほうが、あとからCodespacesを利用しやすいです。
Codespacesでの作業
連携したリポジトリを開き、緑色のボタンからCodespacesを起動します。
開発環境が立ち上がったら、以下のドキュメントを参考に設定ファイルを作成していきます。
Codespacesでは、Gitリポジトリのトップに.devcontainer
というディレクトリを作成し、その中にdevcontainer.json
ファイルに定義することで、起動時の環境をカスタマイズ可能とのこと。
各種ファイルを作成
.devcontainer/**/devcontainer.json
(サブフォルダがあってもいい)を以下内容で作ることで、環境をDockerfile
からビルドするようになります。
{
"build": { "dockerfile": "Dockerfile" }
}
次に、同一フォルダにDockerfile
を以下内容で作成します。
Zenn CLIのインストールにはnpm
が必要とのことで、ベースイメージはNode.js
の公式を選びました。
また、イメージを軽量化したいのでalpine
のタグを指定。
FROM node:19-alpine
WORKDIR /work
RUN npm init --yes && npm install zenn-cli
最終的に以下のフォルダ構成になります。
.devcontainer/
└── zenn-cli
├── devcontainer.json
└── Dockerfile
Dockerfileのビルド確認
Dockerfile
がある場所でdocker build
コマンドを実行し、イメージが問題なく作成されるかを確認しておきます。
workspaces/zenn-docs/.devcontainer/zenn-cli (feature_zenn-cli-test) $ docker build .
[+] Building 5.5s (7/7) FINISHED
=> [internal] load build definition from Dockerfile 0.1s
=> => transferring dockerfile: 116B 0.0s
=> [internal] load .dockerignore 0.1s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/node:19-alpine 0.8s
=> CACHED [1/3] FROM docker.io/library/node:19-alpine@sha256:72b0f918ad76b5ef68c6243869fab5800d7393c1dcccf54ef00958c2abc8164a 0.0s
=> [2/3] WORKDIR /work 0.2s
=> [3/3] RUN npm init --yes && npm install zenn-cli 3.6s
=> exporting to image 0.7s
=> => exporting layers 0.7s
=> => writing image sha256:3576c0767e05f9c571198a43b68f23d4f2f67d91d1312d0879624d041c0e9edc 0.0s
成功しました!
ここまでできたら、それぞれリモートリポジトリにpushしておきます。
Zenn CLIの動作確認
これまで使っていたCodespace環境は一旦削除し、新たな環境を立ち上げます。
(左上のメニューからMy Codespaces
を選択すると環境の一覧画面に飛ぶので、そこから消す)
まずは記事の雛形を作成。--slug
オプションでファイル名を指定してます。
/workspaces/zenn-docs (feature_zenn-cli-test) $ npx zenn new:article --slug article_yyyymmdd
created: articles/article_yyyymmdd.md
この時点で、Zenn CLIが機能していることを確認できました!
続いてMarkdownファイルを更新し、プレビューを試してみます。
/workspaces/zenn-docs (feature_zenn-cli-test) $ npx zenn preview
👀 Preview: http://localhost:8000
ここで、あれ…localhostって行けるのかな…と思いましたが、Codespacesのポートフォワード機能でうまくやってくれました!
無事にプレビューも確認できました。
まとめ
DockerfileでCodespacesの環境をカスタマイズできました。
これで、明示的に開発環境をコードで宣言して即開発可能な環境を作るイメージが伝わったかと思います!
ただしデメリットもあるようで、カスタマイズしたコンテナがStorageの枠を消費してしまうようです…。
なのでイメージサイズには気をつけたいところですが、いざとなればローカルでも同じ環境作れると思うと安心です。
ちなみに標準で使われるイメージのDockerfileはこちら。
色々入っててかつ、標準だとStorageにカウントされないので、状況に応じて使い分けできればいいかなと思います。
Discussion