sakutarou’s blog

とりあえずWeb系技術をゆるく書いていく

WSL上でDockerが動いた!けどまだつらい?

ネットでWSL上でDockerが動くようになってたと見かけたのでTryしてみました。
結果はまだつらそうかな?

WSLのインストール + Ubuntuのインストール

ネットで調べたらいっぱい出てくるのでそちらで

注意点

  • Ubuntu自体を管理者で実行する(右クリック => 管理者として実行)

Dockerのインストール

これでインストール + 起動が出来たのですが、Docker CEでは動作しませんでした。
インストールされるバージョンも Docker version 1.13.1, build 092cba3 とちょっと古めです。

sudo apt update
sudo apt upgrade

# docker.ioを利用する
sudo apt install docker.io

sudo cgroupfs-mount

sudo usermod -aG docker $USER

sudo service docker start

hello-world

docker run hello-world

f:id:sakutarou:20180715024846p:plain

Apacheを動かしてみる

これも普通に動作します

docker run -p 8080:80 --name apache httpd:2.4.33-alpine

コンテナに入りたい。。。

コンテナにエラーが出て入れませんでした。
解決策あるのかな。。。

docker exec apache /bin/bash
rpc error: code = 13 desc = invalid header field value "oci runtime error: exec failed: container_linux.go:247: starting container process caused \"could not create session key: function not implemented\"\n"

まだ難しい?

安定運用可能になるまでには、もう少し時間がかかりそう?
普通に使えるようになると便利そうなんだけどな。。。

巷で噂のデータ可視化ツールMetabaseを試してみた

最近データの可視化にRedashを利用してます。
Redashより素晴らしいとの噂の Metabase を試してみました。

www.metabase.com

以下を参考にさせて頂きました

OSSのデータ可視化ツール「Metabase」が超使いやすい - Qiita
MetabaseがRedashの苦労を吹き飛ばすくらい熱い - Qiita

Metabaseのいいところ

  • Dashboardの自由度が高い
    • グラフのサイズを自由に変更できる
    • 特定データの内訳をドリルダウンすることが出来る
  • SQLを書かなくても、結構自由にグラフを作れる

とりあえずMetabase起動!

docker run -d -p 3000:3000 --name metabase metabase/metabase

とりあえず上記コマンドで起動可能です。
ただMetabaseにアクセスできるようになるには少し時間がかかります。
docker logs -f metabase で起動完了までしばらく待ちましょう。

Metabase Initialization COMPLETE と表示されれば準備完了です。
site URL が表示されるのでブラウザからアクセスして初期設定しましょう。

自分は下記のエラーが発生しました

metabase Error parsing liquibase.yaml

上記エラーが出た場合は、メモリ不足の可能性があるそうです。
ホストに割り当ててるメモリ量を 1G => 2Gに変更しました。

グラフを作る

Question がグラフ用のデータ作成になります。
[New Question]-[Custom or Native query] をクリックしてデータを作成します。

Dashboardを作る

作ったQuestionを適当に配置して、サイズを自由に決めます
サイズをドラッグで自由に決めれるのがいい!
Redashの場合、横幅が広いモニターだとどうしても、横長で間抜けなグラフが配置されていたのが、 Metabase だと自分の思った通りに配置できるのがいい!

f:id:sakutarou:20180108204605p:plain

作成したDashboardを共有する

初期状態ではDashboardを共有することは出来ません。
Admin Panel から共有設定を有効にする必要があります。

  1. [メニュー]-[Admin Panel]-[Public Sharing]で共有設定許可画面まで進む
  2. Enableにする
  3. Dashboardに行き、Sharing設定する

とりあえず、乗り換えてみよう

まだ少ししか触ってないけど乗り換えてみる!
かっこいい!
ただし、Metabaseのバージョンは 0.27.2 なので要注意!!!

f:id:sakutarou:20180108205930p:plain

要調査

現状コンテナを落とすとMetabaseのデータが消える
データの保存先を調べて、ホストをマウントするなどの検討が必要

GitHub Appsを作ってみたら色々詰まって苦労した。。。

開発合宿でGitHub Appsでアプリを初めて作ってみました
自分が詰まったところを中心に情報を残します

fusic.co.jp

GitHub 連携

GitHubで何かしら連携をやろうと考えた場合以下が考えられます。
上3つは今でも使ったことがあるのですが、GitHub Appsは全く使ったことがありませんでした。
なので今回は GitHub Apps にトライしてみました。

GitHub Appsって何?

特徴としては以下

  • organization単位にインストールすることが可能(個人アカウントで作成することも可能)
  • 特定のリポジトリのみにアクセス権を与えることが可能
  • 詳細な権限設定とWebhookが利用可能
  • JWT認証をすることでAPIコールも可能
  • 一般公開も可能(自分の組織に限定することも可能)

要は、OAuthなど今まで個人に紐づいていたものが組織に紐づいて、且つ WebhookとAPIコールもくっついてくるすっごい便利なものだよと

GitHub Appsの登録

とりあえず最初にAppsの登録をします。
ここで Webhookや権限などを設定しておきます。

Creating a GitHub App | GitHub Developer Guide

JWT認証

APIをコールする為には、JWT認証を行いトークンを取得する必要があります。
ここでがっつり詰まってしまいました。

どうすればいいの

このURLに対して証明書と一緒にPOSTを送信するだけ!
すっごい簡単!
※ :installation_id は自身のものに修正する
https://api.github.com/installations/:installation_id/access_tokens

つまりポイントその1

そもそも installation_id って何!

WebHookリクエストの一部としてくっついてきます。

  # 上省略
  "installation": {
    "id": XXXXXX
  }

これでPOSTが送信できる!

つまりポイントその2

何をPOSTすればいいのか分からない!
以下をPOSTします。

- "iat": 現在日時タイムスタンプ,
- "exp": 発行するJWTの失効日時タイムスタンプ(最大10分), 
- "iss": GitHub App's identifier

GitHub App's identifier 何これ!
こいつが何かわかりませんでした。。。

作成したGitHub AppsのGeneralページにある AboutのIDGitHub App's identifier になります。
Private key も 同じ場所にあります。

つまりポイント3

ヘッダーは以下を指定する

"Authorization": "Bearer 作成したJWT",
"Accept": "application/vnd.github.machine-man-preview+json"

何つくったの?

GitHub + Amazon API Gateway + AWS Lambda *+ PythonGitHubラベル管理アプリを作りました。
ソースコードを整理できたら公開するかも。。。

参考URL

https://qiita.com/icoxfog417/items/fe411b94b8e7ae229e3e

Authentication options for GitHub Apps | GitHub Developer Guide

Travis CIみたいなGitHub連携アプリってどうやって作るんだ

GitHubで使われている Travis CI のような連携アプリを作りたい!
と思いついたので、まずはステータスを切り替えれるようにするところまで進んでみる。
※セキュリティとか置いておいて、まずは必要最低限まで

f:id:sakutarou:20170219234506p:plain

アプリケーション作成

以下の順番でアプリケーション作成画面まで進む。
[GitHub] - [Settings] - [OAuth applications] - [Register a new application]

進めたらアプリケーション作成

f:id:sakutarou:20170219235408p:plain

f:id:sakutarou:20170219235422p:plain

callback URL Client ID Client Secret をメモっておきます。

OAuth認証

まず、GitHubにアクセス
Client ID には先ほどメモっておいたものを使います。

https://github.com/login/oauth/authorize?client_id={Client ID}&scope=repo:status

認証を行うと callback URL に設定したURLに code が戻ってきます。

http://example.com/oauths/callback?code={コード}

次に コード を利用して、アクセストークンを取得します。
取得した、 コード Client ID Client Secret を利用します。

https://github.com/login/oauth/access_token?code={コード}&client_id={Client ID}&client_secret={Client Secret}

GitHubステータス変更

以下のAPIを実行して対象プルリクエストの head => sha を取得する

https://api.github.com/repos/:owner/:repo/pulls

- :owner => GitHubユーザー
- :repo => リポジトリ

以下のURLに対して必要な情報をPOSTします。

https://api.github.com/repos/:owner/:repo/statuses/:sha

- :owner => githubユーザー
- :repo => リポジトリ名
- :sha => pullsで取得した sha

POST値

JSONで以下の内容をPOSTする

  • state : pending, success, error, failure のいづれか
  • target_url : 詳細ページへのリンク
  • description : 説明
  • context : 見出し

その他

アクセストークンの使い方

Authorization: token {アクセストークン} の形でヘッダーに組み込む

  or

?access_token={アクセストークン} の形でGET値のパラメーター組み込む

UserAgentが必須である

ヘッダーにユーザーエージェントとして、 アプリ名 を指定する

とりあえず、ここまで
次はhook処理

Vagrant + Hyper-Vでboxを作成する

自分の開発環境はVagrant + Hyper-Vを使っているのですが、 今回ノートPCを新しく購入したこともあって、ゼロからVagrantを起動しようとしたら自分が利用していたboxの公開が終了してました。。。

Vagrant + Hyper-Vは選択肢少ないんですよね。。。

なので今回はbox作成をメモ代わりに残しておこうと思います。
Windows + Hyper-Vなこともあって色々躓きました。。。

ここに記載する内容は必要最低限にしてあります。

CentOS7のイメージ(iso)からOSを起動する

以下のURLからCentOSのイメージをダウンロードして、CentOSを立ち上げます。
自分は Minimal ISOCentOS7 64bit を利用しました。

Download CentOS

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 マネージャーを開いて、仮想マシンをエクスポートします。

f:id:sakutarou:20170213000715p:plain

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にアップするなどして利用してください。

その他

これ使ったら、もっと簡単に作成できるかも?
何も試してないけど

github.com

などなど

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

参考

github.com

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に依存していなければ)

どのタイミングで動くの?

初期だと以下の順番で動作します。

  1. ErrorHandlerMiddleware(リクエスト処理)
  2. AssetMiddleware(リクエスト処理)
  3. RoutingMiddleware(リクエスト処理)
  4. CakePHP
  5. RoutingMiddleware(レスポンス処理)
  6. AssetMiddleware(レスポンス処理)
  7. ErrorHandlerMiddleware(レスポンス処理)

この図のようにMiddlewareを複数重ねていくイメージで動作します。

Untitled (3).png

どんなところで使えるの?

認証やリクエストオブジェクトやレスポンスオブジェクトの加工、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プラグインを作ってみました。 簡単にメンテナンス画面に切り替えるためのプラグインになります。

https://github.com/fusic/maintenance/