SolargraphをDocker環境でこっそり使う
YARDのアノテーションを元にそこそこ便利な説明や補完機能を提供してくれるSolargraphを、Gemfileに含めずこっそり使いてえ……しかもDocker環境で……という人向けの情報。
一番の問題として、gem install solargraph
でsolargraph gemを入れたい訳だけど、揮発しないように工夫が必要になる。
一般的なRuby向けのDockerfileの構成だと、bundle install
で入れるGemだけをdata volumeで永続化していることが多い。よく見るパターンは、vendor/bundle
または /usr/local/bundle
にdata volumeをmountするようdocker-compose.ymlで設定し、加えてこのパスを BUNDLE_PATH
に設定するパターン。これに加えて例えば GEM_HOME
も同じパスに設定しておくと、gem install
でインストールするGemもそこに相乗りできるようになる。今回は雑にそのように設定する。こうすることで、Dockerコンテナ内で gem install solargraph
するとsolargraph gemが永続化されるようになる。この辺の環境変数についてはRubyのDockerイメージでよく使う環境変数で整理しているので良ければ参考にどうぞ。
但し、こっそりやるという主旨なので、Dockerfileやdocker-compose.ymlに GEM_HOME
に関する設定は追加できない。そこで、docker-compose.override.ymlを使う。このファイルは、存在する場合はdocker-composeが勝手に設定をmergeしてくれるというもので、今回のような用途で便利に使える。このファイルは .gitignore で無視するように設定しておく。
# .gitignore
docker-compose.override.yml
solargraphを動かすためのサービスを追加で定義する。
# docker-compose.override.yml
services:
solargraph:
build: .
command: /workspace/vendor/bundle/bin/solargraph socket --host=0.0.0.0 --port=7658
volumes:
- .:/workspace:cached
- bundle:/workspace/vendor/bundle
environment:
GEM_HOME: /workspace/vendor/bundle
ports:
- "7658:7658"
念のため書いておくが、この例ではDockerfileのワーキングディレクトリとして/workspaceというディレクトリを使っていて、かつGemの永続化用のdata volumeを/workspace/vendor/bundleにマウントしている。
上で定義したsolargraphサービスを借りて、まず/workspace/vendor/bundleにsolargraph gemをインストールしてもらう。
docker-compose run --rm solargraph gem install solargraph
そして、solargraphサービスを改めて起動する。
docker-compose up --detach solargraph
バックグラウンド実行されているsolargraphサービスが、solargraph gemのデフォルトである7658番ポートで通信を待ち受けてくれるようになるので、あとはエディタにSolargraphのための拡張を入れて、これに接続させる。
例えばVSCodeだとこの拡張を使う。
VSCodeの場合、設定をsolargraph.externalServerで検索すれば、settings.jsonで好きに設定しろ的なボタンが表示されるので、次のように外部接続する旨と接続先の情報を記入する。
"solargraph.externalServer": {
"host": "localhost",
"port": 7658
},
"solargraph.transport": "external",
これでワークスペースを開き直すとかしてエディタに設定を読み込ませれば、こっそりsolargraphを使う設定は完了。
上手く動いているかどうかは、例えば "foo".
とか入力した状態で補完 (WindowsだとCtrl + Space) を実行してみたり、YARDで型名を注釈した仮引数にマウスオーバーして型名を表示させたりすると分かる。