Help us understand the problem. What is going on with this article?

TF+Docker+Emacs+LSP

計算機サーバでうまいこと動かせる自由な環境が欲しい!

大学などでは一般に、ssh アクセスすることで利用可能となる計算機サーバが共有で用いられる傾向があります。
すると、例えばあの 大変迷惑な Tensorflow を用いる際、大凡環境のバージョン問題などに悩まされます。

環境のバージョンをうまいこと調節するには、Dockerを使うことが一般的だったりしますので、こいつの上手い使い方を考える必要があります。

さらに計算機サーバへの ssh 接続は切れる可能性が高いので、 ssh 接続を切ってもプロセスが生きている必要があるわけです。

Solution としては 2 つくらいあります。

  1. Nvidia-Docker + (tmux or gnu-screen) + vim

    一般的な Solution。みんな大好き vim を使って世界平和

  2. Nvidia-Docker + emacsdaemon

    ちょっと変わった Solution。多分あんまりやる人はいない。

TF + Docker + Emacs

要件定義

今回想定する環境は次の通り

  • Nvidia-Docker が install できる環境
    Ubuntu 14 とか CentOS 4 みたいなサポートが切れているOSは知りません。諦めてください。

  • Emacs (Spacemacs)
    今回は Emacs の、 特に Spacemacs を用います。理由は構築速度が早いこと、.spacemacs ファイルで情報が管理されること、python language server を用いることが簡単なためです。

  • remote access
    今回はサーバ上で Emacs を daemon 化しておき、そこへ適宜アタッチすることで ssh 接続が切れてもプロセスを継続する方法を取ります。そして Emacs から Docker 内へアクセスを図ります。

Nvidia-Docker + Docker-compose + tensorflow

長々と書いてありますが、驚くほど簡潔に書くことができます。(/home/meguru/Github は適宜書き換えてください。)

dockerfile
FROM tensorflow/tensorflow:2.0.0-gpu-py3
RUN mkdir /workspace
RUN pip3 install -U pip
RUN pip3 install python-language-server[all] ptvsd yapf
docker-compose.yml
version: '2.3'
services:
    tensorflow-meguru:
        build: .
        volumes:
            - /home/meguru/Github:/workspace
        runtime: nvidia

これら2つのファイルを任意の同じフォルダに入れます。次にそのフォルダ下で container をビルドしておきます。

docker-compose build

これで docker コンテナを作る準備はできました。

Settings for Spacemacs

Spacemacs の設定を書きます。この辺りは個人の趣味の範囲なので、最低限度(?)の設定ファイルを紹介します。必要に応じて書き足してください。

https://github.com/MokkeMeguru/docker-tensorflow-emacs-lsp

ローカル環境 (linux) で実験してみる。

まずは 手元の Linux で試してみます。
emacsclient を CUI で立ち上げているのは、本番環境が ssh 先の計算機サーバであるためです。

emacs --daemon==tensorflow
emacsclient -c -nw --socket-name=="tensorflow"

emacs 上で multi-term を開いて

docker-compose run --rm tensorflow-meguru /bin/bash                                
________                               _______________                
___  __/__________________________________  ____/__  /________      __
__  /  _  _ \_  __ \_  ___/  __ \_  ___/_  /_   __  /_  __ \_ | /| / /
_  /   /  __/  / / /(__  )/ /_/ /  /   _  __/   _  / / /_/ /_ |/ |/ / 
/_/    \___//_/ /_//____/ \____//_/    /_/      /_/  \____/____/|__/


WARNING: You are running this container as root, which can cause new files in
mounted volumes to be created as the root user on your host machine.

To avoid this, run the container by specifying your user's userid:

$ docker run -u $(id -u):$(id -g) args...

0;root@8f44ad9e5967: /root@8f44ad9e5967:/# 

この 8f44ad9e5967 はコンテナIDです。
次に emacs の tramp-mode を使って、docker コンテナ にアクセスします。

emacs-command
C-x C-f /docker:8f44ad9e5967:/workspace

次に、その tramp-buffer の状態で、 eshell を立ち上げましょう。

emacs-command
M-x eshell

すると、eshell の root が @8f44ad9e5967。 つまり、docker コンテナの内部になります。
次に

eshell_in_docker
@8f44ad9e5967 /d/workspace $

ここで、次の関数を評価します。これは docker 内の LSP を Emacs が呼び出すために必要な関数で、 docker内から呼び出すことで同じ関数を使い回すことが出来ます。 (そうでないと lsp-tramp-connection に与える値が面倒なことになります。)

(lsp-register-client
  (make-lsp-client :new-connection (lsp-tramp-connection "pyls")
                   :major-modes '(python-mode)
                   :remote? t
                   :server-id 'pyls-remote))

これで emacs が正しく LSP を認識できるようになりました。

試しに適当な python ファイルを開いてみましょう。

emacs-command
C-x C-f /docker:8f44ad9e5967:/workspace/test.py

LSP モードのプロジェクトルートを設定するように言われますが、とりあえず今回はデフォルトの /workspace で良いでしょう。

ファイルを編集してみましょう。うまくLSPが動いていることがわかると思います。

image.png

あとは通常通り Python を実行するなりしてください。(ref. document: spacemacs の python layer 但し SPC = M-x)

サーバの生存確認

次にクライアントを接続してもホストが生き残ることを確認します。
C-x C-c でクライアントを切断してみましょう。

次に新しいターミナルを開いて、emacsclient -nw -c -socket-name==tensorflow で接続してみましょう。

image.png

復帰して作業を再開できることが確認できました。

emacs-server を切断するには、 M-x kill-emacs で出来ます。

ps -aux | grep emacs
# meguru     936  0.0  0.0   7332  2568 pts/8    S+   07:52   0:00 grep --colour=auto emacs

サーバが落ちていることがわかると思います。

まとめ

  • tmux 以外でもうまいことサーバ-クライアント的な接続ができそう。
  • emacs-lsp は tramp-mode を駆使すると簡単に接続できる。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした