bz0のにっき

quick and dirty prototype

Dockerに入門した

Dockerに入門してみました。

Dockerのメリット / デメリット

docker
https://thinkit.co.jp/story/2015/08/05/6284

メリット:
・「ハードウェアの調達やメンテナンス、ITシステムのチューニング」などの隠蔽
・複数のOS環境とアプリケーション環境をパッケージ化し、インターネットを通じて
 世界中の開発者やIT部門のメンバーが作った環境をすぐに利用できる

デメリット:
・ホストOSがLinuxの場合には、その上で稼働するコンテナもLinuxに限定される
・シンプルなコマンドラインを提供していますが、GUIを提供する管理ツール類はまだ発展途上
・Dockerだけでシステムがすべて完結することはなく、効率化のための周辺ソフトウェアの
 整備をある程度視野に入れる必要がある
CentOSは6がサポートされないらしい(CentOS7)

開発におけるDocker導入のメリット
https://qiita.com/minodisk/items/5ffd20588b995523756f

CentOS7.1をVagrantに入れて試す

下記を参考にインストール
https://qiita.com/tsuuuuu_san/items/dfd1d6ac55244d64d076

# cat /etc/redhat-release
CentOS Linux release 7.1.1503 (Core)

# docker --version
Docker version 17.11.0-ce, build 1caf76c

# docker-compose --version
docker-compose version 1.14.0, build c7bdf9e

Docker関連用語

コンテナ
・1つのサーバーの上で、複数のサーバー環境をそれぞれ分離して実行する
・コンテナは、1つのOSの中を複数の区画に分離する技術であり、1つのカーネルの上で複数のOS環境が動く

Docker Hub
イメージが多数登録されているサービス

Docker Engine
1つのコマンドで既存のイメージの検索やダウンロードができる

dockerコマンド

コンテナIDを調べる

docker ps -a

使ったコンテナを消す

docker rm -f コンテナID

コンテナの一括削除

docker rm -f $(docker ps -a -q)

注意:
コンテナは永続化されないので、コンテナを削除すると
コンテナ内で作成したファイルも消えます。

ポート指定して起動

docker run -p 80:80 --name php -d php:5.6-apache

phpコンテナ内に入る

docker exec -ti php bash

※「exit」でコンテナ内から出ます。

docker run -p 80:80 -v /var/www/html:/var/www/html --name php -d php:5.6-apache

コロンの左側がホスト側、右側がコンテナ側のディレクトリです。

docker run --name mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
  • eオプションは環境変数を設定するもので、rootのパスワードをpassに設定
docker exec -ti mysql bash

mysqlのコンテナ内に入る

docker-compose

dockerでの環境構築の手順を自動化します。

作業手順:
1.Dockerfileを作成
2.docker-compose.ymlで起動の流れを指定
使うコンテナやパラメータなどを記述した手順書

参考:
https://qiita.com/TsutomuNakamura/items/7e90e5efb36601c5bc8a

depends_on
https://qiita.com/sivertigo/items/9baa73d922a68788402b

php7.1 / apache / mysql5.7

参考:
Docker Hubのオフィシャルイメージを使ったLAMP環境(Apache+PHP+MySQL)構築 - Qiita
DockerでPHP7.0×Apacheの環境を構築する(更新: 2017/6/27) - Qiita



docker-composeで、環境構築してみる。
※試しにやってみたレベルなので、ちゃんと出来ているか分からないです。

下記設置して、コマンドを実行すると自動で環境構築してくれます。

docker-compose up -d

docker-compose

docker-compose.yml

version: '2'
services:
  mysql:
    build: ./mysql
    environment:
      MYSQL_ROOT_PASSWORD: 123456
    volumes:
      - db:/var/lib/mysql
  php:
    build: ./php
    ports:
      - '80:80'
    volumes:
      - /var/www/html:/var/www/html
    depends_on:
      - mysql
volumes:
  db:

mysql

mysql/Dockerfile

FROM mysql:5.7
COPY ./my.cnf /etc/mysql/conf.d/

mysql/my.cnf

[mysqld]
character-set-server=utf8

php

php/Dockerfile

FROM php:7.1-apache
RUN docker-php-ext-install pdo_mysql mysqli mbstring

php/php.ini

[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"

勉強方針

勉強方針

・地道にやっていくしかないので焦らない / でも1日1日着実に進める

・ツールの使い方等は時間経過で、新しいツールがどんどん出てくるので使えない情報になっていきがちだが
 考え方については陳腐化しづらい。

・勉強したことを普段の作業にフィードバックして改善していく
 ・結局業務にフィードバックできない場合、使わなくて勉強しなくなる→忘れる→無駄ではないがコスパ悪い
 ・レガシーな環境でやらざるを得ない場合、他の会社での仕事に適応することが出来なくなっていくので
  個人サービスを作る/ 勉強時間を確保していけるようにする(残業をなるべくしないように業務改善)

・webエンジニアとして、どこでも生きていけるだけの技術力をつけたい
 →選択肢を増やしたい(辛いときに転職できる/自信がつく)
 ・言語やツールの開発・運用経験の広さは、転職時に役に立つはず。
 ・今やっている業務外の技術は深堀りしていくより浅く広くやっていき対応できる範囲を広げる。
  また、客観的に「やっているな」と思われるようにインプットだけでなくアウトプットしていくようにする。

・得意分野を作っていきたい(自分の強みはどこ?に答えられる)

・勉強してても、自分の技術レベルが上がっているか分からなくなる / 全然できなくて辛くなるので
 何かしら進んでいっている実感が持てるようにするのもメンタルの安定によいのではと思う。

 ・1ヶ月単位に目標を立てて、勉強する
 ・1週ごとに小目標を立て、週末進捗の見直しをする
 ・目指したい年収で募集かけてる会社でどの程度のレベルが求められているかを把握する
  その会社で自分が仕事できるビジョンが明確に見えるか / 技術ブログで書かれている内容を自分が理解できるか?

・劣等感で辛くならない
 いまさらこんな事やっているのか?とか思わずにやる。気にしない。

・何を勉強するかの優先順位

 ・業務へのフィードバックが優先=今の仕事で結果を出すことが最優先
  それで金を稼げているわけではあるので。今の仕事で結果が出せれば、次の仕事に結びつきます。
 ・そこから派生して、出来ることを増やしていく。
 ・業務をしていく上での課題の洗い出し→改善策をいくつか→試しに勉強

目的

・「転職できる」という自信を持てるようになる
・カバーできる範囲を広げてできる仕事を増やす / 自分の得意領域を作る

設計

インプット

・よくある設計パターン / アンチパターンの把握
 

アウトプット

・ブログ記事
・要件→設計・プログラミングに落とし込むときに考えるポイントを明確にする

Linuxサーバ構築/運用

インプット

・様々なLinuxOS系でコマンドの違いを把握する
・コマンド
・よく行うことがある作業を見直し(もっとよくできないか)
・運用上おきた問題点の改善
 

アウトプット

・ブログ記事
・業務へのフィードバック

プログラミング

インプット

・主にPHP
デザインパターン
フレームワークを活用した開発 / フレームワークの仕組みの理解 / ライブラリのコードリーディング
Ruby,Go,Node / 構築・運用経験を作る
・CI / テストを習慣化する→リリース後の不具合を減らす / 機能変更後、不具合にすぐ気付ける

アウトプット

・ブログ記事
OSS(既存のライブラリ等へのプルリクエスト / 自分でライブラリ作る)
・勉強会でのLT?
・業務へのフィードバック

DB

インプット

MySQLの機能を知る(主に業務で触るので)
MariaDB / postgreSQL / Redis 構築・運用経験を作る
・DB設計 / モデリング
 

アウトプット

・ブログ記事
・要件→設計・プログラミングに落とし込むときに考えるポイントを明確にする
・レビュワーを立てて、都度チェックしてもらって改善していく形を作りたい
・業務へのフィードバック

フロントエンド

インプット

・今後よく利用しそうなツールでの構築/運用
 ・typescript
 ・vue / react
 ・es6

・よく行うことがある作業を見直し(もっとよくできないか)
・運用上おきた問題点の改善
 

アウトプット

・ブログ記事
・要件→設計・プログラミングに落とし込むときに考えるポイントを明確にする
・レビュワーを立てて、都度チェックしてもらって改善していく形を作りたい

個人サービス

・サービス作ってリリース(月1本目標)
・金稼げるサービスを作る

kintone APIのライブラリを作りました

kintone APIのレコード操作を簡単に行えるライブラリを作ってみました。
github.com

kintone APIの公式ドキュメントは下記です。
kintone REST APIの共通仕様 – cybozu developer network

リクエストボディ

APIリクエストする際、Content-Typeに「application/json」を利用しているが
kintoneではRFC4627の形式に準拠する為、json_encodeで単純に変換すると
「不正なJSON文字列です」とエラーになってしまう事がありました。

配列ではなくオブジェクトとしてJSON変換されてしまう為です。

2016/01/10 の定期メンテナンスにおけるkintone API更新情報 Part1 – cybozu developer network


連想配列でなく、連番の場合は「array_values()」で配列であることを明確にすることで
この点は防ぐことができました。
PHPの配列を安全にJSONシリアライズする - Qiita

kintoneAPI開発での便利ツール

下記使うと楽だった。

HTTP Client Tool for kintone
https://developer.cybozu.io/hc/ja/articles/115001506986

よく分からないところがあれば、コミュニティで過去の質問を漁ってみたり
自分で質問するのもいいかも。

課題

CI

テストコードも、ローカルでのチェック用に申し訳程度に書いたけど
CIに対応しようと思ったら、アプリ生成→テストデータ追加→テスト→アプリ削除という手順を踏む必要がありそうで
非常にめんどくさそう。

ローカルでテスト実施できるだけでも、ちょっと直したときに
影響の有無をチェックできるので、テストコード書くと後が非常に楽だなと実感できたのはよかった。

CIでのAPIトークンってどこに置けばよいか

APIトークンとかbase64化したアカウントをどこに置くのがいいのか。
githubで公開したくないので、どういう風にすべきなんだろう。

調べてたら、下記方法がありそうです。

リクエストをモックに置き換えることで、APIトークンをコード内に含めない
https://github.com/hissy/kintone-php/blob/master/tests/ObjectTest.php

設定ファイル(APIトークン等)を入れたディレクトリをgit管理に含めない。
CIを行う際は、bitbucketなどのプライベートリポジトリを使って行うようにすべきなのだろうなと思います。
https://github.com/wataridori/chatwork-sdk/tree/master/tests

GASをES6で書く

Google Apps Scriptで、チャットワークAPIを使い
メッセージを送信するjsをES6で書いてみたいと思います。

ES6で書くための準備

やること

・GASのアップロードの自動化
・ES6→GAS用のJSに変換する

GASのアップロードの自動化

・初期化 / ダウンロード
 gapps init スクリプトID
 ※確認箇所:プロジェクトのプロパティ > スクリプト ID

・アップロード
 gapps upload

 ・アップロードできるが、ダウンロードははじめの「gapps init」のときのみ

・注意:

 ・アップロードできるのは Standalone Script のみでスプレッドシート
  ドキュメントなどにひもづいた Container-bound Script には対応していない
  (スプレッドシートから作成したGASで行うとgas initは出来るがアップロードで失敗する)

C:\node\gas>gapps upload
Pushing back up to Google Drive...
An error occured while running upload command: File not found: xxxxxx
Upload failed.

ES6→GAS用のJSに変換する

Google Apps Script を ES2015 で開発|株式会社CAリワード

上記ブログに記述されていたpackage.jsonを利用して「npm install」します。

{
  "devDependencies": {
    "browserify": "^13.1.1",
    "chai": "^3.5.0",
    "gasify": "^0.1.0",
    "mocha": "^3.2.0",
    "babel": "^6.5.2",
    "babel-core": "^6.7.4",
    "babel-preset-es2015": "^6.6.0",
    "babel-register": "^6.7.2",
    "gulp": "^3.9.1",
    "gulp-babel": "^6.1.2",
    "gulp-exec": "^2.1.2",
    "gulp-load-plugins": "^1.2.0",
    "gulp-plumber": "^1.1.0",
    "gulp-mocha": "^2.2.0",
    "babelify": "^5.0.5",
    "vinyl-source-stream": "^1.1.0"
  },
  "babel": {
    "presets": ["es2015"]
  }
}

「npm install」したらコードを書いて、下記コマンドでGAS用のソースに変換します。

browserify -t babelify -p gasify index.js -o gas.js


今回、chatworkAPIでメッセージを送信するプログラムを書きました。


chatworkAPIでメッセージを送信します。(ES6 / Google Apps Script)

twitterのトップでコンソールから自動ツイートする

chrome拡張で簡単に定型文をツイートさせようと思っていて、そのツイート部分の実装です。
twitterのホーム画面で、下記コードをchromeのコンソール等から実行すると定型文をツイートできます。

下記ソースは、はじめのやつが動きます。
2つ目は挙動が不安定です。

formタグを埋め込んで実行させる方はCSPの問題でエラーになるのと
成功しても実行結果のJSONファイルがローカルダウンロードされてしまいます。

単純に入力したいテキストを埋め込んでボタン押すようにしました。


CSPエラー:

Refused to execute inline script because it violates the following Content Security Policy directive: "script-src https://connect.facebook.net https://cm.g.doubleclick.net https://ssl.google-analytics.com https://graph.facebook.com https://twitter.com 'unsafe-eval' https://*.twimg.com https://api.twitter.com https://analytics.twitter.com https://publish.twitter.com https://ton.twitter.com https://syndication.twitter.com https://www.google.com https://t.tellapart.com https://platform.twitter.com 'nonce-3fmPjUSbjydKKll2qfU3Hw==' https://www.google-analytics.com blob: 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-a3jrMYVXEEA6OiADmrxAYVqEyCuvciqKxYphw6Z0AiY='), or a nonce ('nonce-...') is required to enable inline execution.


twitter.comでコンソールからツイートを実行する

GoogleAnalyticsAPIを使って定期的にユーザサマリーをチャットに流してくれるライブラリを作った

目的

GoogleAnalyticsは、アクセスがほとんどなかろうと
無限に見ていられる悪魔のツールです。

その為、要点を定期的にチャットにぶん投げてくれる時間節約装置が欲しく作りました。

機能

googleAnalyticsAPIで、ユーザサマリー等を
自前のテンプレート形式で、チャットに自動通知してくれるライブラリを作りました。

まだテストも例外処理も使い方マニュアルも出来ておらず、とりあえず動いているレベルで拙いのですが。。。

github.com

下記のような感じでチャットに流れます。(chatwork)
アクセス数はゴミなのでスルーして下さい。。。

f:id:bz0:20171010005823p:plain

今後やるタスク

・テンプレートの追加
・例外処理
・使い方マニュアルの作成
・通知に、slack / メール通知を追加
・後入れで機能を足していったので
 コードが既にごちゃごちゃしている為、設計から考え直してみる

Google Analytics API(Management API)でビュー情報を取得する

何をしたのか

google analytics APIの「Core Reporting API」だと
サイト名やサイトURLが取れないようだったので、「Management API」でビュー情報からとるようにしてみた。

前提

Google Analytics のデータ構造はアカウント > プロパティ > ビューの構成になっている。
・ビューごとに、サービス アカウント IDのメルアドに権限の付与が必要
Google Analytics APIのライブラリ(SDK)がPHP 5.4以上なので、実行時のバージョンに注意する

準備

下記を読んで、APIキーの設定・composerでGoogle Analtics APIのライブラリをインストールしておく。

google analytics apiの利用方法
 https://qiita.com/zayarwinttun/items/90ef6979c644f262d0c4

google analytics apiの使い方
 https://syncer.jp/google-analytics-api-tutorial

・"google/apiclient": "1.*"でcomposerインストール
 "^2.0"とするとエラーが出てダウンロードできなかった為、1系を利用する。

Failed to download google/apiclient-services from dist: The process "unzip -qq -o '/var/www/html/gaApiClient/vendor/google/apiclient-services/cfe77a392d46e400cc90ece63d6dcc97' -d '/var/www/html/gaApiClient/vendor/composer/2223267b'" exceeded the timeout of 300 seconds.

注意

・ビュー情報を複数作成している場合、何故か1つしか取れなかった。
 今のところ未解決なので下記ソースを利用する場合は注意して下さい。