NTTドコモの石川です。社会人2年目になりました。
最近いろいろなことがあって在宅での勤務や、在宅での研究を推奨する企業や学校が増えましたね。
そんな中で僕も在宅勤務をすることがとても増えて、この際なのでリモートで行う開発の環境構築に力を入れていたら、結構良い感じのができたのでよかったら参考にしてみてください。
まるでローカルで作業をしているような感覚で、リモートサーバ上のDockerコンテナ内での作業をすることができるようになります。
今回の環境構築の前提として、
- ローカルPCはMac
- MacへのVSCodeはインストール済み
- リモートサーバにはDockerが導入済み
とします。
また、DockerDesktopを使った方法もありますが、こちらは少し面倒に思ったので今回はそれを使用しない方法をご紹介します。
出来上がった環境
ローカルPCのVSCodeの画面上だけでリモートサーバに立てたDockerコンテナ内の下記の操作ができるようになります。
- 実行環境の整備
- プログラムファイルの編集
- プログラムの実行
- JupyterNotebookの実行
これに加えてCyberduckを使ったコンテナ内のファイルの編集、転送やGPUを使用した計算も可能です。
コンテナの作成
それでは早速環境の作り方です。
まずはリモートサーバ上にSSH接続できるようにしておきましょう。
ここではRSA鍵認証による接続を使います。(※RSA鍵認証の設定の仕方については一般的なもので大丈夫なのでここでは省略)
リモートサーバへSSH接続でログインしたら、リモートサーバ上の任意の場所に下記のようなdockerfileを作成します。ファイル名は「dockerfile」です。
# ベースのイメージ。下記のものは僕のGPU環境に合わせているので各自適切なものを選んでください。
# GPUを使わない人は"ubuntu:18.04"などで大丈夫です。
FROM nvidia/cuda:10.1-cudnn7-runtime-ubuntu18.04
# 作った人の名前です。
LABEL maintainer "dcm_ishikawa"
# 必要最低限のものやSSH接続などに必要となるものを取り込みます。
RUN apt-get update --fix-missing && \
apt-get install -y apt-utils && \
apt-get install -y software-properties-common vim curl unzip htop openssh-server wget procps
# SSH接続のための設定です。
# "password"のところを任意のパスワードへ変更してください。
# いろいろ設定しているのは、Ubuntu18.04でrootユーザでSSH接続するための作業です。
RUN mkdir /var/run/sshd
RUN echo 'root:password' | chpasswd
RUN echo '\nPermitRootLogin yes' >> /etc/ssh/sshd_config
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
# GPUの設定です。GPUを使用しない場合は不要です。
ENV NVIDIA_VISIBLE_DEVICES all
ENV NVIDIA_DRIVER_CAPABILITIES utility,compute
# SSH接続のための設定です。
ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile
# runしたときにSSH接続を始められるようにします。
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
dockerfileの作成が終わったら、dockerfile
を保存したのと同じ場所で下記コマンドを実行しましょう。
docker image build . -t [imagename]
docker run --name [containername] -d -p 10000:22 -p 18888:8888 [imagename]
※nvidia-dockerを使用する人はdocker
のところをnvidia-docker
へ変えてください。
[imagename]
は任意のイメージ名、[containername]
は任意のコンテナ名です。
-p 10000:22
について、10000はリモートサーバにポートを通すときの任意のポート番号。
-p 18888:8888
について、18888はブラウザ上でJupyterNotebookでアクセスするときのポート番号。JupyterNotebookを使用しない場合、またはVSCode上でJuoyterNotebookを使用するときは不要。
リモートサーバで下記コマンドを打ってコンテナ内に入れたら、コンテナの作成は成功です。
ssh root@127.0.0.1 -p 10000
接続の際にパスワードを求められますが、そのパスワードはdockerfile
へ記述したものになります。
接続ができたらコンテナ内に~/.ssh/authorized_keys
を作成し、ローカルPCで作成した公開鍵を記入しましょう。
これができたらexit
でコンテナへのSSH接続を切断しましょう。
また、同様にリモートサーバ内でも~/.ssh/authorized_keys
を作成し、ローカルPCで作成した公開鍵を記入しましょう。
これでリモートサーバでの作業はこれで完了です。リモートサーバへのSSH接続も切断しましょう。
VSCodeの設定
それではローカルPCの設定です。
ローカルPCの~/.ssh/config
へリモートサーバ、リモートサーバ上のコンテナへのSSHに関する下記の記述を書き足します。(このファイルがそもそもない場合は作成します)
Host Server01 # 任意の接続名
HostName xxx.xxx.xxx.xxx # リモートサーバのアドレス
User username # リモートサーバにおけるユーザ名
IdentityFile ~/.ssh/id_rsa # 作成した秘密鍵のパス
Host Server01:Container # 任意の接続名
HostName 127.0.0.1
User root
IdentityFile ~/.ssh/id_rsa # 同上
Port 10000 # コンテナをrunしたときに通したポート番号
ProxyCommand ssh -W %h:%p Server01 # Server01のところは1行目のものと同一に
次に下記のURLから、VSCodeのSSH接続のための拡張機能をインストールします。
VSCodeを起動し、左側のリモート接続的なボタンを押します。
その中の一覧に~/.ssh/config
で指定したコンテナの接続名が現れると思います。(ここではServer01:Container
)
その接続名の右の方にあるフォルダマークをクリックすると、いよいよコンテナ内へのVSCodeでの接続が完了します。
現れた画面で「フォルダーを開く」と言うボタンがありますので、それを押すことでコンテナ内の任意の場所が選択できるので、ワークスペースに追加したい場所を選択しましょう。
お疲れ様でした。これで環境構築は完了です。
下記は使い方になります。ご参考ください。
コマンドの実行
画像の順にボタンをクリックすることで、コンテナ上のコマンドラインを開くことができます。
Pythonのインストール
コンテナのコマンドラインからwgetを用いてAnacondaやMinicondaなどのインストーラをダウンロードし、インストールしましょう。
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh
rm Miniconda3-latest-Linux-x86_64.sh
source ~/.bashrc
JupyterNotebookの起動
まずコンテナのワークスペースでPythonの拡張機能をインストールします。(※場合によっては初期状態ではインストールされていません!)
インストール : https://marketplace.visualstudio.com/items?itemName=ms-python.python
次にコンテナ内のコマンドラインでJupyterをインストールします。
pip install jupyter
Jupyterを起動するコマンドを打ちます。
VSCode上で使う場合
command
+shift
+P
でコマンドパレットを開き、
>Create New Blank Jupyter Notebook
を入力しEnter
。
最近のアップデートによってこれだけで起動できるようになりました。すごい。
ブラウザ上で使う場合
下記コマンドをコンテナ内のコマンドラインで実行します。
jupyter notebook --port 8888 --ip=0.0.0.0 --allow-root
jupyter notebook
コマンドのみではできないことがあるので注意。
aliasで設定しておくと便利だと思います。
コマンドラインに下記のように返ってくるのでxxxxxxxxxxxxxxx
の部分をコピーしておきます。
http://127.0.0.1:8000/?token=xxxxxxxxxxxxxxx
ローカルのブラウザを開き、アドレスバーに
[リモートサーバのIPアドレス]:18888
を入力しEnter
。(18888
はdocker run時に指定したポート番号。)
この後パスワードまたはトークンを求められるので、先ほどコピーしておいたxxxxxxxxxxxxxxx
を入力するとJupyterNotebookをブラウザで使用できるようになります。
Cyberduckでの接続
新規接続
から下記の設定で接続できるようになります。
- SFTPを選択
- サーバ:リモートサーバのアドレス
- ポート:runのときに指定したポート番号(ここでは10000)
- ユーザ名:root
- パスワードを入力するか、もしくはSSH秘密鍵を選択
接続がうまくいかないとき
VSCodeやコマンドラインでのSSH接続がうまくいかないときは、大抵は何度かコンテナを作り直したりして、known_hosts
で衝突が起こっていることが考えられます。
ローカルPCの~/.ssh/known_hosts
で該当の記述の部分を削除する、もしくは名前を変更して~/.ssh/known_hosts.old
などとすることで、解決することがあります。
終わりに
いかがでしたでしょうか。
この記事が少しでもみなさんの在宅勤務や研究などの手助けになれば幸いです。
これからもみんなで力を合わせて、頑張りましょう!