HackMD

CentOS7 + Apache でサブディレクトリに HackMD を公開する

HackMD 超便利ですよね。PCとスマホで同時に開き、編集がリアルタイムに同期するさまを見たときは感動&興奮しました。

そんな HackMD を職場のオンプレミス環境に導入したときの備忘録です。そのサーバーではすでに Apache Web Server が動いているので、リバースプロキシを使ってサブディレクトリに公開します。

条件

  • CentOS 7.4
  • Apache 2.4
  • 公開URL: https://example.com/hackmd/
  • HackMD データ保存先: MySQL
  • HackMD 認証方法: GitLab OAuth のみ

HackMD インストール

※ 公式の README 通りに進めます

  1. Node.js, npm をインストール: sudo yum install -y nodejs npm
  2. MySQL にて HackMD 用のユーザーおよびデータベースを作成
  3. GitLab にてアプリケーション登録
    • Redirect URI: https://example.com/hackmd/auth/gitlab/callback
    • Scopes: api
  4. ソースをダウンロード: git clone https://github.com/hackmdio/hackmd.git
  5. セットアップスクリプトを実行: bin/setup
  6. 設定ファイル(config.json)を編集
  7. DB設定ファイル(.sequelizerc)を編集
    • url: mysql://USERNAME:PASSWORD@localhost:3306/DBNAME
  8. DBマイグレーション実行: node_modules/.bin/sequelize db:migrate
  9. アセットファイルをビルド: npm run build
    • ちなみにRAM:4GB環境ではスラッシングが発生しOSごと死にました。アイドル時に最低3GBは空いてないとダメかも
    • emitError: EMFILE: too many open files エラーが出てうまくいかない場合は、ulimit -n 4096 にしてファイルオープン上限数を一時的に上げてから実行
    • どうしてもうまくいかない時は、rm -rf public/build/ public/views/build/ でビルド済みファイルを削除すると直るかも
  10. 動作確認: NODE_ENV='production' node app.js
    • "HTTP Server listening at port 8001" と表示されればOK
config.json
{
    "production": {
        "domain": "example.com", //公開ドメイン名
        "urlpath": "hackmd", //公開サブディレクトリ名
        "port": 8001, //ポートを変更
        "usessl": false, //リバプロ〜HackMDはHTTPで通信
        "protocolusessl": true, //URLはhttps://で表記
        "usecdn": false, //ネット接続できない環境なのでCDN使わず
        "imageUploadType": "filesystem", // もちろんクラウドなど使えるはずもないのでローカル
        "allowanonymous": false, //ゲストを不許可
        "email": false, //メールでのサインアップ不許可
        "db": {
            "username": "DB_USERNAME",
            "password": "DB_PASSWORD",
            "database": "DB_DBNAME",
            "host": "localhost",
            "port": "3306",
            "dialect": "mysql"
        },
        "gitlab": {
            "baseURL": "https://gitlab.ipnoc.net",
            "clientID": "GITLAB_APPLICATION_ID",
            "clientSecret": "GITLAB_APPLICATION_SECRET"
        }
    }
}

usessl を false、protocolusessl を true とすることで HackMD サーバーはHTTPで待ち受けるが、URLは https:// で出力されるというリバプロ向けセッティングになります。

Apache リバースプロキシ設定

HackMD はリアルタイム更新を実現するため WebSocket を使います。なので特定URLおよび、Upgrade header もしくは Connection header があったら、WebSocket へアップグレードするようにします。

/etc/httpd/conf/httpd.conf
#
# HackMD configuration
#

# WebSocket upgrade
ProxyPreserveHost On

RewriteEngine On
RewriteCond %{REQUEST_URI} ^/hackmd/socket.io     [NC,OR]
RewriteCond %{HTTP:UPGRADE} ^WebSocket$           [NC,OR]
RewriteCond %{HTTP:CONNECTION} ^Upgrade$          [NC]
RewriteRule .* ws://localhost:8001%{REQUEST_URI}  [P,QSA,L]

# Reverse proxy
ProxyPass /hackmd http://localhost:8001
ProxyPassReverse /hackmd http://localhost:8001

設定が終わったら、sudo apachectl configtest で設定をチェックしましょう。

Systemd で HackMD 自動起動

  1. サービス定義ファイルを /etc/systemd/system に作成
  2. サービス定義を反映: sudo systemctl daemon-reload
  3. サービス起動: sudo systemctl start hackmd
  4. サービス自動起動設定: sudo systemctl enable hackmd
/etc/systemd/system/hackmd.service
[Unit]
Description=HackMD
After=syslog.target network.target

[Service]
Type=simple
Environment=NODE_ENV='production'
ExecStart=/usr/bin/node /path/to/hackmd/app.js
WorkingDirectory=/path/to/hackmd
KillMode=process
Restart=always
User=root
Group=root

[Install]
WantedBy=multi-user.target

最後に Apache を再起動して正常に見られるかチェックします。また可能であればOSごと再起動して自動起動するかもチェックしておくとベターですね。

それでは良いリアルタイム Markdown ライフを!!


バグ情報

2017/11/1 現在、サブディレクトリに公開すると一部のWebフォントが404になってしまう不具合があります。バグレポしたのでそのうち修正してもらえると思いますが、それまでは asset ファイルを検索してURLを手動で修正するなどしてください。