👌

Zennの執筆環境をVSCode + Dockerで作ってみた ver 3.0

2023/02/22に公開

Zenn執筆が捗るように執筆用の専用devcontainerを作りました。
自分のPCにあれこれ入れるのが嫌なので、なにかやってみたりするときはgitのリポジトリごとにdevcontainerを作っています。
今回も同様にzenn cliやmarkdownを書く時に楽になるようなextentionsを詰め込んだdevcontainerを用意したので、そのことを書いていきます。

リポジトリの用意

Githubにzenn-contentでプライベートリポジトリを作りました。
リポジトリをそのまま公開するでもよかったのですが、書いてる途中の記事とかもあるので
今回はdevcontainerの部分だけを乗せることにしました。

ディレクトリ構成

作成したContainerはVSCodeのdevcontainerで使用するので、以下のようなディレクトリ構成になっています。
devcontainerと記事や本を1つのリポジトリで保存するようにしています。

  • 単一Containerですが、docker-composeから起動するためです。(個人的な理由)
  • .extensionsはDLしたVSCode拡張をコンテナ起動時に再ダウンロードしなくてよいようにするためです。
  • articlesとbooksはzenn cliで記事作成時や本作成時に出来るディレクトリです。
  • imagesは記事を書いた時に画像を貼り付ける場合に画像が格納されるディレクトリです。
|--.devcontainer
|  |--.extensions
|  |--ubuntu
|  |  |--Dockerfile
|  |--.env
|  |--compose.yml
|  |--devcontainer.json
|---articles
|  |--.keep
|---books
|  |--.keep
|---images
|  |--.keep
|---gitignore

Dockerfileの作成

  • DockerのベースコンテナはUbuntuで作りました。
  • rootユーザーではなく、別でユーザーを作成してコンテナ内での操作をします。
  • zenn-clinpxを使わずに使用できるようにしてます。
  • Paste Imageというextentionを使うためにxclipをInstallしています。
Dockerfile
FROM ubuntu:20.04

ARG USER_ID
ARG USER_NAME
ARG GROUP_ID
ARG GROUP_NAME
ARG WORK_DIR

# 証明書のDL
RUN set -x \
    && apt-get update \
    && apt-get install -y --no-install-recommends \
        ca-certificates \
    && apt-get clean && rm -rf /var/cache/apt/archives/* /var/lib/apt/lists/*
# Set TimeZone
RUN set -x \
    && apt-get update \
    && apt-get install -y --no-install-recommends \
        tzdata \
    && apt-get clean && rm -rf /var/cache/apt/archives/* /var/lib/apt/lists/* \
    && ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \
    && echo 'Asia/Tokyo' >/etc/timezone

# Install sudo, curl
RUN set -x \
    && apt-get -y update \
    && apt-get install -y --no-install-recommends \
    sudo \
    curl \
    openssh-client \
    # Paste Imageを使うために必要
    xclip \
    && apt-get clean && rm -rf /var/cache/apt/archives/* /var/lib/apt/lists/*

# create group
RUN set -x \
    && groupadd --gid ${GROUP_ID} ${GROUP_NAME}

# create vscode user
RUN set - x \
    && echo "$USER_NAME ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/${USER_NAME} \
    && chmod 0440 /etc/sudoers.d/${USER_NAME} \
    && useradd \
        --uid ${USER_ID} \
        --gid ${GROUP_ID} \
        --home-dir /home/${USER_NAME} \
        --create-home \
        --shell /bin/bash \
        ${USER_NAME}

# vscode extensions cache (extensionsの再インストールを防ぐ)
# https://code.visualstudio.com/docs/remote/containers-advanced#_avoiding-extension-reinstalls-on-container-rebuild
RUN set -x \
    && mkdir -p /home/${USER_NAME}/.vscode-server/extensions \
    && chown -R ${GROUP_NAME}:${USER_NAME} /home/${USER_NAME}/.vscode-server

# node18 install
RUN set -x \
    && apt-get -y update \
    && curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
    && apt-get install -y --no-install-recommends \
    nodejs \
    && apt-get clean && rm -rf /var/cache/apt/archives/* /var/lib/apt/lists/*

# install yarn
RUN npm install -g yarn

# install zenn-cli
RUN set -x \
    && yarn global add \
    zenn-cli

USER ${USER_NAME}

# create working directory
RUN set -x \
    && mkdir /home/${USER_NAME}/${WORK_DIR}
WORKDIR /home/${USER_NAME}/${WORK_DIR}

compose.ymlの作成

今回は特に同時起動するContainerはないですが、僕の場合は単一Containerでもcomposeから起動してます。
ここは個人的にそうしているだけなので必須事項ではないです
Dockerfileから立ち上げたい方はそれで問題ありません。

  • ホストのvolumeマウントはcompose.ymlに書いてます。
compose.yml
version: "3.4"
services:
  zenn_cli_on_nodejs:
    container_name: $CONTAINER_NAME
    # ホスト名を明示的に指定する
    hostname: localhost
    init: true
    build:
      context: .
      dockerfile: ./ubuntu/Dockerfile
      args:
        USER_ID: 1000
        USER_NAME: $USER_NAME
        GROUP_ID: 1000
        GROUP_NAME: $USER_NAME
        WORK_DIR: develop
    environment:
      - TZ=JST-9
    ports:
      - 8000:8000
    volumes:
      # ソースコードとdevcontainerを一緒に管理する場合は明示的にマウント先を指定
      - ..:$HOME_DIR/develop:cached
      # ホストのsshキーを配置しているディレクトリをコンテナのsshキーの配置ディレクトリとしてマウント
      - ~/.ssh:$HOME_DIR/.ssh
      # ホストの.extensionsディレクトリをマウントしてコンテナのVSCode拡張のダウンロード先に指定
      - .extensions:$HOME_DIR/.vscode-server/extensions
    command: sleep infinity

devcontainer.jsonの設定

devcontainer.jsonは最近すこし書き方が変わりcustomizationsという項目ができました。
今まではextentionsのみだったのですがsettingsをまとめて書くことが可能になり、.vscode/setting.jsonという別ファイルを用意する必要がなくなりました。
devcontainerの設定が1ファイルで済むようになったのは簡潔になってありがたいです。

extensionsの設定は各自で必要な物を入れて頂けたらと思いますが、Zenn EditorPaste Imageはあると執筆に便利だと思います。
linterはmarkdownlintを入れてますが、ちょっと面倒に感じるかもなので欲しい人だけで・・・

devcontainer.json
{
  "name": "Zenn CLI on VSCode",
  "dockerComposeFile": "./compose.yml",
  "service": "zenn_cli_on_nodejs",
  // workspaceを明示的に指定
  "workspaceFolder": "/home/vscode/develop",
  "customizations": {
    "vscode": {
      // VSCodeの設定
      "settings": {
        // 行末技の空白の自動削除を無効
        "files.trimTrailingWhitespace": false,
        // Code Spell Checker
        // チェック対象外の単語をセット
        "cSpell.words": [
          "zenn",
          "stmn",
          "devcontainer",
          "extentions"
        ],
        // Paste Images setting
        // https://github.com/mushanshitiancai/vscode-paste-image
        "pasteImage.basePath": "${projectRoot}",
        "pasteImage.defaultName": "Y-MM-DD-HH-mm-ss",
        "pasteImage.namePrefix": "${currentFileNameWithoutExt}_",
        "pasteImage.insertPattern": "${imageSyntaxPrefix}/${imageFilePath}${imageSyntaxSuffix}",
        "pasteImage.path": "${projectRoot}/images"
      },
      // devcontainer起動時に追加するextentions
      "extensions": [
          "vscodevim.vim",                          // Vim
          "formulahendry.auto-rename-tag",          // Auto Rename Tag
          "mhutchie.git-graph",                     // Git Graph
          "pkief.material-icon-theme",              // Material Icon Theme
          "oderwat.indent-rainbow",                 // indent-rainbow
          "streetsidesoftware.code-spell-checker",  // Code Spell Checker
          "EditorConfig.EditorConfig",              // EditorConfig for VS Code
          "negokaz.zenn-editor",                    // Zenn Editor
          "DavidAnson.vscode-markdownlint",         // markdownlint
          "mushan.vscode-paste-image"               // Paste Image
      ]
    }
  },
  "remoteUser": "vscode",
  // Dev Container Features
  // https://containers.dev/features
  "features": {
    "ghcr.io/devcontainers/features/git:1": {
      "version": "latest"
    }
  }
}

Github連携

こちらに詳しく書いてあるので割愛します

記事作成

初期設定

一番最初だけ以下のコマンドを実行します。

zenn init

新規記事作成

新しい記事を作る時には以下のコマンドを実行します。

zenn new:article

ローカル環境での確認

ローカル環境で確認したい場合は以下のコマンドを実行します。
ローカル環境のURLはhttp://localhost:8000/になります

zenn

まとめ

この記事ももう3回目になります😂
その都度、自分の中での最新で書きやすい状態に変えていってます。
VSCodeで書く時の懸念点だった画像貼り付けもPaste Imageで解消されたのが今回の更新で大きかったです。

また引き続き変更があったら更新します!

株式会社スタメン

Discussion