angular
Bluemix
Angular2
angular-cli

Bluemix DevOps で Angular をデプロイする

More than 1 year has passed since last update.

概要

Bluemix DevOps (Open Toolchains) の Delivery PipelineでAngular 2 (TypeScript)をビルドして稼働させるには、次のようにしてビルドするとよい。

Delivery Pipelineの編集

  1. Delivery Pipeline の Buildタスクを編集する。デフォルトでは、BUILDフェーズのBuildタスクである。
  2. ビルダー・タイプ を、デフォルトの「シンプル」から「npm」に変更する
  3. シェル・コマンドのビルド に次のスクリプトを仕込む
#!/bin/bash
export NVM_DIR=/home/pipeline/nvm
export NODE_VERSION=6.10.3
export NVM_VERSION=0.33.2

npm config delete prefix \
  && curl https://raw.githubusercontent.com/creationix/nvm/v${NVM_VERSION}/install.sh | sh \
  && . $NVM_DIR/nvm.sh \
  && nvm install $NODE_VERSION \
  && nvm alias default $NODE_VERSION \
  && nvm use default \
  && node -v \
  && npm -v
npm install -g @angular/cli

npm install
ng build -prod --aot
rm -rf node_modules/

4.ビルドタスクを保存してパイプラインを流すと、Angularソースがビルドされ、成果物の中に dist/ フォルダが作成される。

処理の機序

Delivery Pipelineは、github等のgitレポジトリからコードをcloneしてコンテナ内にもってきます。
デフォルトで構成されている「シンプル」ビルドタスクは、cloneしてもってきたコードを再度まとめて保存し後続フェーズのタスクへ渡すのですが、それでは後続フェーズでは直接 cf push されるため、ng buildでJavaScriptコードを生成させる機会はありません。そのため「シンプル」以外の何らかのビルドタスクにてng buildを行う必要があります。

コンテナの/opt/IBMには各種ビルドツール、ランタイム類が仕込んであります。

drwxr-xr-x 21 root     root  4096 Jun 22 22:42 .
drwxr-xr-x  3 root     root  4096 Jun 22 20:41 ..
lrwxrwxrwx  1 root     root    25 Jun 22 22:38 ant -> /opt/IBM/apache-ant-1.9.2
lrwxrwxrwx  1 root     root    26 Jun 22 22:38 ant.java8 -> /opt/IBM/apache-ant-1.10.1
drwxr-xr-x  6 root     root  4096 Feb  2 19:00 apache-ant-1.10.1
drwxr-xr-x  6 root     root  4096 Jul  8  2013 apache-ant-1.9.2
drwxr-xr-x  6 pipeline  1000 4096 May  2  2014 apache-maven-3.2.1
drwxr-xr-x  3 root     root  4096 Jun 22 20:56 cf
lrwxrwxrwx  1 root     root    20 Jun 22 22:38 gradle -> /opt/IBM/gradle-1.12
drwxr-xr-x  6 root     root  4096 Apr 29  2014 gradle-1.12
lrwxrwxrwx  1 root     root    19 Jun 22 22:38 gradle2 -> /opt/IBM/gradle-2.9
drwxr-xr-x  6 root     root  4096 Nov 17  2015 gradle-2.9
drwxr-xr-x 10 root     root  4096 Mar 13  2015 ibm-java-x86_64-71
drwxr-xr-x 10 root     root  4096 May 18 14:11 ibm-java-x86_64-80
lrwxrwxrwx  1 root     root    14 Jun 22 22:38 java -> /opt/IBM/java7
lrwxrwxrwx  1 root     root    27 Jun 22 22:38 java7 -> /opt/IBM/ibm-java-x86_64-71
lrwxrwxrwx  1 root     root    27 Jun 22 22:38 java8 -> /opt/IBM/ibm-java-x86_64-80
lrwxrwxrwx  1 root     root    27 Jun 22 22:38 maven -> /opt/IBM/apache-maven-3.2.1
lrwxrwxrwx  1 root     root    32 Jun 22 22:38 node -> /opt/IBM/node-v0.10.40-linux-x64
lrwxrwxrwx  1 root     root    32 Jun 22 22:38 node-v0.10 -> /opt/IBM/node-v0.10.40-linux-x64
drwxr-xr-x  7      495   371 4096 Aug 14  2015 node-v0.10.40-linux-x64
lrwxrwxrwx  1 root     root    32 Jun 22 22:38 node-v0.10.48 -> /opt/IBM/node-v0.10.48-linux-x64
drwxr-xr-x  7    50371 50009 4096 Oct 19  2016 node-v0.10.48-linux-x64
lrwxrwxrwx  1 root     root    31 Jun 22 22:38 node-v0.12 -> /opt/IBM/node-v0.12.7-linux-x64
lrwxrwxrwx  1 root     root    32 Jun 22 22:38 node-v0.12.17 -> /opt/IBM/node-v0.12.17-linux-x64
drwxr-xr-x  7    50371 50009 4096 Oct 19  2016 node-v0.12.17-linux-x64
drwxr-xr-x  7      495   371 4096 Aug 14  2015 node-v0.12.7-linux-x64
lrwxrwxrwx  1 root     root    30 Jun 22 22:38 node-v4.2 -> /opt/IBM/node-v4.2.2-linux-x64
drwxr-xr-x  7      495   371 4096 Nov 11  2015 node-v4.2.2-linux-x64
lrwxrwxrwx  1 root     root    30 Jun 22 22:38 node-v4.4.5 -> /opt/IBM/node-v4.4.5-linux-x64
drwxr-xr-x  7    50371 50009 4096 May 26  2016 node-v4.4.5-linux-x64
lrwxrwxrwx  1 root     root    30 Jun 22 22:38 node-v4.6.0 -> /opt/IBM/node-v4.6.0-linux-x64
drwxr-xr-x  7    50371 50009 4096 Sep 28  2016 node-v4.6.0-linux-x64
lrwxrwxrwx  1 root     root    30 Jun 22 22:38 node-v6.2.2 -> /opt/IBM/node-v6.2.2-linux-x64
drwxr-xr-x  7    50371 50009 4096 Jun 20  2016 node-v6.2.2-linux-x64
lrwxrwxrwx  1 root     root    30 Jun 22 22:38 node-v6.7.0 -> /opt/IBM/node-v6.7.0-linux-x64
drwxr-xr-x  7    50371 50009 4096 Sep 28  2016 node-v6.7.0-linux-x64
drwxr-xr-x  4 root     root  4096 Jun 22 22:27 pipeline
drwxr-xr-x  3 root     root  4096 Jun 22 22:38 RTC-SCM-Tools

「npm」ビルドタスクを選ぶことで、上記のツール群を使ったシェルスクリプトを実行できますので、この環境でng buildを動かすことになります。

ただ、@angular/cli は、Node V6.9以上を要求しますが、上記の2017-06時点での ls -al /opt/IBM の出力を見てわかるように、Node環境は要求を満たせません。(V6.7までしか無い)
そのため、@angular/cliをグローバルインストールする以前に、一旦 NVM にて最新のNodeを導入します。

/opt/IBM に Ver. 6.9以上のNode.jsがインストールされていれば、そのNVMの部分はスクリプトに含める必要はなく、直接 npm install -g @angular/cli を実行すればOKです。

実施手順(詳細) 2017-06現在

前提
開発環境に:
* Node.js Ver 6.9以降 が導入されていること
* git ツールが導入されていること
* npm install -g @angular/cli で、Angular-CLIがグローバル導入されていること
* Cloud Foundry CLI (cf コマンド) が導入されていること

あと、有効なBluemixのアカウントを登録済みであること。

やりたいこと
Gitレポジトリ (GitHub または Git repositry on Bluemix) 上に Angular-CLI で生成されたプロジェクト・ファイルを置く。(ただしビルドはしていない)
開発環境から git push origin master で更新されると、自動的にビルドされ、稼働サーバー (http|https)://somewhere.mybluemix.net/ に反映される。

開発環境ローカルにて初期プロジェクト・コードを作成する

  • Angular-CLI でひな形コードを生成 ~ でも ~/dev でもいいですが、親フォルダにて ng new PROJECT_NAME コマンドを実行する。プロジェクト名を ang2 とした場合
ng new ang2
  • 正常なコードが出来たことを確認するには, ng serve にてローカルで実行する。
cd ang2/
ng serve

http://localhost:4200/ で初期コードが稼働します。

Bluemix で DevOpsデリバリー・パイプラインを構成する

新規ツールチェーンの作成

  • http://bluemix.net でBluemixにログインするとダッシュボードが表示されるので、左上のメニューボタンから「サービス - DevOps」を選択する。(なお、事前に地域として米国南部を選択しておく。)
  • 「始めに」ボタンを押すと「ツールチェーンの作成」画面になります。好きなツールチェーンのテンプレートを選べばいいのだが、初めて使う場合には Simple Cloud Foundry ツールチェーン (v1 か v2) を選ぶのが無難。

    ちなみにv1(と表記は無い方)がGitHubを使う。v2(と表記がある方)が GitLab on Bluemixを使う。

  • ツールチェーンの設定画面になるので、「ツールチェーン名」にアプリケーションの名前を入れる。(まだ、作成ボタンは押さない)

  • ツールチェーン名を入れるボックスの下に「ツール統合」セクションがある。Git Repos を選んだ状態では、下に作成するGitレポジトリーの設定を行う項目がある。リポジトリー・タイプ新規作成 を選択する。

  • 作成 ボタンを押す。

デリバリー・パイプラインの構成

デリバリー・パイプラインが、Gitレポジトリー上のコードをクローンし、ビルドし、CloudFoundryにプッシュして稼働させる一連の作業を自動で行う。これをカスタマイズし、Typescriptをコンパイルし、ビルドするように変更する。

  • ツールチェーンの概要画面のパイプラインボタンを押すと、パイプライン画面になる。 BUILDステージの枠とDEPLOYステージの枠の二つが表示されている。
  • BUILDステージ枠の右上隅に歯車アイコンがあるので、これを押して ステージの構成 を選択する。
  • ステージ構成画面で「ジョブ」が表示されており、ビルトインの「Build」ジョブ構成画面になっている。
  • ビルド構成の ビルダー・タイプnpm にする。
  • 現れた シェル・コマンドのビルド フィールドにて、下記コードをペースト。
#!/bin/bash
export NVM_DIR=/home/pipeline/nvm
export NODE_VERSION=6.10.3
export NVM_VERSION=0.33.2

npm config delete prefix \
  && curl https://raw.githubusercontent.com/creationix/nvm/v${NVM_VERSION}/install.sh | sh \
  && . $NVM_DIR/nvm.sh \
  && nvm install $NODE_VERSION \
  && nvm alias default $NODE_VERSION \
  && nvm use default \
  && node -v \
  && npm -v
npm install -g @angular/cli

npm install
ng build -prod --aot
rm -rf node_modules/
  • 保存 ボタンを押す。

Git Repositry on Bluemix を選んだ場合: Git接続

2017/06現在ssh接続しか出来ないので、ssh公開鍵を登録しておくこと。
* ツールチェーンの概要画面の Git ボタンをおすと、GitLabのプロジェクト初期画面に入る。右上のアカウントアイコンから Settings に入り、上部メニューのSSH Keysで公開鍵登録画面になる。

プロジェクトのSSH接続文字列: git@git.ng.bluemix.net:somebody/something.git を控えておくことも重要。

ローカルのプロジェクト・フォルダをGitレポジトリーにpush

下記のコマンドをプロジェクト・フォルダの中で実行する。

git remote add origin git@github.com:somebody/something.git
git add --all
git commit -m 'initial commit'
git push -u origin master

Gitレポジトリーにプッシュされるのでパイプラインが起動し、ひな形コードがCloudFoundryにプッシュされ、サーバーランタイムが作成される。
Bluemix画面の左上メニューボタンで アプリ - ダッシュボード を選択しダッシュボードを開くと、Cloud Foundry アプリのリストに新しい名前・経路のランタイムが出来ている。だが、サーバーランタイムとしは 未実行 になってしまっており、「経路」のリンクから画面表示させてもAngularの初期コード画面は表示されない。
なぜなら、フロントエンドのJavaScriptコードは、ビルドにより生成されたものの、それを提供するためのhttpデーモンが稼働していないから。
なので、初期コードに Node.js Expressのサーバーコードを組み合わせてやり、サーバーランタイムとして正常に稼働できるようにする。

サーバーサイド・コードの組み込み

サーバーサイドのひな形コードをダウンロード

ひな形コード: https://github.com/open-toolchain/node-hello-world
のうち、次の2つのファイルをダウンロードし、ローカルのプロジェクト・フォルダに配置する。

  • manifest.yml
  • app.js

配置先は、ローカルのプロジェクト・フォルダの直下。すなわち、package.jsonやREADME.mdと同じ階層。

サーバーサイドのひな形コードをカスタマイズする。

プロジェクト・フォルダにある、サーバーサイドコードを編集する。

  • manifest.yml のカスタマイズ
    manifest.yml は、CloudFoundryでランタイム・インスタンスを作成する際に参照される設定ファイル。ゆえに、ここでは、サーバー・ランタイムをどのような設定で動かすかを記述する。
    カスタマイズ推奨フィールド:
    - applications → name: Bluemixでのランタイム名
    - applications → memory: Bluemixでのメモリ量設定 (初期コードなら64Mで十分)
    追加推奨フィールド:
    - applications → host: Webアクセスする際のホスト名
    - applications → domain: Webアクセスする際のドメイン名 (mybluemix.net)

  • app.js のカスタマイズ
    app.js は、node.jsにてhttpサーバーを立て稼働させるソースコード。Angularプロジェクトをビルドした成果物をstaticとして見せたいので、ここでは、どのフォルダがstaticフォルダか指定する。

    • 下記の行 (19行目)
    app.use(express.static(__dirname + '/public'));
    

    app.use(express.static(__dirname + '/dist'));
    

    に変更する。

  • package.json のカスタマイズ
    package.json は、npmがnode.jsパッケージをビルドする際に参照される設定ファイル。ゆえに、ここでは、node.jsをどのような設定で動かすかを記述する。

    • package.json を開く前に、dependencies への express, cfenv の追加 下記コマンドを実行する。
    npm install express cfenv --save
    
    • scripts → start の変更 package.json (ll. 5-7) の sciprts.start を変更。
    "scripts": {
        ...
        "start": "node app.js",
        ...
    }
    
    • engines → node の追加 package.json (l. 50) に engines.node を追加。
    "engines": {
        "node": "6.10.x"
    }
    

gitレポジトリへ再push

下記のコマンドをプロジェクト・フォルダの中で実行する。

git add --all
git commit -m 'added server-side code'
git push origin master

pushすると、デリバリー・パイプラインが自動で実行される(自動でビルドとプッシュ)
しばらく待ち、アプリのダッシュボードで該当するランタイムを見ると稼働中になっており、経路欄に表示されるリンクで画面を表示させると、Angualrのひな形コード画面が表示される。