IntelliJ + php + fuel + xdebug + vagrant でリモートデバッグする
PHP(Fuelフレームワーク)を触ることがたまにあるのでリモートデバッグの方法をメモする。書いてみたけどPHP自体よくわかってない
vagrant のIP 192.168.33.10
ローカルのIP 192.168.33.1
root@vagrant-ubuntu-trusty-64:~# php -v PHP 5.5.9-1ubuntu4.20 (cli) (built: Oct 3 2016 13:00:37) Copyright (c) 1997-2014 The PHP Group Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies with Zend OPcache v7.0.3, Copyright (c) 1999-2014, by Zend Technologies with Xdebug v2.2.3, Copyright (c) 2002-2013, by Derick Rethans
ディレクトリ構成
blogの下にfuelのコード一式が入っている
vagrantは config.vm.synced_folder "./html/blog", "/data", owner: "www-data", group: "www-data"
をしてるところ以外は特記するところはない。
ゲスト側の設定
php周りのインストール
add-apt-repository ppa:ondrej/php5-5.6 apt-get update apt-get install -y php5 php5-fpm nginx php5-cli php5-xdebug
/etc/nginx/conf.d/php.conf の設定
server { # バーチャルサーバが使用するアドレス、ポートを指定 listen 80 ; # サーバの公開ディレクトリを指定 # /data をローカルと同期してる root /data/public; # インデックスページを指定 index index.php index.html index.htm; # URIごとにどのファイルを配信するか設定 location / { # 指定したパスにファイルが存在するかどうか if (-f $request_filename) { # キャッシュの有効期限を設定 expires 30d; break; } if (!-e $request_filename) { rewrite ^(.*)$ /index.php?q=$1 last; } } location ~ [^/]\.php(/|$) { # PATH_INFO 部の分割に使用する正規表現を指定 # 一つ目 ( .+\.php ) は $fastcgi_script_name の値になり、二つ目 ( /.+ ) は $fastcgi_path_info の値になる fastcgi_split_path_info ^(.+\.php)(/.+)$; if (!-f $document_root$fastcgi_script_name) { return 404; } # FastCGI サーバへリクエストをプロキシする #fastcgi_pass 127.0.0.1:9000; fastcgi_pass unix:/var/run/php5-fpm.sock; # スラッシュで終わる URI の後に追加されるファイル名を設定 # $fastcgi_script_name の値になる fastcgi_index index.php; # 設定ファイルを読み込む include fastcgi_params; # 環境設定を与える fastcgi_param PHP_IDE_CONFIG serverName=192.168.33.10; # FastCGI サーバに渡されるべきパラメータを設定 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info; } }
/etc/php5/fpm/php.ini に追加
[xdebug] zend_extension="/usr/lib/php5/20121212/xdebug.so" xdebug.remote_enable=1 xdebug.remote_host="192.168.33.1" xdebug.remote_handler=dbgp xdebug.remote_port=9001 xdebug.remote_autostart=1 xdebug.idekey="phpdebug" ; annot accept external Xdebug connection: Cannot evaluate expression 'isset($_SERVER['PHP_IDE_CONFIG'])' 対策 xdebug.extended_info=1
Intellijの設定
ディレクトリ構成のところで設定しているIP, /data
の設定以外に、Language & Framework > PHP > Debugのportを9001にする
メニューの Run > Break at first line in PHP scriptにチェックを入れる(デバッグをOFFにしたいときはこれを外す)
メニューの Run > Start Listening For PHP debug Connection を選択する
ブラウザなどで http://192.168.33.10/hello/a
にアクセスするとブレークポイントに止まる。
ちなみに
技術選択とQCDのトレードオフという結論がない話
経緯としては受託開発会社にiOSアプリの開発を依頼したら、Objective-C(Obで作ると言われて「え?Swiftじゃないの?」とエンジニア陣がざわついた。
同僚とオンライン・オフラインで話してたけどこれは難しい。iOSアプリ開発には詳しくないけど、技術的な制約がないのにObjective-Cかとなるのはすごいわかる。Java8の時代にこれからJDK1.4で開発しなさいと言われたらFXで有り金全部溶かした人の顔になる。AppleがこれからSwiftを使ってねと言ってて、これからObjective-Cを書ける人も少なくなってくる。書ける人が少なくなるということは、メンテコストも高くなる。
ただ、相手の会社からしたら、今のメンバー構成でQCDを守るためにはこの選択が最良と判断したのだろう。相手のスキルとかは知らないが、会社にノウハウが溜まってない技術をお客のサービスに納品するというのはリスクが高い。内製開発と受託開発ではそもそもビジネスとしてのゴールが違うのでどちらも間違ってないから余計辛い。(もちろん最初に「この技術」でという制約があれば話が別だけど今回はなかった)
言語ではないが自分もそれまで使ったことがない技術をお客のサービスにいれたことがあった。新しい技術を使わないと問題を解決できない可能性があることを伝え、技術検証も含めてスケジュール・費用はきちんと頂いて仕事をした。
自分は検証とか好きなので自宅で素振りして会社にフィードバックしてたがそれがすぐ使えるかというとそういうわけではない。ビジネス・技術の制限事項や、そもそも今のチームで運用ができるのかというところまで考える必要がある。明日自分が倒れたらコスト・リスクが高くなる技術はみんなを不幸にする。それをなくすためにもスケジュール・費用は必要なものなのだ。それがないときは出してないものは成功するか失敗するかのスタートラインにも立ててないので、出してからその負債を返すか考えたほうがいい気がしてきた。今回は負債が大きすぎるのと、それをやると後辛いんだよなぁ...
ああ、結論がない。
プロダクトマネージャーカンファレンス2016に参加してきた
プロダクトマネージャーカンファレンス 2016 | 10/24~10/25 に参加してきました。カンファレンス内容とかは動画・スライドが上がると思うので、そちらを参考にいただければと思います。(業務連絡:社内向けには多分別途書きます)
2016/10/24(月)25(火) Japan Product Manager Conference 2016 #pmconfjp - Togetterまとめ
謝辞
2日目では1日目のフィードバックを受けて素早い改善がされてました。これがプロダクトマネジメントか仕事の一環としてカンファレンス参加を認めてくれるうちの部長は論理的太っ腹です
— Eiji Hachiya (@hachi_eiji) 2016年10月24日
当日アンケートの結果、机が欲しい、電源が欲しい、毎セッションQAをやって欲しい、との要望が多かったため、対応いたしました。
— pmconf.jp (@pmconfjp) 2016年10月24日
また明日のご来場心よりお待ちしております。#pmconfjp pic.twitter.com/nCyqWNZJZ8
なぜ参加したのか?
エンジニアとしてプロダクトマネージャー(PdM)がどういう思考をもっているのかというのを知って幅を広げたかったというのが一番になります。会社にはPdMはいないのですが、部分部分では思考や考え方、手法が使えてそれをうまくフィードバックできないかなと考えたためです。あとは、色々な記事で拝見する及川さんを見たかったというミーハー心は多分にありましたw
参加目的達成できた?
達成できました。明日からPdMを作るということはできないですが、エンジニアからアプローチしやすい内容もあった(例:最初にKPIを決めてその結果を計測する)ので、そういうところから入っていくのもいいのかもしれないかなと思いました。
ちなみに楽天の齊藤さんに個別で「もし最初のPMを置くとしたらどのようにしたらよいですか?」と質問したら、「すでにPMがいる外部の会社に3〜5年出して修行させる。難しいのであれば本を読んでその通りにやってみる」とおっしゃってました。このセッションは本当によかった…
感想
セッションの話を聞いていると各社でそれぞれやり方は違っていて正解・定石はない。考えたら会社のフェーズ・規模・文化が違うからそれをひとまとめにできないね。と言うのが改めてわかりました。ただ、共通項もあって
- プロダクトに愛情・熱意を持つ
- ユーザ・ものづくりへの理解を示す
- インパクトがでるもの・ユーザにささるものをつくる
- そのためにも目標を立ててその結果を数字として計測する
- 計測した数字をすぐ見れるようにする
- 会社目標、事業目標、個人目標をつなげてきちんと落とし込む
- 決断をする、信頼を得る、ビジョンを言語化して(ドキュメントにおこして)共感してもらう
というところが、各セッション毎にまとめてた自分のメモに書いてました。 会場で話を聞いてるときは文脈があるので伝わるのですが、箇条書きに書くとなんか当たり前の事を言ってる感じになりますね。明日社内向けにコンフルに書くつもりなのですが正確に伝えられるのか心配になってきました。
楽天の齊藤さんのセッションでみんなが共有できるドキュメントが大事でこれがないと必ず手戻りする。まずは理想をドキュメント化する、ヒット性のものを作るのであればPdMはいらない。まずは理想をもってこい。できるできないはその後に考える。というのが一番印象になりました。ドキュメントを各フェーズに書いてるとおっしゃってたので、各フェーズのドキュメントが矛盾なく作られてるのでしょう。
アンカンファレンスで話した
同僚も参加してたので「話してみたら?」とプッシュしてもらい、ちょうど会社で議論真っ最中のサービスコンセプトについて話してきました。弁が立つほうではなく、緊張しやすいので社内外含めてこのような形で話すことがほとんどなく、アンカンファレンスへの参加した記憶がないとおもうので、色々空気読まずにディスカッション形式でやってみたんですがよかったんでしょうか。
あと議論してる途中で時間が来てしまって尻切れトンボみたいになったのにその後のNetworking Partyで捕まえられない方がいてすいませんでした。
enzyme+React
enzymeとは
GitHub - airbnb/enzyme: JavaScript Testing utilities for React
Enzyme is a JavaScript Testing utility for React that makes it easier to assert, manipulate, and traverse your React Components' output.
karmaとかと組み合わせることも可能なのでできることは結構幅広いと思う
書いてみる
utf8_unicode_ci
全角と半角を区別する
create table test ( id int PRIMARY KEY , name varchar(255) COLLATE utf8_unicode_ci, title varchar(255) ); INSERT INTO test(id, name, title) VALUES (1, 'abc', 'abc'),(2, 'ABC', 'ABC'),(3, 'ABC', 'ABC');
結果
mysql> SELECT * from test where name ='abc'; +----+-----------+-----------+ | id | name | title | +----+-----------+-----------+ | 1 | abc | abc | | 2 | ABC | ABC | | 3 | ABC | ABC | +----+-----------+-----------+ 3 rows in set (0.01 sec) mysql> SELECT * from test where title ='abc'; +----+------+-------+ | id | name | title | +----+------+-------+ | 1 | abc | abc | | 2 | ABC | ABC | +----+------+-------+ 2 rows in set (0.01 sec)
ridgepole 0.6.4 メモ
実戦で使えるように素振り
URL
https://github.com/winebarrel/ridgepole
install
gem 'ridgepole' # スキーマにoptions(ストレージエンジンの設定など)をつける gem 'activerecord-mysql-awesome'
エクスポート
すでにテーブルがある場合はexportする.
ridgepole -c config/database.yml --export -o db/schemas/Schemafile \ --dump-with-default-fk-name --split --enable-mysql-awesome
--dump-with-default-fk-name
Railsの場合は外部キーの名前がfk_rails_xxxx
になるのでそれもエクスポートする。applyするときにも必要--split
テーブルごとにスキーマファイルを分ける--enable-mysql-awesome
create文にoptionをつける
ちなみに limit:4
は4バイト
create_table "tasks", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4" do |t| t.integer "project_id", limit: 4, null: false t.string "title", limit: 255, null: false t.text "description", limit: 65535 t.integer "creator_id", limit: 4, null: false t.integer "updater_id", limit: 4, null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false end add_index "tasks", ["project_id"], name: "fk_rails_02e851e3b7", using: :btree
実行
runするときには --dry-run
をはずす
ridgepole -c config/database.yml --apply \ --dry-run -f db/schemas/Schemafile \ --dump-with-default-fk-name
比較
通常の比較
DBとファイルを比較
ridgepole --diff config/database.yml db/schemas/Schemafile \ --dump-with-default-fk-name
ロールバック的な
ridgepole --diff config/database.yml db/schemas/Schemafile \ --reverse \ --dump-with-default-fk-name
AWS CodeDeployで遊んでみた
会社でCodeDeployを使ってたけど、使ったことなかったので遊んでみた。
AWS CodeDeployとは?
https://aws.amazon.com/jp/codedeploy/ より
AWS CodeDeploy は、Amazon EC2 インスタンス、およびオンプレミスで稼働するインスタンスを含む、さまざまなインスタンスへのコードのデプロイを自動化するサービスです。
シンプルなデプロイであればこれで十二分に思える。デプロイを自動化してくれるサービスなのでCI的なことをやりたいのであれば、CodePipelineとかつかうんだろう。
全体図
GitHubにpushするとCircleCIが走るので、テストが通ったらアプリをS3にput後デプロイする。 リージョンは安いからus-east-1
内容
一部でも読んだドキュメント
- What Is AWS CodeDeploy? - AWS CodeDeploy
- Continuous Deployment with AWS CodeDeploy - CircleCI
- ポリシーでのアクセス許可の指定 - Amazon Simple Storage Service
- ユーザーポリシーの例 - Amazon Simple Storage Service
- AppSpec File Example - AWS CodeDeploy
- Install or Reinstall the AWS CodeDeploy Agent - AWS CodeDeploy
IAMユーザとロールの作成
- APIを叩くためのユーザ(ユーザ名:codeDeployUser)を作成する(このユーザのaccess id をCircleCIに管理画面で登録する) Step 1: Provision an IAM User - AWS CodeDeploy をみてロールを適切に付与する。やりたいことにもよるが,最低限S3とCodeDeploy関連があればOK
- CodeDeployで実行するときに必要なデプロイグループ用ロール(ロール名:CodeDeployServiceRole)を作成する
- アクセス許可の管理ポリシーに
AWSCodeDeployRole
を追加する - 信頼されたエンティティを追加する
- アクセス許可の管理ポリシーに
- EC2を作るときに設定するIAMロール(ロール名:CodeDeployDemo-EC2)を作成する
- 管理用ポリシーに
AmazonEC2FullAccess
を追加した(ここは多分ちゃんと絞るべき) - インラインポリシーにポリシー(ポリシー名:ec2-role-permission)を追加
- 信頼関係を追加する
- 管理用ポリシーに
CodeDeployServiceRoleの信頼関係
{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "codedeploy.us-east-1.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
CodeDeployDemo-EC2のインラインポリシー
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:Get*", "s3:List*" ], "Resource": [ "arn:aws:s3:::aws-codedeploy-us-east-1/*" ] } ] }
CodeDeployDemo-EC2の信頼関係
{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
S3バケットの追加
特定者からのみのアクセスをうけるように、バケットポリシーにユーザ codeDeployUserとロールCodeDeployDemo-EC2を追加した。
EC2ユーザ作成
2台以上で作ること。
- インスタンスを作成するときにIAMロールCodeDeployDemo-EC2を忘れない
- CodeDeployのグループの対象インスタンスとなるようにタグを作成するときにキー:Role, 値:WebAppという名前をつけた
- AWS CodeDeploy agentをインストールする
CodeDeployの設定
途中で失敗してもアプリの内容はロールバックしないので注意(正常にデプロイしたものがあればそれはそのまま)
- アプリケーションを新規で作成する
- アプリケーション名:sample-app (ここは circle.ymlで使う)
- デプロイグループ名:SampleAppsGroup (ここは circle.ymlで使う)
- EC2インスタンスタグ:Role:WebApp
- サービスロール ARN:CodeDeployServiceRole を選択した
- デプロイ設定:CodeDeployDefault.OneAtATime ここはお好み
CircleCIの設定
- codeDeployUserのaccess Key IDとSecret Keyを登録する
アプリの設定
circle.yml
にデプロイの設定を記載appspec.yml
にcodeDeployで実行する内容を記載する。(この辺はあまり調べられてない)
circle.ymlの内容の抜粋
deployment: staging: branch: master codedeploy: sample-app: # ここはアプリケーション名と合わせる application_root: / region: us-east-1 deployment_group: SampleAppsGroup # ここはデプロイメントグループと合わせる revision_location: revision_type: S3 s3_location: bucket: バケット名 key_pattern: my-sample-app-{SHORT_COMMIT}-{BUILD_NUM} # キーパターンは適当
appspec.ymlの内容
version: 0.0 os: linux files: - source: / destination: /usr/local/demo-app # アプリ配置先 hooks: BeforeInstall: - location: deploy/before_install.sh # インストールする前の実行するシェル(ELBから外すとか..)
その他
/var/log/aws/codedeploy-agent/codedeploy-agent.log
にログが出るので途中で失敗した時は確認する