🍣

Zenn-CLIをDockerで構築しつつMakefileで快適に動かす

2020/10/01に公開4

きっかけ

ということで実際にやってみました。

前提

リポジトリの構成を以下[1]のようにします。

zenn-contents.git
├ articles -> Zenn-CLIで管理される記事ディレクトリ
├ books -> Zenn-CLIで管理される本ディレクトリ
├ CLI
│ ├ Dockerfile
│ └ package.json -> Zenn-CLIのバージョン管理に使用
├ docker-compose.yml
└ Makefile

コンテナ内の作業ディレクトリ構成

まずはDockerfiledocker-compose.ymlを以下の通り作成します。

Dockerfile

FROM node:12

WORKDIR /zenn

ADD package.json /zenn/package.json
RUN npm install

EXPOSE 8000

ENTRYPOINT [ "npx", "zenn" ]
CMD [ "preview" ]

公式の手順のようにしても良かったのですが、複数のPCで編集できるようにすることを考えるとZenn-CLIのバージョンも管理した方がいいと思いpackage.jsonをgit管理することにしています。

また、ENTRYPOINTCMDを組み合わせることでコンテナ実行時の引数をよしなに省略することができます。

docker-compose.yml

version: '3.1'
services:
  zenn-cli:
    build:
      context: ./CLI
    volumes:
      - ./articles:/zenn/articles
      - ./books:/zenn/books
    working_dir: /zenn
    ports: 
      - 127.0.0.1:8000:8000

articlesbooksだけをマウントすることで記事と本のみをホスト-コンテナ間で共有でき、余計なファイルが行ったり来たりするのを防げます。

実際に動かしてみる

まずdocker-compose upと打って以下のようになることを確認します。

zenn-cli_1  | 👀Preview on http://localhost:8000

その後、ブラウザでhttp://localhost:8000/を開いてZenn Editorが出れば成功です。

ただし、このままだとターミナルがZenn-CLIに独占されてしまうので、今後はdocker-compose up -dでデーモンとして動かすようにします。

Makefileでコマンドを簡略化

ここに打つのが面倒なコマンドがあるじゃろ?

( ^ω^)
docker-compose up -d

これをこうして…
( ^ω^)
≡⊃⊂≡

こうじゃ
( ^ω^)
make

ここに覚えにくいコマンドがあるじゃろ?

( ^ω^)
docker-compose run zenn-cli new:article

これをこうして…
( ^ω^)
≡⊃⊂≡

こうじゃ
( ^ω^)
make article

up:
	docker-compose up -d

down:
	docker-compose down

article:
	docker-compose run zenn-cli new:article

book:
	docker-compose run zenn-cli new:book

shell:
	docker-compose run --entrypoint bash zenn-cli

update:
	@jq ".dependencies[\"zenn-cli\"] = \"`docker-compose run --entrypoint npm zenn-cli show zenn-cli version | tr -d '\r'`\"" CLI/package.json > CLI/tmp.json
	@mv CLI/tmp.json CLI/package.json
	docker-compose build

終わりに

プレビューを表示したまま記事のmdファイルを更新するとリアルタイムでプレビューに反映されるので捗りますね(・∀・)
更にGitHubで管理できる->GitHub Actionsが使える->CIでTextLintが簡単に動かせる!
ってことでTextLintも組み込めば快適な執筆環境が作れそうですね😇

脚注
  1. 厳密には.gitignoreREADME.mdもありますが本質ではないのでここでは割愛しています ↩︎

Discussion

sogaohsogaoh

いい感じに使えそうです。情報ありがとうございます。
docker-compose.yml の version: '3.1' には特別な意図がありますか?
自分は 3.8 で動かしてみて、まだ数時間ですが特に問題ないです。

椎名夏希椎名夏希

コメントありがとうございます!

version についてですが、ドキュメントに以下のように書かれており、
version: '3'とすると3.0で固定されてしまうが、version: '3.1'とすることで、マイナーバージョンをよしなに追従してくれる」
と解釈しています(間違っていたらご指摘ください)。

  • Version 3.x, the latest and recommended version, designed to be cross-compatible between Compose and the Docker Engine’s swarm mode. This is specified with a version: '3' or version: '3.1', etc., entry at the root of the YAML.

v2 and v3 Declaration

Note: When specifying the Compose file version to use, make sure to specify both the
major and minor numbers. If no minor version is given, 0 is used by default and not the > latest minor version.

https://docs.docker.com/compose/compose-file/compose-versioning/#versioning

sogaohsogaoh

DeepL 翻訳ですが、

ComposeとDocker Engineのスウォームモードとの相互互換性を考慮して設計された、最新の推奨バージョンであるバージョン3.x。これはYAMLのルートにversion: '3'やversion: '3.1'などのエントリで指定されます。

注意:使用するComposeファイルのバージョンを指定する際には、必ずメジャーとマイナーの両方を指定してください。マイナーバージョンが指定されていない場合、デフォルトでは最新のマイナーバージョンではなく 0 が使用されます。

と訳が返ってくるので、使う機能とDockerのバージョンnに応じてマイナーバージョンまで適切に指定するのがおそらく正解のように思います。
こちらの docker-compose.yml に関しては '3' でも大丈夫そうに思いました。

なお、自分は脆弱性診断ツールの都合上、Dockerfile, package.json, packeage-lock.json をリポジトリ直下に移しました。
併せて、Makefile と docker-compose.yml を調整して運用しています。

椎名夏希椎名夏希

使う機能とDockerのバージョンnに応じてマイナーバージョンまで適切に指定するのがおそらく正解

言われてみればそんな気がしてきました、ありがとうございます。

こちらの docker-compose.yml に関しては '3' でも大丈夫そうに思いました。

そうですね、3.1以上で追加されたパラメータは使っていないので3.0でも十分だと思います。