1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Kabanero を使ったクラウド・ネイティブなアプリ開発(VSCode + Codewind)を体験 - その後

Last updated at Posted at 2020-07-09

2020年7月8日に実施された 初夏のIBM Dojo #9 Kabaneroを使ったクラウド・ネイティブなアプリ開発を体験 ワークショップに参加してきました。講師 @osonoi さんです。

以前に翻訳した Kabanero と、それと関連する Developer Experience にある「VS Code を使用して Kabanero を試す」を体験できるオンラインセッションでした。セッション資料 がわかりやすいので、ぜひ参照してください。

VSCode + codewind の環境、とっても手軽で便利。監視、ビルド、実行など全て Docker 環境で実行され、処理系のインストール無しでさくさく試せる。いろんな言語/環境を試してみたい。

と、Twitter で呟きましたが、すごく参考になったので、ちょっと自分でも中身を確認してみました。自分なりに迷いつつのメモなので、間違えていたり、意味不明だったらスミマセン。

お手軽に開発環境をセットアップ

セッション資料に従い、アプリケーション開発環境をセットアップしてみます。前提となるソフトウェアは以下の2つだけ。

  • Docker : 仮想マシン実行環境
  • VSCode : テキストエディタ

VSCode の 拡張機能 (Extension) で Codewind を探してインストールします。
image.png
新規プロジェクト作成で、Kabanero リポジトリにある Kabanero Node.js Express scaffold template を選択します。
image.png
後は開発環境などが自動でセットアップされます。ビルド環境も実行環境も Docker コンテナ化されているため、Node.js など開発に必要なツールがインストールされていなくても問題ありません。今回のセットアップも Docker 上にコンテナが追加されるだけで、ローカルにインストールされないため、気軽に試すことができます。

アプリを起動すると Node.js Express が動作し、シンプルな Webページが表示されます。
image.png
さあ、後はサンプルコードを修正して、いろいろ試すだけ。ソースコードに修正を保存すれば、ビルドが実施され、すぐにWebページに反映されます。

以上、ここまでの手順の詳細は IBM Dojo の セッション資料 をご参照ください。IBM Developer Dojo のどれかに参加すると、Dojo サポート用の Slack チャネルに招待されるので、そこで質問もできます。

生成された環境を眺めてみる

さてこのまま、環境はブラックボックスとして、Node.js + Express のアプリ開発を開始してもいいのですが… せっかくですから、自動生成された環境を少し眺めてみましょう。

VSCode のワークスペース

まず VSCode のワークスペースを見てみると、以下のような構成になっています。
image.png
ページを表示しているのは routes/index.js ですね。
image.png
表示に利用されている Pug 形式のテンプレート views/index.pug は以下のように非常にシンプルでした。
image.png
これらなのですが、探してみると GitHub の appsody アカウントにある stacks リポジトリ 配下にある /incubator/nodejs-express/templates/scaffold フォルダが元になっているようです。

Docker で動作するコンテナについて

さて、上記の Web ページを表示中、Docker は以下のように3つのコンテナを実行していました。
image.png

最初のコンテナ (イメージは kabanero/nodejs-express:0.4) がアプリを実行している環境のようですので、コンテナに sh アクセスして、動作しているプロセスの状態を見てみます。
image.png
自身の /bin/sh と ps コマンド以外のプロセスは以下のような感じ。

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
default      1  1.8  0.3 105308  7492 pts/0    Ssl+ 09:43   7:34 /.appsody/appsody-controller --mode=run
default     42  0.0  2.2 743756 45576 ?        Ssl  09:43   0:00 npm
default     58  0.2  4.2 1268880 86480 ?       Sl   09:43   1:08 node server.js

ついでに真ん中のコンテナ(イメージは eclipse/codewind-performance-amd64:0.13.0) のプロセスはこちらで、ちょっと何やっているか不明なのですが、実行しているイメージ名から Codewind 本体のような気がします。アプリのビルド前から居ましたし。

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
1000         1  0.0  1.5 741756 30936 ?        Ssl  07:20   0:00 npm
1000        16  0.0  2.5 680096 52572 ?        Sl   07:20   0:00 node server.js

三番目のコンテナ (イメージは eclipse/codewind-pfe-amd64:0.13.0) のプロセスはこちらで、こちらはソースコードの更新をチェックしたり、最初のコンテナを起動してたり、いろいろ働いているようです。

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1  11892  2652 ?        Ss   07:20   0:00 sh -c  /file-watcher/scripts/root-watcher.sh ${HOST_WORKSPACE_DIRECTORY} ${CONTAINER_WORKSPACE_DIRECTORY}
root        33  0.0  2.1 676736 43460 ?        Sl   07:20   0:00 npm
root        61  0.0  0.1  11896  2916 ?        S    07:20   0:00 /bin/bash ./npm-start.sh
root        62  0.0  2.1 676368 44708 ?        Sl   07:20   0:00 npm
root        73  0.0  5.6 972028 115352 ?       Sl   07:20   0:16 node server.js
root       535  0.0  0.1  11896  2760 ?        S    09:43   0:00 /bin/bash /codewind-workspace/.extensions/codewind-appsody-extension/appsody run --name cw-dojoyamacha
root       536  0.0  0.0  23032  1408 ?        S    09:43   0:00 /usr/bin/coreutils --coreutils-prog-shebang=tee /usr/bin/tee -a /codewind-workspace/.logs/dojo-yamacha
root       542  0.0  0.5 116632 11840 ?        Sl   09:43   0:00 /codewind-workspace/.extensions/codewind-appsody-extension/bin/appsody run --name cw-dojoyamachan-df39
root       603  0.0  1.4  45688 29636 ?        Sl   09:43   0:00 docker run --rm -P --name cw-dojoyamachan-df39b4d0-c0eb-11ea-97e7-d775ccf52e96 --network codewind_netw
root       620  0.0  0.0  23032  1320 ?        S    16:11   0:00 /usr/bin/coreutils --coreutils-prog-shebang=tail /usr/bin/tail -q -F -c +0 /codewind-workspace/.logs/d

三番目のコンテナ内の環境変数に、幾つか興味深い値がありましたので、転記します。

CODEWIND_VERSION=0.13.0
CONTAINER_WORKSPACE_DIRECTORY=/codewind-workspace
ENABLE_CODE_COVERAGE=false
HELM_HOME=/root/.helm
HOSTNAME=72958642fbc6
HOST_HOME=C:\Users\z
HOST_MAVEN_OPTS=
HOST_OS=windows
HOST_WORKSPACE_DIRECTORY=C:\codewind-data
IMAGE_BUILD_TIME=20200612-133352
JAVA_HOME=/opt/java/jre
LOG_LEVEL=info
NODE_ENV=production
PATH=/opt/java/jre/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PERFORMANCE_CONTAINER=codewind-performance-amd64:0.13.0

そして気がついていませんでしたが、ローカルPCに C:\codewind-data なんてフォルダが生成されていました… 作業ディレクトリとほぼ同じ構成ですが、.vscode フォルダが無いかわりに空の node_modules フォルダが存在します。
image.png
試しに c:\ ドライブ全体を対象に appsody でファイル名検索した結果がこちら。c:\work\codewind\dojo-yamachan がプロジェクト作成時に自身で指定した作業フォルダです。
image.png
ふーむ、なかなか興味深いですね。

実際の起動プロセス

さて、作成したアプリがどう起動されるか追ってみましょう。実行用コンテナで node server.js とあるので、sh でコンテナの中に入り、server.js ファイルの中でそれっぽい部分を探してみます。

// Register the user's app.
const basePath = __dirname + '/user-app/';

function getEntryPoint() {
    let rawPackage = fs.readFileSync(basePath + 'package.json');
    let package = JSON.parse(rawPackage);
    if (!package.main) {
        console.error("Please define a primary entrypoint of your application by adding 'main: <entrypoint>' to package.json.")
        process.exit(1)
    }
    return package.main;
}

const userApp = require(basePath + getEntryPoint());
app.use('/', userApp({
  server: server,
  app: app,
  log: pino,
}));

まずわかるのが、作成した自身のアプリが /project/user-app/ ディレクトリに配置されているということです。
image.png

そしてこのディレクトリですが、Docker ランタイムにより、さきほど発見したローカルPCの C:\codewind-data 配下のフォルダがマウントされ、永続化されていることがわかります。

image.png

たぶんですが、作業フォルダの内容をビルドした結果 (今回は Node.js で webpack など前処理もないので単にファイルコピーのみ?) がこのローカルPC上のフォルダに配置され、それを実行環境の Docker コンテナの /project/user-app/ ディレクトリにマウントすることで、即時反映できている、という仕組みのようです。

で、さきほどの server.js ファイルのコードにある getEntryPoint() 関数の中を見ると、package.json のなかの main エントリがアプリの本体を指定しているようで、今回だと app.js が指定されています。

package.json
  "main": "app.js",

そしてこの app.js を見ると、これが Express アプリの本体で、これでようやく最初に出てきた routes/index.jsviews/index.pug ファイルに繋がります。

app.js
module.exports = (/*options*/) => {
  // Use options.server to access http.Server. Example of socket.io:
  //     const io = require('socket.io')(options.server)
  const app = require('express')()

  app.set('views', __dirname + "/views");
  app.set('view engine', 'pug');

  app.use('/', require('./routes'));
 
  return app;
};

起動順としては、以下のような感じですかね。

  1. Appsody が用意した実行用コンテナの /project/user-app にローカルPCの c\codewind-data 配下のプロジェクト用フォルダがマウントされる 【Appsody共通】
  2. Appsody が用意した実行用コンテナ内の /project/server.js/project/user-app/package.json ファイルの main エントリを参照する【Appsody Node.js 系共通】
  3. main エントリに指定された /project/user-app/app.js が実行される【Appsody Node.js Express 系共通?】
  4. app.js によって Pug テンプレートエンジンがセットされ、views/index.pug をテンプレートとして route/index.js が表示される。【今回の Stack 固有】

うん、これでやっとスッキリしました。

というわけで

Appsody (VSCode + Codewind) で作成した Node.js + Express サンプルアプリの起動の仕組みをざっくり調べてみました。なかなか良く出来た仕組みだなー、と感心してみたり。

ただ、時間の関係もあり、ソースコードの変更をウォッチしているところ、ビルドしているところ、などはまだ調べていません。また時間を作って、コンパイルする Java などの環境(変化がわかりやすいので)を対象に調べてみたいな、などと思っています。なにかわかったら、メモ公開するかもしれません。

それではまた!

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?