Vagrant + Hyper-Vでboxを作成する
自分の開発環境はVagrant + Hyper-Vを使っているのですが、 今回ノートPCを新しく購入したこともあって、ゼロからVagrantを起動しようとしたら自分が利用していたboxの公開が終了してました。。。
Vagrant + Hyper-Vは選択肢少ないんですよね。。。
なので今回はbox作成をメモ代わりに残しておこうと思います。
※Windows + Hyper-Vなこともあって色々躓きました。。。
ここに記載する内容は必要最低限にしてあります。
CentOS7のイメージ(iso)からOSを起動する
以下のURLからCentOSのイメージをダウンロードして、CentOSを立ち上げます。
自分は Minimal ISO
の CentOS7 64bit
を利用しました。
hypervkvpdのインストール
hypervkvpd
をインストールしておかないと Waiting for the machine to report its IP address...
と出たところでタイムアウトします。
yum install hypervkvpd systemctl enable hypervkvpd
vagrantユーザーの作成 + 鍵ファイルの設置
passwd # rootのパスワードはvagrantに設定 useradd -g wheel vagrant passwd vagrant # vagrantのパスワードはvagrantに設定
mkdir /home/vagrant/.ssh chmod 700 /home/vagrant/.ssh cd /home/vagrant/.ssh curl -k -L -o authorized_keys 'https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub' chmod 600 /home/vagrant/.ssh/authorized_keys chown -R vagrant:wheel /home/vagrant/.ssh
その他設定
systemctl stop firewalld systemctl disable firewalld vi /etc/selinux/config - SELINUX=enforcing + SELINUX=disabled vi /etc/sysctl.d/disable_ipv6.conf + net.ipv6.conf.all.disable_ipv6 = 1 + net.ipv6.conf.default.disable_ipv6 = 1 vi /etc/sysconfig/network-scripts/ifcfg-eth0 - UUID=XXXXXXXXXXX
sudoの設定
visudo # コメントアウトを外す %wheel ALL=(ALL) NOPASSWD: ALL
キャッシュの削除
完成するbox自体のサイズを小さくするために、キャッシュを削除しておきます。
yum clean all rm ~/.bash_history history -c
OSの終了
shutdown -h now
作成したOSをエクスポートする
Hyper-V マネージャーを開いて、仮想マシンをエクスポートします。
boxの作成(その1)
エクスポートしたフォルダを開くと以下のようになってるはずです。
- Snapshots
- Virtual Hard Disks
- Virtual Machines
上記のうち、 Snapshots
は不要なので削除します。
boxの作成(その2)
エクスポートしたフォルダに metadata.json
を作成する。
最低限以下のような内容になります。
{ "name": "sakutarou/centos7", "provider": "hyperv" }
作成後、以下になります。
- Virtual Hard Disks
- Virtual Machines
- metadata.json
boxの作成(その3)
Virtual Hard Disks
, Virtual Machines
, metadata.json
の3つ選択した状態で、zip圧縮します。
※この時、上階層のフォルダを選択してzip圧縮するではなく、3つを選択して圧縮してください。
zipファイルが完成後、拡張子を .box
に変更してください。
これでbox完成です。
boxとして利用する
以下のコマンドを実行すれば、作成したboxファイルを利用することが出来ます。
vagrant box add --name "sakutarou/centos7" "centos7.box"
もしくは、atlasにアップするなどして利用してください。
その他
これ使ったら、もっと簡単に作成できるかも?
何も試してないけど
などなど
CentOS7でPowerShellを実行する
さて、別にPowerShellを日頃からばりばり使っているわけではありません。
コマンドじゃないとめんどくさいときに、やっとPowerShell出てきてやっと使うレベルです。
あとは、Vagrant立ち上げるとき。。。
なぜ、CentOS7でPoserShellなのかというと、ついにWindowsから「コマンドプロンプト」が消えるらしいです。
そもそも、自分は開発OS自体はWindowsなので、使えた方がいろいろと効率がいいはずです。きっと。。。たぶん。。。
とりあえずトライ!
http://business.newsln.jp/news/201612072350480000.html
インストール
yum install https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.13/powershell-6.0.0_alpha.13-1.el7.centos.x86_64.rpm
実行
powershell
で実行できます。
powershell PowerShell Copyright (C) 2016 Microsoft Corporation. All rights reserved. PS /root>
とりあえずコマンドレットの数を計測してみる
必要かは別として、Windows10 と CentOS7 を比較すると2500くらいは差がありますね。。。
# CentOS 7 Get-Command | measure | select count Count ----- 349
# Windows10 Get-Command | measure | select count Count ----- 2725
参考
CakePHP3のMiddleware導入
この記事は 「Fusic Advent Calendar 2016の6日目」になります
使ってますか?Middleware
これですね。CakePHP3.3から導入されている機能ですね。
http://book.cakephp.org/3.0/ja/controllers/middleware.html
Middlewareって何?
アクセスに対するリクエスト、レスポンスに対して処理を挟むことができます。
処理を挟むといわれると、Controllerには initialize
とかありますけどもっと前に処理を挟むことが可能になります。なります。
また、 PSR-7
に互換しているため、 Packagist
などで公開されている PSR-7
互換のライブラリを利用することが可能となります。
例えば、 Laravelで利用されているMiddlewareをCakePHPで利用するということも可能になります。(Laravelに依存していなければ)
どのタイミングで動くの?
初期だと以下の順番で動作します。
- ErrorHandlerMiddleware(リクエスト処理)
- AssetMiddleware(リクエスト処理)
- RoutingMiddleware(リクエスト処理)
- CakePHP
- RoutingMiddleware(レスポンス処理)
- AssetMiddleware(レスポンス処理)
- ErrorHandlerMiddleware(レスポンス処理)
この図のようにMiddlewareを複数重ねていくイメージで動作します。
どんなところで使えるの?
認証やリクエストオブジェクトやレスポンスオブジェクトの加工、IPアドレス制限などアプリケーションが起動する前の処理などは適した処理だと言えると思います。 レスポンス側だと、ログ出力や実行時間の計測などがいいのでしょうか。
上記の図でもそうですが、 initializeはアプリケーションが起動した後になります。 認証などは起動前の処理でいいものはいろいろとあると思われます。
Middlewareサンプル
1メソッドの中で、リクエスト処理、レスポンス処理を行います。 癖はありますね。
<?php // src/Middleware/TrackingCookieMiddleware.php の中で namespace App\Middleware; class TrackingCookieMiddleware { public function __invoke($request, $response, $next) { // ここでリクエスト処理 $response = $next($request, $response); // ここでレスポンス処理 return $response; } }
Middlewareの使い方
Middlewareの起動などの設定は src/Application.php
に記述します。
必要なMiddlewareを追記してきます。
注意点としては、作成したMiddlewareの __invoke
にrequest, responseオブジェクトが渡ってきますが、
それぞれ、 Zend\Diactoros\ServerRequest
, Zend\Diactoros\Response
になっており、 Cake\Network\Request
, Cake\Network\Response
とは違うことに注意が必要です。
webroot/index.php
の $server->run()
の引数に利用したいオブジェクトを渡すと、Cake\Network\Request
, Cake\Network\Response
など使いたいオブジェクトに切り替えることが可能です。
メンテナンス画面表示用プラグイン作ってみた
Middlewareの勉強がてら、 Maintenanceプラグインを作ってみました。 簡単にメンテナンス画面に切り替えるためのプラグインになります。
CakePHP3のRouteクラス3種
CakePHP3でRouteクラスを利用してるのでしょうか?
Router::scope
などはよく使うのですが、 DashedRoute
、 InflectedRoute
、 RedirectRoute
は頻繁には利用せず毎回調べてるので備忘録程度に残しておきます。
ようはどういうURLでアクセスするかというやつですね。
DashedRoute
特に気にしていない場合は、DashedRouteを利用していると思います。
- アクセスするURL => /my-controller/my-action
- クラス => MyController::myAction
InflectedRoute
CakePHP2までと同じようなURLでアクセスしたい場合はこちらですね
- アクセスするURL => /my_controller/my_action
- クラス => MyController::myAction
RedirectRoute
これは少し毛色の違うRouteです。
特定のURLにアクセスされたら、別ページにRedirectしたい場合があると思います。
RedirectRouteを使えばRouteだけでRedirect可能です。
- アクセスするURL => /my-controller/my-action
- アクセスしたいURL => http://example.com
使い方
routes.php
に記述するだけです。
$routes->connect('/', ['redirect' => 'http://example.com'], ['routeClass' => 'RedirectRoute']);
その他
全体をInflectedRouteにしたい
デフォルトのRouteを指定する
Router::defaultRouteClass(InflectedRoute::class);
laravel/envoyでデプロイしてみる
PHPで作られているシステムをデプロイをするために、Envoyを使ってみました。
CapistranoやRocketeerとかと似たような立ち位置のものですね。
ただこれらよりはずっとシンプルです。
簡単な機能しかないですが、シンプルなものであれば全然問題ないと思う。
Envoyはこれ↓ github.com
これって、Laravelでしか使えないの?
Laravelってついてるけど、Laravelに限らずどこで使えます。
自分はCakePHP3と組み合わせて使ってます。
Envoyインストール
composer require "laravel/envoy=~1.0"
Envoyファイルの作成
# 127.0.0.1がデプロイ先になります。 php vendor/bin/envoy init 127.0.0.1
上記コマンドを実行すると Envoy.blade.php
が作成されます。
こんなやつ
// Envoy.blade.php @servers(['web' => '127.0.0.1']) @task('deploy') cd /var/www/html git pull origin master @endtask
taskからendtaskの間がデプロイ先で実行するスクリプトになります。
複数サーバーにデプロイするような場合は、 @servers(['web1' => '127.0.0.1', 'web2' => '127.0.0.1'])
のように単純に複数並べます。
実行してみる
deploy
が実行するタスク名になります。
以下を実行すると、リモートサーバーにログインして、 /var/www/html
に移動して、 git pull
をする
というものになります。簡単!
php vendor/bin/envoy run deploy
story
storyは、複数のタスクをまとめて実行することができる機能です。
storyに、実行したいタスク名を羅列するだけです。
@servers(['web' => '192.168.1.1']) @story('deploy') git composer @endstory @task('git') git pull origin master @endtask @task('composer') composer install @endtask
setup
デプロイ処理をするときに必ず初期化したいような処理を書いておくのが、 setup
です。
setupは PHPで記述します
タスクでPHPの変数を使いたい場合は、{{}}
で変数を囲みます。
@setup $date = date('Y/m/d'); @endsetup @task('deploy']) echo {{$date}} @endtask
特定のサーバーに限定してタスクを実行したい
特定のサーバーに限定する場合は、タスクのパラメーターとして、 on
にサーバー名を追加します。
@servers(['web1' => '192.168.1.1', 'web2' => '192.168.1.2']) @task('deploy', ['on' => ['web1']]) cd site git pull origin master @endtask
並列処理
基本的に処理は、1サーバーごとに実行されます。
たた、同時に実行して問題がない場合は並列でデプロイしたほうがいいかもしれません。
並列処理も簡単で、並列に処理したいタスクのパラメーターとして、 parallel
をtrueに設定するだけです
@servers(['web1' => '192.168.1.1', 'web2' => '192.168.1.2']) @task('deploy', ['parallel' => true]) cd site git pull origin master @endtask
ifやforを使いたい
使いどころがいまいち思いついてないですが、ループや分岐も使えます。
マニュアルにも載ってないので、必要ないかも?
@servers(['web1' => '192.168.1.1']) @setup $list = ['one', 'two', 'three']; @endsetup @task('deploy') @foreach ($list as $user) @if ($user == 'aaa') echo {{$user}} @endif @endforeach @endtask
終了処理
これもマニュアルに載ってない。。。
タスクごと、デプロイ自体の終了処理も書くことが可能です。
// タスクごとの終了処理 @after echo "タスク完了"; @endafter // デプロイ自体の終了処理 @finished echo "デプロイ終了"; @endfinished
Slack通知
デプロイとは関係ないですが、Slack、Hipchatへの通知機能を持ってます。
setupやafter、finishedで使うといい感じかも
@servers(['web1' => '192.168.1.1']) @finished @slack('Incoming WebHooks URL', '通知先チャンネル', 'デプロイ終わったよー') @endfinished
DockerでAmazonLinuxを動かす
AmazonLinuxがdocker上で簡単に動かせるようになったので試してみました。
環境
- ホストOS・・・CentOS 7
- Docker・・・1.12.3
※CentOS 6上のDocker 1.7で試したら、 image amazonlinux:latest not found
と出て実行できませんでした。
AWS cliのインストール
インストール
yum install python-pip pip install pip --upgrade pip install awscli
aws configure # 以下は環境に合わせて AWS Access Key ID [None]: Access Key AWS Secret Access Key [None]: Secret Key Default region name [None]: ap-northeast-1 Default output format [None]: json
Amazon Linuxイメージ取得
aws ecr get-login --region ap-northeast-1 --registry-ids 137112412989 # ecr get-loginを実行すると以下のようなコマンドが出力されるので、そのまま実行する docker login -u AWS -p {パスワード} -e none https://137112412989.dkr.ecr.ap-northeast-1.amazonaws.com # Docker Imageを取得 docker pull 137112412989.dkr.ecr.ap-northeast-1.amazonaws.com/amazonlinux:latest
Amazon Linuxの起動
ここまで来たら、通常通りコンテナを起動するだけです。
docker run -it 137112412989.dkr.ecr.ap-northeast-1.amazonaws.com/amazonlinux:latest /bin/bash
AmazonLinux起動してみるとわかるのですが、本当に何も入ってないです。
image名の変更
特に必要ないですがimage名を変更したほうが楽かも
docker tag {イメージID} amazonlinux docker rmi 137112412989.dkr.ecr.ap-northeast-1.amazonaws.com/amazonlinux