LoginSignup
8
8

More than 3 years have passed since last update.

VSCode内の統合ターミナルから、Docker内でアプリを実行するために使った力技

Last updated at Posted at 2018-12-02

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の接続先に、ドライブレターを割り当て、
ファイルシステムとして操作することができます!
sshfsでマウントしたあと.png

dockerイメージを毎回ビルドしないとアプリが実行できない

pythonやruby等のインタプリタ言語を書いているとき、
dockerイメージをビルド→docker runで実行という流れでやってしまっており、
インタプリタ言語の利点を殺してしまっていると感じました。

そこで、

・dockerホストと、コンテナでディスク共有してしまえばいいじゃないか?
 コードの編集はdockerホスト上で、
 コードの実行は、コンテナの中から実行すればいいんじゃないのか?

・開発中のコンテナはアプリを包まずベースとして定義。
 リリース用のコンテナは、別で定義できないかな?

と考えました。

まず、コンテナとdockerホストで、ディスク共有ですが、
-vオプションを使えば簡単にできます。
・・・が、そんな長いコマンドは打ってられないし、覚えてられないので、
makefileにタスクを切っておきます。

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上に定義

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実行

という流れで編集~コード実行までできるようになった。

8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8