③CoreOSでDockerしてみる(Dockerを使って、Jenkinsをインストール)
Dockerを使って、Jenkinsをインストールしてみます。
■Dockerイメージの取得
公式のDockerイメージが配布されていますので、そちらを利用します。
下記コマンドでイメージを取得します。
docker pull jenkins
■Jenkinsコンテナの起動
下記コマンドでコンテナを起動します。
mkdir /home/core/jenkins_home sudo chown 1000 /home/core/jenkins_home sudo docker run --restart=always --name jenkins -d -p 8080:8080 -v /home/core/jenkins_home:/var/jenkins_home -v /etc/localtime:/etc/localtime:ro -e JAVA_OPTS='-Duser.timezone=Asia/Tokyo -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8' jenkins
・[--restart=always]オプション指定で、OS起動時に自動起動します。
・[--name jenkins]でコンテナ名を指定します。
・[-v]オプション指定で、Dockerコンテナが停止しても、/home/core/jenkins_homeにデータが残ります。(データの永続化)
・[-p 8080:8080]でポート番号を指定する。とりあえずそのまま。
・[-v /etc/localtime:/etc/localtime:ro]でホストと時刻同期する。(同期しないとコンテナ内はUTCになる)
・[-e JAVA_OPTS='-Duser.timezone=Asia/Tokyo 〜]でJenkinsのタイムゾーンとファイルエンコードを指定する。
http://
また、Dockerの仮想コンテナは、パラメータで、コンテナ名、ポート番号、データ永続化フォルダが指定できるので、1サーバ内にJenkinsを複数立ち上げることもできます。
JENKINS_HOME等が競合しないので、便利ですね。
sudo docker run --restart=always --name jenkins1 -d -p 8081:8080 -v /home/core/jenkins_home1:/var/jenkins_home jenkins sudo docker run --restart=always --name jenkins2 -d -p 8082:8080 -v /home/core/jenkins_home2:/var/jenkins_home jenkins sudo docker run --restart=always --name jenkins3 -d -p 8083:8080 -v /home/core/jenkins_home3:/var/jenkins_home jenkins
自宅開発環境のアップデート
自宅開発環境アップデートです。
前回の教訓を生かして、こまめにアップデートします。自分への覚書を残しておきます。
■Ubuntuアップデート
VirtualBox上のEclipse等を詰め込んだ、Ubuntu開発環境をアップデート。
デスクトップ左側のランチャーの1番上の「unity-dash」アイコンをクリック→「update」と入力→「ソフトウェアの更新」で手動アップデートします。
Ubuntu15.04→15.10にアップグレード。特に問題なく終了。
■Hyper-V Serverアップデート
Hyper-V ServerのWindows Updateを実行。特に問題なく終了。
Hyper-V上のCentOS5.11は、yum update でアップデート。特に問題なく終了。
Hyper-V上のJenkinsとJenkinsプラグインもアップデート。特に問題なく終了。
②CoreOSでDockerしてみる(Panamaxをインストール)
Panamaxをインストールしてみます。
■Panamaxとは?
オープンソースのWEBアプリケーションです。
Dockerコンテナの管理やインストールをGUI上で実行できます。
http://panamax.io/
■Panamaxをインストール
下記コマンドで、CoreOSにインストールします。
sudo su curl -O http://download.panamax.io/installer/panamax-latest.tar.gz && mkdir -p /var/panamax && tar -C /var/panamax -zxvf panamax-latest.tar.gz cd /var/panamax ./coreos install --stable
http://
Dockerレポジトリを検索して、公開されているDockerコンテナをインストールすることができます。
例えば、Wordpressをインストールする場合、通常なら、WordpressとMySQLをインストールして設定する必要があります。
Dockerなら、Dockerコンテナをインストールするだけで、Wordpressが使用できます。
(Dockerコンテナに、WordpressとMySQL等の必要なソフトウェアがインストール&設定済み)
また、Panamaxを使えば、WEBブラウザ上から、Dockerコンテナをインストールすることができます。
インストール済みのDockerコンテナを一覧表示できます。
設定変更や削除等ができるみたいですね。
①CoreOSでDockerしてみる(CoreOSのセットアップ)
CoreOSでDockerしてみます。
■CoreOSとは?
Dockerコンテナ実行に特化した、Linuxベースの軽量OSです。
https://coreos.com/
■Dockerとは?
コンテナ型の仮想化オープンソースソフトウェアです。
従来はOS全体を仮想化していましたが、コンテナ型の仮想化は、ソフトウェアアプリケーション単位で仮想化します。
その為、インスタンス生成やインスタンス起動が早く、性能劣化が少ない利点があります。
また、仮想化なので、プラットフォームやハードウェアに依存しません。
例えば、WEBサーバ、WEBアプリケーション、データベース等を1つのコンテナで仮想化しておけば、
開発PC上で作成したコンテナを、そのまま本番環境に配置する事ができます。
https://www.docker.com/
まずは、Hyper-V環境に、CoreOSをセットアップします。
■CoreOSのセットアップ
下記から、「coreos_production_iso_image.iso」をダウンロードします。
・Booting CoreOS from an ISO
https://coreos.com/os/docs/latest/booting-with-iso.html
新規にHyper-V仮想マシンを作成し、ダウンロードしたISOから起動します。
CoreOSが立ち上がるので、ユーザ名Coreのパスワードを設定します。
$ sudo passwd core
インストール後のssh接続用パスワードのハッシュ値を取得します。
$ openssl passwd -1 $【ハッシュ値が表示される】
初期セットアップファイルを作成します。
$ vi cloud-config.yml #cloud-config coreos: update: reboot-strategy: best-effort units: - name: etcd.service command: start - name: fleet.service command: start - name: docker.service command: start - name: timezone.service command: start content: | [Unit] Description=timezone [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/bin/ln -sf ../usr/share/zoneinfo/Japan /etc/localtime users: - name: core passwd: `ハッシュ値` ※「openssl passwd -1」で取得したハッシュ値を設定する groups: - sudo - docker
下記のコマンドでインストールします。
#インストール sudo coreos-install -d /dev/sda -C stable -c cloud-config.yml sudo shutdown -h now #インストールCDを外して、起動する #cloud-config.ymlを保存しておく sudo coreos-cloudinit -from-file=./cloud-config.yml sudo cp cloud-config.yml /var/lib/coreos-install/user_data sudo reboot
⑤Meteorに触ってみる(アカウント管理を追加してみる)
公式サイトのTutorialsを参考に、
前回作成したアプリケーションに、アカウント管理を追加してみます。
meteorには、アカウント管理の部品が標準で用意されています。
部品を利用するだけで、アカウント管理が実装できます。
メール認証、Twitter、Facebook、GoogleAccount認証とかもできるみたいですが、
今回は、シンプルなパスワード認証を追加してみます。
まずは、下記コマンドを実行して、パスワード認証を追加します。
meteor add accounts-ui accounts-password
■simple-todos.html を変更します。
〜 <body> <div class="container"> {{> loginButtons}} {{#if currentUser}} 〜 {{/if}} </div> </body> <template name="task"> <li class="{{#if checked}}checked{{/if}}"> 〜 <span class="text"><strong>{{username}}</strong> - {{text}}</span> </li> </template>
{{> loginButtons}} を追加します。
ログインしている時だけ、表示したい部分を{{#if currentUser}} 〜 {{/if}}で囲みます。
{{username}}は、ログインユーザです。
誰が追加したタスクであるかを表示します。
■simple-todos.js を変更します。
// クライアント側のコード if( Meteor.isClient ){ //-------------------------------------- // アカウント管理 Accounts.ui.config({ passwordSignupFields: "USERNAME_ONLY" }); //-------------------------------------- // <body>内のイベント Template.body.events({ // Form送信(新規タスクの入力) "submit .new-task": function( event ) { 〜 // タスクの追加 Tasks.insert({ text: text, createdAt: new Date(), // 現在時刻 username: Meteor.user().username // ログインユーザ名 }); 〜 } }); }
アカウント管理の宣言を追加します。
また、タスク追加時に、ログインユーザ名も保存するように変更します。
初回アクセス時は、こんな感じです。
「Sign in▼」をクリックすると、アカウント画面が出てきます。
右下にある「Create account」をクリックします。
ユーザ名、パスワードを入力し、「Create account」ボタンを押して、ユーザを作成します。
作成したユーザでログインしてみます。
「Sign in」ボタンを押して、ログインします。
ログインできました。
画面の上部に、ユーザ名が表示されています。
タスクを追加してみます。
タスク名の前に、ユーザ名が表示されています。
■meteorのアップデートについて
今回、meteorをアップデートしたら、作成したアプリが動かなくなってしまいました。
そんな時は、一度、resetすると動くようになります。
meteor update meteor reset meteor
④Meteorに触ってみる(簡単なDB検索/更新のアプリを作成してみる)
公式サイトのTutorialsを参考に、簡単なDB検索/更新のアプリを作成してみます。
まずは、下記コマンドで、アプリを作成します。※「simple-todos」の部分は、任意のアプリ名を指定します
meteor create simple-todos
simple-todosフォルダ配下に下記ファイルが生成されます。
Tutorialsを参考にして、ファイルの中身を変更します。
- simple-todos.html
- simple-todos.js
- simple-todos.css
■simple-todos.html
<head> <title>Todo List</title> </head> <body> <div class="container"> <header> <h1>Todo List</h1> <input type="text" name="taskSearch" placeholder="検索するタスクを入力してください" value="{{taskSearchQuery}}" size="50"/> <form class="new-task"> <input type="text" name="text" placeholder="追加するタスクを入力してください" /> </form> </header> <ul> {{#each tasks}} {{> task}} {{/each}} </ul> </div> </body> <template name="task"> <li class="{{#if checked}}checked{{/if}}"> <button class="delete">×</button> <input type="checkbox" checked="{{checked}}" class="toggle-checked" /> <span class="text">{{text}}</span> </li> </template>
基本は普通のHTMLですが、
動的に表示を変更する箇所のみ、Meteorの記載になっています。
下記は、ループ制御文です。
サーバ側で設定した、tasksコレクションを回して、taskテンプレート形式で出力します。
{{#each tasks}}
{{> task}}
{{/each}}
下記が、taskテンプレートの定義です。
{}で囲まれている部分で、条件式判定や、サーバ側で設定した値を出力しています。
<template name="task"> <li class="{{#if checked}}checked{{/if}}"> <button class="delete">×</button> <input type="checkbox" checked="{{checked}}" class="toggle-checked" /> <span class="text">{{text}}</span> </li> </template>
■simple-todos.js
Tasks = new Mongo.Collection( "tasks" ); // サーバ側のコード if( Meteor.isServer ) { } // クライアント側のコード if( Meteor.isClient ){ //-------------------------------------- // <body>内の自動設定 Template.body.helpers({ tasks: function() { // 検索条件をセッションから取得 var query = Session.get( "taskSearchQuery" ); // ログ出力(ブラウザのコンソールに出力) console.log( "query = " + query ); // 検索条件が指定されている場合 if( query ) { // タスク一覧の取得(部分一致検索) var search = new RegExp( query, "i" ); return Tasks.find( { text: search }, { sort: { createdAt: -1 } } ); } // 検索条件が指定されていない場合 else { // タスク一覧の取得(登録順) return Tasks.find( {}, { sort: { createdAt: -1 } } ); } } }); //-------------------------------------- // <body>内のイベント Template.body.events({ // 検索条件テキストボックスのキーイベント "keyup [name=taskSearch]": function( event, template ) { // 検索条件をセッションに格納 Session.set( "taskSearchQuery" , event.target.value ); }, // Form送信(新規タスクの入力) "submit .new-task": function( event ) { // Form処理時の画面リフレッシュ防止 event.preventDefault(); // 入力値の取得 var text = event.target.text.value; // タスクの追加 Tasks.insert({ text: text, createdAt: new Date() // 現在時刻 }); // 入力エリアをクリア event.target.text.value = ""; } }); //-------------------------------------- // <template name="task">内のイベント Template.task.events({ // 完了チェックボックスのクリックイベント "click .toggle-checked": function() { // タスクの更新 Tasks.update( this._id, { $set: { checked: ! this.checked } } ); }, // 削除ボタンのクリックイベント "click .delete": function() { // タスクの削除 Tasks.remove( this._id ); } }); }
サーバ側のコードとクライアント側のコードを分けて書くことができます。
今回は、クライアント側のコードのみで実装できました。
// サーバ側のコード if( Meteor.isServer ) { 〜 } // クライアント側のコード if( Meteor.isClient ){ 〜 }
各イベントを定義して、その中で、ロジックを記述していきます。
DB操作も含めて、全てJavaScriptでロジックを記述する事ができます。
また、データの自動同期等は、Meteor内部で行われるので、コード上で意識する必要はありません。
数行で実装できてしまうので、とても簡潔なコードになります。
また、DBは、MongoDBなので、CreateTable文を発行してスキーマを作成する必要はありません。
Meteorの作法を覚える必要がありますが、
JavaやJavaScriptが書ける人なら、敷居は高くないと思いました。
■simple-todos.css
/* CSS declarations go here */ body { font-family: sans-serif; background-color: #315481; background-image: linear-gradient(to bottom, #315481, #918e82 100%); background-attachment: fixed; position: absolute; top: 0; bottom: 0; left: 0; right: 0; padding: 0; margin: 0; font-size: 14px; } .container { max-width: 600px; margin: 0 auto; min-height: 100%; background: white; } header { background: #d2edf4; background-image: linear-gradient(to bottom, #d0edf5, #e1e5f0 100%); padding: 20px 15px 15px 15px; position: relative; } #login-buttons { display: block; } h1 { font-size: 1.5em; margin: 0; margin-bottom: 10px; display: inline-block; margin-right: 1em; } form { margin-top: 10px; margin-bottom: -10px; position: relative; } .new-task input { box-sizing: border-box; padding: 10px 0; background: transparent; border: none; width: 100%; padding-right: 80px; font-size: 1em; } .new-task input:focus{ outline: 0; } ul { margin: 0; padding: 0; background: white; } .delete { float: right; font-weight: bold; background: none; font-size: 1em; border: none; position: relative; } li { position: relative; list-style: none; padding: 15px; border-bottom: #eee solid 1px; } li .text { margin-left: 10px; } li.checked { color: #888; } li.checked .text { text-decoration: line-through; } li.private { background: #eee; border-color: #ddd; } header .hide-completed { float: right; } .toggle-private { margin-left: 5px; } @media (max-width: 600px) { li { padding: 12px 15px; } .search { width: 150px; clear: both; } .new-task input { padding-bottom: 5px; } }
公式サイトのTutorialsのままです。
普通のCSSです。
では、アプリを実行してみます。
cd simple-todos meteor
http://localhost:3000に、ブラウザでアクセスしてみます。
Todoの登録、更新、削除ができます。
また、リアルタイムに絞込み検索ができます。
ブラウザを2つ並べて、片方でTodoを新規登録すると、
もう片方のブラウザにも、追加したTodoが表示されます。
ブラウザのリロード無しで、リアルタイムに同期する処理が組み込まれています。
下記コマンドで、クラウド環境へデプロイします。※「hogehogehoge-simple-todos」の部分は、任意のサイト名を指定します
meteor deploy hogehogehoge-simple-todos.meteor.com
http://hogehogehoge-simple-todos.meteor.comに、ブラウザでアクセスして、動かすことができます。
③Meteorに触ってみる(モバイルアプリへの変換)
作成したMeteorアプリをモバイルアプリに変換してみます。
下記コマンドで、iOS、Android用のモバイルアプリに変換できます。
・iOS用 meteor install-sdk ios meteor add-platform ios meteor run ios ・Android用 meteor install-sdk android meteor add-platform android meteor run android
iOSへの変換は、Mac上でのみ実行可能です。
今回は、Ubuntu環境なので、Android用に変換してみます。
Android用のコマンドを実行すると、Androidエミュレータが起動します。
てっきり、Android用アプリに変換されるのかと思ったら違うみたい・・・
やり方間違ってるかもですが。
とりあえず、Androidエミュレータ上でブラウザを起動して、hogehogehoge.meteor.comにアクセスしてみます。
問題なく表示されますね。