Ubuntu Weekly Recipe

第709回CodiMDでMarkdownをウェブブラウザーから共同編集する

ミーティングで議論した内容は、議事録として残すことが重要です。人間は1時間ぐらい経つと半分ぐらいしか思い出せないという話もあります。言った・言わないの話をする時間を考えたら、最初から議事録をとっておくのが重要でしょう。今回はオンラインミーティングの議事録に有用な、ウェブブラウザーでMarkdownフォーマットのテキストを共同編集できるCodiMDを紹介します。

HackMDのFLOSS版である「CodiMD」

CodiMDはMarkdownをウェブブラウザーで編集し、共有できるサービスであるHackMDのFLOSS版という位置づけです。HackMDから一部の機能を削っただけで、基本的な機能は一通り揃っています。具体的にはアカウント認証・ゲストアクセス・HTML/PDFやPandoc経由の出力、スライドページ化などです。

いわゆる「ホワイトボード」だと第622回のSpacedeckでホワイトボードを共有するで紹介したSpacedeckが存在します。ただこれはどちらかというと図形を描く用途のツールで、ディスカッションで互いの考えを模式化する際には有用ではあるものの、議事録を書くには向きません。

議事録をとるとなると、誰かがテキストエディターの画面を共有して書くという方法もあるものの、議事録係が発言するとなるといろいろ大変です。もちろん「議事録係」専任として発言はしない人をミーティングに参加させるのは、本末転倒でしょう[1]⁠。

そこで出てくるのが「共同編集する仕組み」です[2]⁠。誰でも編集できるようにしておくことで、発言していない人でもフォローできるようになります。もちろん「誰が書く」かで「お見合い」になってしまう可能性もありますので、ある程度事前に決めごとが必要になるものの、一言伝えるだけで作業を引き渡せるのは非常に重要です。

共同編集ツールと言えばEtherpadが古くから有名です。もともとはJava/Scalaで作られたプロプライエタリなソフトウェアだったのですがその後FLOSSとなります。さらにNode.jsで再実装されたetherpad-liteが登場し、現在ではそちらが主流となりJava版のEtherpadは開発終了しました[3]⁠。

etherpad-liteとCodiMDに共同編集という観点で基本的な違いはありません。一番大きな違いは、etherpad-liteがMicrosoft Word/LibreOffice WriterっぽいUIなのに対して、CodiMDはMarkdownをメインに据えているところでしょうか。CodiMDのほうはMarkdown記法で記述した上でライブレンダリングによる表示もサポートしています。ちなみにCodiMDはehterpad-liteからのマイグレーションもサポートしています。

CodiMDのデプロイ

CodiMDはNode.jsベースのソフトウェアです。よってそのデプロイにはNode.js/npmに加えて、PostgreSQLもしくはMySQLのデータベースが必要になります。とは言うものの、本連載でここ最近紹介しているサービスの例に漏れず、CodiMDもDockerイメージが用意されており、それを使ってデプロイするのが一番簡単です。

まずはいつものように、Dockerとdocker-composeをインストールしておきます。次のようにUbuntuリポジトリのパッケージでも良いですし、Docker本家のバイナリでもかまいません。

$ sudo apt install -y docker.io docker-compose

次に本家が用意しているdocker-compose.ymlを用意しましょう。

$ sudo mkdir /etc/codimd && cd $_
$ sudo editor docker-compose.yml

今回は次のように記述します。

version: "3"
  services:
    database:
      image: postgres:11.6-alpine
      environment:
        - POSTGRES_USER=codimd
        - POSTGRES_PASSWORD=パスワード
        - POSTGRES_DB=codimd
      volumes:
        - "database-data:/var/lib/postgresql/data"
      restart: always
    codimd:
      image: hackmdio/hackmd:2.4.1-cjk
      environment:
        - CMD_DB_URL=postgres://codimd:パスワード@database/codimd
        - CMD_USECDN=false
      depends_on:
        - database
      ports:
        - "3000:3000"
      volumes:
        - upload-data:/home/hackmd/app/public/uploads
      restart: always
  volumes:
    database-data: {}
    upload-data: {}

最低限変更すべきなのは次の3箇所です。

  • databaseサービスのPostgreSQLのデータベースのパスワード
  • codimdサービスのCMD_DB_URLに含まれるパスワード(上と同じにする)
  • codimdサービスのimagehackmdio/hackmd:2.4.1からhackmdio/hackmd:2.4.1-cjkに変更する

パスワードはここではベタに書いてしまっていますが、.envファイルを用意してそこから環境変数として参照させても良いでしょう。

imageをcjk付きにすると、Source Han Sans(源ノ角)フォント付きのコンテナイメージが使われます。これは日本語文書をPDFに生成したいときに必要になります。PDF生成等を使わないのであれば、cjk無しのイメージのほうがサイズを小さくできます。

あとはインスタンスを立ち上げるだけです。

$ sudo docker-compose up -d

http://localhost:3000にアクセスすると、ログイン画面が表示されます。

図1 ⁠サインイン」ボタンでログインする。⁠履歴」で過去にアクセスした文書のリストを参照できる
図1
図2 メールアドレスとパスワードを入力し「登録」を選択するとアカウントが作成される
図2
図3 ログインが完了すると新規文書が作成される
図3

初期設定では誰でもアカウントを作れるようになっています。また、アカウントには「管理者」という概念は存在しないようです。

文書の編集画面は一般的なMarkdownエディターです。左にMarkdownを入力し、右にレンダリング結果が表示されます。

図4 適当なMarkdownファイルを入力した状態
図4
図5 画面上部の「?」をクリックするとチートシートが表示される
図5

もちろん日本語も問題なく使えます。画面左上にある「ペンアイコン」を選択すると編集画面のみの表示になり、⁠眼のアイコン」を選択するとレンダリング結果のみの表示になります。

文書を他の人も編集・閲覧できるようにするためには、このページのURLを共有してください。右上の「ONLINE」が編集・閲覧中の人数で、クリックするとメンバーリストが表示されます。メンバーリストの左にある色が、編集画面の各行の色に反映され、最後に誰が編集したかがわかるようになるというわけです。また編集時はカーソルの場所が他の人に見えるようになっています。

同じく右上の「公開する」を選択すると、公開用のURLが生成されます。ログインしていないユーザーに閲覧権限だけ与えたい場合は、このURLを渡すことになります。ただし既存の設定では、誰でも編集画面へと遷移できる状態になっているため、編集時のヘッダーが表示されるかどうかの違いぐらいしかありません。

SSL/TLSの利用も可能ではありますが、Nginxなどのリバースプロキシー側で実施することを推奨しています。公式ドキュメントにApache、Nginx、HAProxyの設定例が載っていますので、これをそのまま使うと良いでしょう。

バックアップやリカバリーは、docker-compose.ymlに書かれている2個のボリュームをバックアップ取れば事足ります。ただしdatabase-dataのほうはpg_dumpコマンドでダンプファイルを作ったほうが安全です。

設定の変更方法

CodiMDには様々な設定が用意されています。これはいずれもdocker-compose.ymlから環境変数として渡すことで変更可能です。具体的には次の部分が該当します。

  codimd:
      image: hackmdio/hackmd:2.4.1-cjk
      environment:
        - CMD_DB_URL=postgres://codimd:パスワード@database/codimd
        - CMD_USECDN=false

つまりenvironmentsCMD_FOO=barのような形で指定していくわけです。変更したら一度インスタンスを止めて、再度起動してください。

$ sudo docker-compose down
$ sudo docker-compose up -d

これで新しい設定が反映された状態になります。データは残っていますので安心してください。ただし一旦ログアウトされますので、必要に応じて再度ログインしてください。ここからは主だった設定内容について見ていきましょう。なお、今回はバージョン2.4.1を想定しています。

アカウント作成機能とゲストアクセスの制限

CodiMDは何も設定しないと次のような状態になります。

  • 誰でもアカウントを作成可能
  • ページのURLを知っている人はアカウントがなくても誰でも閲覧可能
  • アカウントを持っている人のみページの新規作成可
  • アカウントがない場合は編集は不可

つまりフルオープンに近い状態です。ただしURL自体はランダムな文字列なので、⁠誰でもページが閲覧できるわけではない」という点は安心して大丈夫でしょう。気になるようならリバースプロキシー側で認証を付けるという手もあります。

まずアカウントの作成については、CMD_ALLOW_EMAIL_REGISTERfalseにしておくことで無効化できます。この場合、次のコマンドを使えば手動でアカウント作成可能です。

$ cd /etc/codimd/
$ sudo docker-compose exec codimd ls ./bin/manage_users
You did not specify either --add or --del or --reset!

Command-line utility to create users for email-signin.
Usage: bin/manage_users [--pass password] (--add | --del) user-email
  Options:
    --add       Add user with the specified user-email
    --del       Delete user with specified user-email
    --reset     Reset user password with specified user-email
    --pass      Use password from cmdline rather than prompting

$ sudo docker-compose exec codimd ls ./bin/manage_users --add メールアドレス

しかしながらCodiMDのローカルアカウント機能はかなり貧弱です。管理者が動作確認の用途に使うと思っておいたほうが良さそうです。その代わりSAMLLDAPOAuth関連には一通り対応しているため、本格的な運用を行うならそちらを使いましょう。

アカウントの作成を制限できたら、アクセスできるのは「ページの作成者」「正規の手順でアカウントを持っていてURLを知っている人」「ゲストでURLを知っている人」のいずれかに限定できます。ここでゲストの権限を管理するのがページごとのパーミッションと全体の設定です。

まず、CodiMDはページごとにパーミッションを設定できます。これはページの作成者のみが変更でき、次のような選択肢が存在します。

Freely
ゲストも含めて誰でも閲覧・編集が可能
Editable
ゲストは閲覧可・編集不可、それ以外は閲覧・編集が可能
Limited
ゲストは閲覧・編集共に不可、それ以外は閲覧・編集が可能
Locked
ページ作成者のみが編集可、それ以外はゲストを含めて閲覧のみ可
Protected
ページ作成者のみが編集可、アカウント持ちは閲覧可・編集不可、ゲストは閲覧・編集ともに不可
Private
ページ作成者のみが閲覧・編集可、それ以外は閲覧・編集共に不可
図6 ページごとのパーミッションの選択
図6

特に何も指定しなければ「Editable」が選択されます。つまりゲストもURLさえわかれば、閲覧は可能です。編集画面も表示はできますが、編集しようとするとログインを要求されます。

パーミッションの初期値やゲストの扱いは、次の環境変数で変更します。

  • CMD_ALLOW_ANONYMOUStrueにするとゲストはページの新規制限も含めて無制限に許可されます。初期値はfalseになっています。
  • CMD_ALLOW_ANONYMOUS_VIEWSfalseにするとEditableやLockedが選択できなくなります。初期値はtrueになっています。
  • CMD_ALLOW_ANONYMOUS_EDITSfalseにするとFreelyが選択できなくなります。初期値はtrueになっています。
  • CMD_DEFAULT_PERMISSION:ページ作成時のパーミッションです。初期値はeditableになっています。

ゲストアクセスを完全無効化したいのなら、次のように設定すると良いでしょう。

CMD_ALLOW_ANONYMOUS_VIEWS=false
CMD_ALLOW_ANONYMOUS_EDITS=false
CMD_DEFAULT_PERMISSION=limited

特殊な書式とエクスポート機能

CodiMDは単なるMarkdownだけでなく、動画や図版の埋め込み・生成を含めた拡張書式もサポートしています。

図7 埋め込み系は{%名前 URL}のように書く
図7

図8 生成系はFenced code blockにプロパティを追加する

図8

特にMermaidVega-Liteのように拡張性が高く、⁠うまく使えば)見栄えの良い書式にも対応しているので、きれいな図をたくさん用意したい場合に役に立つことでしょう。

内容が固まったらURL以外の方法で共有する方法として、次のようなフォーマットへエクスポート可能です。

  • Markdown
  • HTML
  • PDF
  • Pandoc経由でのEPUB3やLaTeX、reStructuredText、ODT(OpenDocument Text⁠⁠、Wordなど
図9 作成したMarkdownは様々なフォーマットにエクスポートできる
図9

PDFとPandocはベータ扱いです。おそらくもっとも便利なのがPDFでしょう。内部ではmarkdown-pdfを使っているらしく、日本語の生成にも対応しています。ただし埋め込まれるフォントが部分的にSource Han SansのTC(繁体字)やSC(簡体字)になるらしく、句読点を含めて一部おかしくなる点には注意が必要です。うまく回避する方法が見つかっていないため、気になるようならMarkdownをダウンロードして自分で生成してしまったほうが楽かもしれません。

その他の設定項目

ドメイン名やサービスURL、パスが決まっているならCMD_DOMAIN⁠、CMD_URL_PATHあたりを設定しておきましょう。

社内で限定して運用するなら、CMD_AUTO_VERSION_CHECKfalseにしたほうがいいかもしれません。これは現在実行中のバージョンとIPアドレスを、CodiMDの開発者に通知してしまうからです。

設定項目自体はそこまで多くないため、一通り読んでおくとあとあと楽かもしれません。

CodiMDは「Markdownに慣れている」メンバー間で、リアルタイムに共同編集したい場合には非常に便利なツールです。自分でデプロイ・運用が面倒な場合も、より高機能なHackMDが、いくつかの条件付きで無料で利用できますし、有償のプランもあります。まずはこちらの無料プランで試してみて、フィーリングが合うようなら選択肢にいれてみてもいいのではないでしょうか。

おすすめ記事

記事・ニュース一覧