2019年8月21日 追記
この記事の内容は古く、大きく遠回りしています。
読む必要はありません。
VSCodeのリモートデベロップメントを使おう。
https://code.visualstudio.com/docs/remote/remote-overview
ボクはリモートデベロップメント(linux vm)を使っていますが、快適です。
はじめに
Windows上にVMを立て、
VM上のDockerコンテナでアプリケーションを実行させているのですが、
・毎回dockerイメージをビルドするのも面倒くさい。
・Windows上で編集したファイルをLinuxにコピーするのも面倒くさい。
・Windows上のVMだから、F1からのタスクが定義できなくて実行が面倒くさい。
・毎回docker runとか叩きたくない。
といった悩みがありました。
私なりに解決策を考えてみたので、
誰かの役に立てばと思います。
WindowsとLinuxのファイルコピーが面倒くさい。
WindowsとLinuxでファイル共有する方法は沢山あると思います。
WinSCPを使う。
→いちいちSyncされているかを意識しなければいけないのが面倒かと思った
(実際意識する必要はないかもです。あんまり触ってないです。いい加減ですね。。。)
Linux上にSambaを立てちゃう。
→SambaはSambaで、ファイル作成時の権限の設定してあげないといけなかったり、
SambaのユーザとLinuxのユーザーをマッピングしなければいけなかったりと、
複雑化しそうなので手を出したくなくなった。
vagrantとVirtualBoxでファイル共有設定しちゃう。
→guest additionが入らないことがよくあったので、避けた
色々理由をつけて避けましたが、
私が選んだのはコレでした。
dokany+win-sshfs
https://github.com/masaeedu/win-sshfs
https://github.com/dokan-dev/dokany
※Dokanのバージョンは。1.1.0.2000にすること。
GUI版もあるので、その場合は、他の型のQiitaの記事を参考に、インストールするといいと思います。
なんとSSHの接続先に、ドライブレターを割り当て、
ファイルシステムとして操作することができます!
dockerイメージを毎回ビルドしないとアプリが実行できない
pythonやruby等のインタプリタ言語を書いているとき、
dockerイメージをビルド→docker runで実行という流れでやってしまっており、
インタプリタ言語の利点を殺してしまっていると感じました。
そこで、
・dockerホストと、コンテナでディスク共有してしまえばいいじゃないか?
コードの編集はdockerホスト上で、
コードの実行は、コンテナの中から実行すればいいんじゃないのか?
・開発中のコンテナはアプリを包まずベースとして定義。
リリース用のコンテナは、別で定義できないかな?
と考えました。
まず、コンテナとdockerホストで、ディスク共有ですが、
-vオプションを使えば簡単にできます。
・・・が、そんな長いコマンドは打ってられないし、覚えてられないので、
makefileにタスクを切っておきます。
RELEASE_CONTAINER := hogehoge
BASE_CONTAINER := $(RELEASE_CONTAINER)-base
APP_ROOT := /app
CONTAINER_APP_ROOT := /app
MAIN_APPLICATION := entrypoint.sh
# ベースのコンテナは、頻繁に利用、更新されると思ったので、
# 先頭に定義して「make」だけで実行するようにした。
commit: var
docker image build -t $(BASE_CONTAINER) \
--target base \
.
# 試行錯誤中、コンテナの中に入りたいときは沢山ある。
# なんで「make shell」でコンテナの中に入るタスクを定義
shell: var
docker container run -ti \
--network host \
-v $(ROOT_DIR)$(APP_ROOT):$(CONTAINER_APP_ROOT) \
--rm $(BASE_CONTAINER) \
/bin/sh
# いちいち /app/entorypoint.shをコンテナの中で実行するのは面倒なので、
# これも「make run」でタスクをていぎ
run: var
docker container run -ti \
--network host \
-v $(ROOT_DIR)$(APP_ROOT):$(CONTAINER_APP_ROOT) \
--rm $(BASE_CONTAINER) \
/app/entrypoint.sh
# リリース用のコンテナを作る定義
release: var
docker image build -t $(RELEASE_CONTAINER) \
--target release \
.
var:
$(eval ROOT_DIR := $(shell pwd))
次に、ベースのコンテナと、リリース用のコンテナを分けるため、
マルチステージビルドをDockerfile上に定義
FROM alpine:latest as base
RUN apk add python3
RUN pip3 install --upgrade pip
COPY /app/requirements.txt /requirements.txt
RUN pip3 install -r /requirements.txt
FROM base as release
COPY /app /app
ENTRYPOINT ["/app/entrypoint.sh"]
マルチステージビルドと、dockerの-vオプション、
makefileを駆使すれば、それなりに使いやすくなり、
以下のような形でコンテナへのアクセスが楽になった。
[root@localhost hogehoge]# make shell
docker container run -ti \
--network host \
-v /home/hoge_user/develop/hogehoge/app:/app \
--rm hogehoge-base \
/bin/sh
/ #
VSCodeからmakefileで定義したタスクが実行できない。
SSH接続先のmakefileをいい感じに実行できる。
そんな楽なものは見つけることができなかった。
なので、VSCodeの拡張を導入し、
統合ターミナル上ですぐにSSHログインできるようにし、
makeを単純に実行することにした。
そこで利用したのが、
SSHExtention
https://github.com/VitalyKondratiev/vscode-sshextension
こんな感じでコンフィグを書いておくと、F1から簡単にSSHログインできる。
"sshextension.serverList": [
{
"name": "hogehogevm",
"host": "192.168.56.100",
"port": 22,
"username": "root",
"privateKey": "C:\\Users\\hoge_user\\develop\\keys\\id_rsa",
"path": "/develop"
},
],
"sshextension.openProjectCatalog": true
終わりに
ここまでやったことによって
①VSCodeからSSHFSでマウントした先をディレクトリとして開く
②コードを編集
③F1からSSHでVM接続へのショートカットを呼び出し→SSHでVMにログイン
④VMの中でmake run実行
という流れで編集~コード実行までできるようになった。