Qiita CLI を Node.js on Docker Compose 環境で動かしてみよう！

## はじめに

そもそも、ローカル（ ホスト ）に Node 環境があるなら、基本的には、あえて Docker で動かす必要もないわけですが、案外、同じことを考える人も多いもので、既に、いくつかの記事が存在していますね。

https://qiita.com/search?q=Qiita+CLI+Docker

個人的には、`node_modules` ディレクトリ等は Docker コンテナ内にだけあればよく、環境を丸ごと作り直したりするのが、非常に簡単だという点に、特に魅力を感じているのかもしれません。

というわけで、本記事では、Qiita CLI だけでなく、何かを Node で動かす際、Docker Compose を使って環境構築したい場合に、広く参考になりそうな手順を、備忘録も兼ねて、紹介していきます。

## 確認と準備

ともあれ、まずは、Qiita CLI を動かすために必要なファイルなどを生成してみて、確認するところから始めていきましょう。

https://github.com/increments/qiita-cli

ローカル（ ホスト ）環境に Qiita CLI をインストールしてもいいですが、Node 関係のファイルはできるだけ残したくないという過激派の方はもちろん、

依存関係を切り分けるため、あるいは、何か失敗した時などに備えて、環境を隔離しておきたいなら、次のようなコマンドを実行して、Docker コンテナ内で作業するのがオススメです。[^pc]

[^pc]: ちなみに、本記事の執筆時に利用している PC は、MacBook Pro（ 14-inch, M2 Pro, 2023 ）で、macOS Sonoma 14.3（ Docker version 24.0.7 ）環境です。

```
docker run --rm -it --name=node node:20.11.0 bash
```

Node [^node] のバージョンはお好みですが、ここでは、現時点で最新の LTS を指定しています。

[^node]: https://hub.docker.com/_/node/

コンテナに入ったら、早速、次のコマンドを実行し、Qiita CLI をインストールしましょう。

```
cd /root
npm install @qiita/qiita-cli --save-dev
```

↓（ バージョンを確認 ）

```
# npx qiita version
1.3.1
```

先に `/root` ディレクトリに移動しているのは、ファイルの生成された場所が、後から分かりやすいようにしておくためですが、ここがデフォルトのホームディレクトリになっているので、以降、割と活用していくことになります。

さて、それでは、そのまま `init` コマンドを実行して、必要なファイル群を生成し、

```
npx qiita init
```

`login` コマンドを実行したら、指示に従って（ アクセストークンを発行して設定し ）ログインまで済ませてください。

```
npx qiita login
```

ここまでは、Docker コンテナ内で作業している点を除けば、Qiita CLI の README に書いてある通りなので、特に問題はないでしょう。

`ls` コマンド（ `ls -a` ）などを実行して、ちゃんとファイルが生成されているかどうか、確認してみてください。

ただし、Docker を使っている場合、注意が必要なのは、コンテナを消すと、生成したファイル群も、全て消えてしまうということです。

というより、もともと消すつもりでコンテナを立てているわけですが、その前に、必要なファイルだけ、ホストにコピーしておきます。

`node_modules` ディレクトリもホストとマウントしたいなど、好みは分かれるかと思いますが、例えば、最低限、本記事の以降の作業で必要となるファイルのみを取り出すなら、

ターミナルの新規ウィンドウを開くなどして、作業ディレクトリ（ ファイルを置く場所 ）を作成し、以下のようなコマンドを実行してください。[^name]

[^name]: 実は、ここで `docker cp` コマンドを実行する際、コンテナを識別しやすいように、`--name=node` というオプションをつけて `docker run` コマンドを実行しておいたわけです。代わりに、コンテナの ID を使っても構いません。

```
docker cp node:/root/.config/qiita-cli/credentials.json .
docker cp node:/root/qiita.config.json .
```

まぁ、これだけなら、`cat` コマンドなどで中身を見て、自分でファイルを作成しても良いかもしれませんね。

ともかく、これで、確認と準備は終わりです。[^rm]

[^rm]: 必要なファイルが確保できたら、コンテナは削除して構いません。`--rm` オプションをつけて起動（ `docker run` ）した場合には、`exit` コマンドなどでコンテナから抜けると、自動的に削除されるはずです。

## Docker Compose 環境の構築

では、いよいよ、Docker Compose 環境の構築に入っていきましょう。

といっても、基本的には、ごく簡単な `Dockerfile` と `compose.yaml` ファイルを作成し、`docker compose` コマンドを実行するだけです。

まず、以下のような `Dockerfile` を作成してください。

```Dockerfile:Dockerfile
FROM node:20.11.0
WORKDIR /root
RUN npm install @qiita/qiita-cli --save-dev
COPY credentials.json /root/.config/qiita-cli/credentials.json
CMD ["npx","qiita","preview"]
```

環境を整え、上で確保した `credentials.json` を適切な場所に配置し、起動コマンド（ `npx qiita preview` ）を指定しているだけですね。

これにより、ちゃんとログインした状態で、いきなりプレビューページを起動することができるようになります。

次に、`compose.yaml` ファイルは、例えば、以下のように書いておくと良いのではないでしょうか。

```yaml:compose.yaml
services:
  qiita-cli:
    container_name: qiita-cli
    build: .
    volumes:
      - ./qiita.config.json:/root/qiita.config.json
      - ./public:/root/public
    ports:
      - "8888:8888"
```

あらかじめ、`public` ディレクトリを作成しておくこともお忘れなく。

また、コンテナ内で起動したプレビューページに、ブラウザから `localhost` でアクセスしたいなら、`qiita.config.json` を以下のように書き換えて、設定しておきましょう。

```diff_json:qiita.config.json
{
  "includePrivate": false,
- "host": "localhost",
+ "host": "0.0.0.0",
  "port": 8888
}
```

これで、単に `docker compose up -d` を実行すれば、http://localhost:8888 で、以下のようなページにアクセスできるはずです。[^compose]

[^compose]: `Dockerfile` を更新するなどして、ビルドする必要がある時には、`docker compose up -d --build` 等を実行してください。

![Screenshot 2024-01-28 at 14-58-15 Qiita Preview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109175/a60701c0-d023-e350-892f-12fadb68593e.png)

サイドバーを開いたら、Qiita で書いた自分の記事が並んでいるでしょうか？

ちなみに、新しい記事を作成したり、投稿や更新などを行う際には、Docker Compose 環境の場合、例えば、次のようにして、実行したいコマンドを、コンテナ内へ受け渡すことができます。

```
docker compose exec -T qiita-cli npx qiita new newArticle001
```

## おわりに

とりあえず、環境構築の手順としては、最低限の情報を共有できているかと思いますが、どうでしょうか？

今、まさにここで説明したような方法で Qiita CLI を動かし、本記事を執筆しているのですが、これが正常に投稿できたら、次のステップとして、今度は、個人的な執筆環境も含めて、投稿までの流れを紹介する記事などを書いていきたいと思います。

あと、ゆくゆくは（ GitHub Actions のワークフローファイルも利用して ）GitHub で記事を管理することも、検討していきたいところですね。[^credentials]

[^credentials]: もちろん `credentials.json` については、リモートリポジトリで公開しないよう、取り扱いに注意してくださいね。

それでは、良きローカル環境執筆ライフを！