📰

zennの執筆環境向けdevcontainerを作成した話

2022/04/18に公開

タイトルまんまでzennの執筆環境向けdevcontainerを作成したという話です
前々からzennの記事はGithub repositoryと連携して書いており、codespaceにvscodeから接続して執筆してたのですが、zenn-cliを使ったプレビューが可能らしいということを最近知ったので、devcontainerの勉強がてらサクッとプレビューが可能な環境を作りましたという内容になります

作ったdevcontainerのリポジトリはこちらです
https://github.com/bells17/zenn-template

使い方

READMEに書いてある通りですが、template repositoryなので、これからGithubでリポジトリを作り始める人は"Use this template"でこのリポジトリをテンプレートとして作成すれば、あとはcodespaceを立ち上げるだけですぐに執筆環境が作れるという感じです

既にリポジトリがある方は.devcontainerディレクトリをそのままリポジトリにコピペして貰えればあとはcodespaceを立ち上げるだけで動きます

起動したらあとは執筆するだけで、devcontainer起動時から zenn preview コマンドでプレビュー環境を起動してあるので、 http://localhost:8000 にアクセスするだけでWeb GUIが表示されると思います
(既に8000ポートが使われてる場合は別のポートが割り当たるようです)

試しにこの記事を書く時にdevcontainerでプレビューを見ながら書いてみたのですが、ファイルを追加したり、テキストを書いて保存するだけで自動的にWeb GUIに反映されるので、実際の表示(に近いもの)を確認しながらかけて思ってた以上に快適でした

devcontainer

devcontainerの設定をしたのは今回が初めてだったので結構苦戦したのですが、codespaceが利用している(と思われる)
https://github.com/microsoft/vscode-dev-containers/tree/v0.229.0/containers/codespaces-linux
をベースに一部書き換える形で以下のように設定してます

.devcontainer/devcontainer.json
{
  "name": "zenn",
  "postStartCommand": "git config --global include.path ${containerWorkspaceFolder}/.devcontainer/.gitconfig; docker-compose -f ./.devcontainer/docker-compose.yml up -d",
  "appPort": [
    8000,
  ],
  "image": "mcr.microsoft.com/vscode/devcontainers/universal:1.7.5",
  ...
}

imageより下の部分についてはcodespaceのdevcontainer.jsonの設定そのまんまで利用しています
本当はdockerComposeFileを利用してdocker-composeを起動したくて試行錯誤したんだけど何故かこのファイルだと動かなくて(別の設定ファイルの時は動いたんだけどな)まとめて postStartCommand で起動しています
(gitのコマンドエイリアスを設定したのでついでに postStartCommand で設定も入れてます)
その他独自設定したのは以下のような感じです

  • appPort: ここで指定したポートが自動でforwardされます、今回の場合は zenn preview で起動するサーバーのポートを割り当ててます
  • image: devcontainerで起動するコンテナでcodespaceのコンテナイメージを利用してます

参考記事:

docker-compose.ymlの中身はこんな感じですごい簡単です

.devcontainer/docker-compose.yml
version: '3'
services:
  zenn:
    image: ghcr.io/bells17/zenn:1.1.0
    volumes:
      - ../:/zenn
    ports:
      - 8000:8000

このイメージだけ(既存のいい感じのがあるのか不明だったので)自分で作りました

Docker Image

イメージはこんな感じで自作してみました
自作ついでにGithub PackageをContainer Registryとして利用してみました

https://github.com/bells17/zenn-template/pkgs/container/zenn

Github Actionsのワークフローはこんな感じです
(https://github.com/topolvm/pvc-autoresizer/blob/main/.github/workflows/release.yaml を参考に書き換えました)

.github/workflows/release.yaml
name: "Release"
on:
  push:
    tags:
      - "v*"
jobs:
  release:
    name: "release"
    runs-on: "ubuntu-20.04"
    permissions:
      contents: read
      packages: write
    steps:
      - name: "Validate Release Version"
        id: "check_version"
        run: |
          VERSION=$(echo $GITHUB_REF | sed -ne 's/[^0-9]*\([0-9]\+\.[0-9]\+\.[0-9]\+\(-.*\)\?\).*/\1/p')
          if [ "$VERSION" = "" ]; then
            # Invalid version format
            exit 1
          fi
          if [ $(echo $VERSION | grep "-") ]; then PRERELEASE=true; else PRERELEASE=false; fi
          echo "::set-output name=version::${VERSION}"
          echo "::set-output name=prerelease::${PRERELEASE}"
      - uses: actions/checkout@v2
      - name: Log in to the Container registry
        uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - run: make image
      - run: make tag IMAGE_TAG=${{ steps.check_version.outputs.version }}
      - run: make push IMAGE_TAG=${{ steps.check_version.outputs.version }}

下記に挙げてる参考記事でGithub ActionsからGithub Packagesへのpush(write)を許可する設定をすると

  • ${{ github.actor }}
  • ${{ secrets.GITHUB_TOKEN }}

は自動で設定されるようなので、それ以外にGithub側のGUIでの設定などはしてないです

参考記事:

おまけで Dockerfile はこんな感じで、初めてまともにOCIのPre-Defined Annotation Keysの中からあった方が良さそうなラベルをコンテナイメージに設定してみました(設定したからと言って具体的に何がうれしいのかはよくわかって無い)
https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys

Dockerfile
FROM node:17.9.0-slim
LABEL org.opencontainers.image.authors bells17
LABEL org.opencontainers.image.title zenn
LABEL org.opencontainers.image.url https://github.com/bells17/zenn-template/pkgs/container/zenn
LABEL org.opencontainers.image.source https://github.com/bells17/zenn-template
WORKDIR /zenn
EXPOSE 8000
RUN npm install -g zenn-cli@0.1.109
CMD ["zenn", "preview"]

まとめ

  • codespaceなどのdevcontainer環境でサクッと zenn preview でプレビューしなが記事や本を書けるzennの執筆環境を作りました
  • 実際に使ってみると思った以上に便利でした
  • 環境を作るために初めてdevcontainerの勉強&試行錯誤したのが結構時間かかって面倒だったけど、基本的なことはある程度は理解できたので良かったです
  • ぶっちゃけ使いこなせたらdevcontainer環境はかなり便利そうな気がしました
  • ついでにGithub Packages(ghcr.io)も試せたので良かったかなと

という感じで、要はサクッとzennで記事書く環境つくりたい人は是非使ってみてください!

Discussion