長生村本郷Engineers'Blog

千葉県長生村本郷育ちのエンジニアが書いているブログ

I used Phinx, DB migration Tool on Docker!

f:id:kenzo0107:20170721210050p:plain

Overview

This is Sandbox for DB Migration Tool Phinx.

Preparation

$ git clone https://github.com/kenzo0107/phinx-mysql
$ cd phinx-mysql

Create and Run Containers of Phinx, DB (MySQL).

$ make build
$ docker-compose ps

         Name                       Command             State     Ports
-------------------------------------------------------------------------
phinxmysql_db-migrate_1   phinx --help                  Exit 0
phinxmysql_db_1           docker-entrypoint.sh mysqld   Up       3306/tcp

The Container db-migrate is used as for one-off container, so its state is Exit 0.

Initialize Phinx Project

Phinx creates a default file called phinx.yml.

$ make init

In default setting, phinx select development environment.

1. Create Table

Create phinx definition file

$ make create DB=hogehoge CLASS=CreateTableUsers
$ make create DB=mogemoge CLASS=CreateTableMembers
...
...
created db/migrations/hogehoge/20170724065658_create_table_users.php
created db/migrations/mogemoge/20170724065738_create_table_members.php

Edit phinx definition file

  • db/migrations/hogehoge/20170724065658_create_table_users.php

Writing Migrations

<?php

use Phinx\Migration\AbstractMigration;
use Phinx\Db\Adapter\MysqlAdapter;

class CreateTableUsers extends AbstractMigration
{
    public function up()
    {
        // Automatically generated id is excluded, and primary key is set as user_id
        $t = $this->table('users', ['id' => 'user_id']);

        $t->addColumn('last_name',       'string',     ['limit' => 10,  'comment' => '姓'])
          ->addColumn('first_name',      'string',     ['limit' => 10,  'comment' => '名'])
          ->addColumn('last_kana_name',  'string',     ['null' => true, 'limit' => 10,  'comment' => '姓(カナ)'])
          ->addColumn('first_kana_name', 'string',     ['null' => true, 'limit' => 10,  'comment' => '名(カナ)'])
          ->addColumn('username',        'string',     ['limit' => 20,  'comment' => 'ユーザ名'])
          ->addColumn('password',        'string',     ['limit' => 40,  'comment' => 'パスワード'])
          ->addColumn('email',           'string',     ['limit' => 100, 'comment' => 'Email'])
          ->addColumn('postcode',        'string',     ['limit' => 10,  'comment' => '郵便番号'])
          ->addColumn('birthday',        'date',       ['comment' => '誕生日'])
          ->addColumn('gender',          'integer',    ['limit' => MysqlAdapter::INT_TINY, 'comment' => '性別(1:男 2:女 3:その他)'])
          ->addColumn('card_number',     'string',     ['null' => true, 'limit' => 20,  'comment' =>'クレジットカードNo']) 
          ->addColumn('description',     'text',       ['null' => true, 'limit' => MysqlAdapter::TEXT_LONG, 'comment' =>'説明'])
          ->addColumn('created',         'timestamp',  ['default' => 'CURRENT_TIMESTAMP'])
          ->addColumn('updated',         'datetime',   ['null' => true])
          ->addIndex(['username', 'email'],     ['unique' => true])
          ->create();
    }

    public function down()
    {
        $this->dropTable('users');
    }
}
  • db/migrations/mogemoge/20170724065738_create_table_members.php
<?php

use Phinx\Migration\AbstractMigration;

class CreateTableMembers extends AbstractMigration
{
    public function up()
    {
        $t = $this->table('members');
        $t->addColumn('member_code', 'string',    ['limit' => 20,  'comment' => '会員コード'])
          ->addColumn('created',     'timestamp', ['default' => 'CURRENT_TIMESTAMP'])
          ->addColumn('updated',     'datetime',  ['null' => true])
          ->addIndex(['member_code'], ['unique' => true])
          ->create();
    }

    public function down()
    {
        $this->dropTable('members');
    }
}

2. Add Column

Create phinx definition file

$ make create CLASS=AddTableUsersColumnsCity
...
...
created db/migrations/hogehoge/20170724065838_add_table_users_columns_city.php

Edit phinx definition file

  • db/migrations/hogehoge/20170724065838_add_table_users_columns_city.php

Add the column city after the column email.

<?php

use Phinx\Migration\AbstractMigration;

class AddTableUsersColumnsCity extends AbstractMigration
{
    public function up()
    {
        $t = $this->table('users');
        $t->addColumn('city', 'string', ['limit' => 10, 'comment' => '都市', 'after' => 'postcode'])
          ->update();
    }

    public function down()
    {
        $t = $this->table('users');
        $t->removeColumn('city')
          ->save();
    }
}

Migration

$ make migrate
  • Result
mysql> use hogehoge
mysql> show full columns from users;
+-----------------+--------------+-----------------+------+-----+-------------------+----------------+---------------------------------+---------------------------------+
| Field           | Type         | Collation       | Null | Key | Default           | Extra| Privileges                      | Comment                         |
+-----------------+--------------+-----------------+------+-----+-------------------+----------------+---------------------------------+---------------------------------+
| user_id         | int(11)      | NULL            | NO   | PRI | NULL              | auto_increment| select,insert,update,references |                                 |
| last_name       | varchar(10)  | utf8_general_ci | NO   |     | NULL              || select,insert,update,references | 姓                              |
| first_name      | varchar(10)  | utf8_general_ci | NO   |     | NULL              || select,insert,update,references | 名                              |
| last_kana_name  | varchar(10)  | utf8_general_ci | YES  |     | NULL              || select,insert,update,references | 姓(カナ)                      |
| first_kana_name | varchar(10)  | utf8_general_ci | YES  |     | NULL              || select,insert,update,references | 名(カナ)                      |
| username        | varchar(20)  | utf8_general_ci | NO   | MUL | NULL              || select,insert,update,references | ユーザ名                        |
| password        | varchar(40)  | utf8_general_ci | NO   |     | NULL              || select,insert,update,references | パスワード                      |
| email           | varchar(100) | utf8_general_ci | NO   |     | NULL              || select,insert,update,references | Email                           |
| city            | varchar(255) | utf8_general_ci | NO   |     | NULL              || select,insert,update,references |                                 |
| postcode        | varchar(10)  | utf8_general_ci | NO   |     | NULL              || select,insert,update,references | 郵便番号                        |
| birthday        | date         | NULL            | NO   |     | NULL              || select,insert,update,references | 誕生日                          |
| gender          | tinyint(4)   | NULL            | NO   |     | NULL              || select,insert,update,references | 性別(1:男 2:女 3:その他)        |
| card_number     | varchar(20)  | utf8_general_ci | YES  |     | NULL              || select,insert,update,references | クレジットカードNo              |
| description     | longtext     | utf8_general_ci | YES  |     | NULL              || select,insert,update,references | 説明                            |
| created         | timestamp    | NULL            | NO   |     | CURRENT_TIMESTAMP || select,insert,update,references |                                 |
| updated         | datetime     | NULL            | YES  |     | NULL              || select,insert,update,references |                                 |
+-----------------+--------------+-----------------+------+-----+-------------------+----------------+---------------------------------+---------------------------------+


mysql> use mogemoge
mysql> show full columns from members;
+-------------+-------------+-----------------+------+-----+-------------------+----------------+---------------------------------+-----------------+
| Field       | Type        | Collation       | Null | Key | Default           | Extra          | Privileges                      | Comment         |
+-------------+-------------+-----------------+------+-----+-------------------+----------------+---------------------------------+-----------------+
| id          | int(11)     | NULL            | NO   | PRI | NULL              | auto_increment | select,insert,update,references |                 |
| member_code | varchar(20) | utf8_general_ci | NO   | UNI | NULL              |                | select,insert,update,references | 会員コード      |
| created     | timestamp   | NULL            | NO   |     | CURRENT_TIMESTAMP |                | select,insert,update,references |                 |
| updated     | datetime    | NULL            | YES  |     | NULL              |                | select,insert,update,references |                 |
+-------------+-------------+-----------------+------+-----+-------------------+----------------+---------------------------------+-----------------+

Rollback

$ make rollback

3. Create sample seeds for Multi Databases;

Create phinx definition file

$ make seed_create DB=hogehoge CLASS=UserSeeder
$ make seed_create DB=mogemoge CLASS=MembersSeeder
...
...
created ./db/seeds/hogehoge/UsersSeeder.php
created ./db/seeds/mogemoge/MembersSeeder.php

Edit phinx definition file

  • ./db/seeds/hogehoge/UsersSeeder.php
<?php

use Phinx\Seed\AbstractSeed;

class UsersSeeder extends AbstractSeed
{
    public function run()
    {
        $t = $this->table('users');
        $t->truncate();

        $genders = [1,2,3];

        $faker = Faker\Factory::create('ja_JP');
        $d = [];
        for ($i = 0; $i < 10; $i++) {
            $d[] = [
                'last_name'        => $faker->lastName(10),
                'first_name'       => $faker->firstName(10),
                'last_kana_name'   => $faker->lastKanaName(10),
                'first_kana_name'  => $faker->firstKanaName(10),
                'username'         => $faker->userName(20),
                'password'         => sha1($faker->password),
                'email'            => $faker->email,
                'postcode'         => $faker->postcode,
                'city'             => $faker->city,
                'birthday'         => $faker->date($format='Y-m-d',$max='now'),
                'gender'           => $faker->randomElement($genders),
                'card_number'      => $faker->creditCardNumber,
                'description'      => $faker->text(200),
                'created'          => date('Y-m-d H:i:s'),
                'updated'          => date('Y-m-d H:i:s'),
            ];
        }

        $this->insert('users', $d);
    }
}
  • ./db/seeds/hogehoge/MembersSeeder.php
<?php

use Phinx\Seed\AbstractSeed;

class MembersSeeder extends AbstractSeed
{
    public function run()
    {
        $t = $this->table('members');
        $t->truncate();

        $faker = Faker\Factory::create('ja_JP');
        $d = [];
        for ($i = 0; $i < 10; $i++) {
            $d[] = [
                'member_code'  => $faker->regexify('[0-9]{20}'),
                'created'   => date('Y-m-d H:i:s'),
                'updated'   => date('Y-m-d H:i:s'),
            ];
        }

        $this->insert('members', $d);
    }
}

Run seed

$ make seed
  • Result
mysql> use hogehoge;
mysql> select * from users;
+---------+-----------+------------+-----------------+-----------------+-------------+------------------------------------------+------------------------------+----------+--------------+------------+--------+------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+---------------------+
| user_id | last_name | first_name | last_kana_name  | first_kana_name | username    | password                                 | email          | postcode | city         | birthday   | gender | card_number      | description                                                                                                                    | created             | updated           |
+---------+-----------+------------+-----------------+-----------------+-------------+------------------------------------------+------------------------------+----------+--------------+------------+--------+------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+---------------------+
|       1 | 佐々木    | 零         | ヤマダ          | カナ            | akira97     | e270038c94f231da7bca25dead3e386ba3984491 | hirokawa.rika@hotmail.co.jp  | 1867251  | 佐々木市     | 1987-09-25 |      1 | 4024007116991463 | Dolor reiciendis fuga fugiat id molestiae eos. Dolores sint rem repudiandae perspiciatis. Ducimus aut mollitia aut asperiores laboriosam.                                                 | 2017-07-25 12:22:50 | 2017-07-25 12:22:50 |
|       2 | 宮沢      | 千代       | ノムラ          | ヨウイチ        | nagisa.taro | 695a90d1b84cf004357aad3eb37697b51afbf5cc | tanabe.hiroshi@kudo.org      | 8639535  | 江古田市     | 1977-06-01 |      3 | 344103919563863  | Doloribus et recusandae quam accusantium pariatur nobis reiciendis quo. Eos quae et commodi quos accusamus ex. Ullam repellendus maiores vero sit sit et.                                 | 2017-07-25 12:22:50 | 2017-07-25 12:22:50 |
|       3 | 斉藤      | 充         | ミヤケ          | オサム          | kana.suzuki | f309f34d08b4d0d686863fa38ed3d3af5e0b2104 | kana.kudo@mail.goo.ne.jp     | 2763622  | 青田市       | 1997-01-30 |      1 | 4716886227252    | Veritatis voluptatem pariatur libero aut quia. Facere nemo quos enim amet ut ipsum sequi. Nobis natus et aspernatur aut. Natus pariatur deserunt voluptatum deserunt.                     | 2017-07-25 12:22:50 | 2017-07-25 12:22:50 |
|       4 | 吉田      | 太郎       | ウノ            | ツバサ          | naoko.uno   | 45d04bda7ac79244c90a33ff68798b979138054a | taro.nagisa@hirokawa.com     | 6099661  | 江古田市     | 2006-03-19 |      2 | 5372535333698250 | Nostrum velit nostrum eos magni. Reiciendis quos enim adipisci quisquam sed voluptas. Necessitatibus sint qui dolorem animi impedit consectetur commodi.                                  | 2017-07-25 12:22:50 | 2017-07-25 12:22:50 |
|       5 | 野村      | 亮介       | サトウ          | ミノル          | rika.tanabe | dd3d50714c0775bfee453f7d9a9815ce26ba57db | wkudo@hotmail.co.jp          | 6966314  | 渡辺市       | 1985-12-21 |      1 | 4929108488987091 | Id atque molestiae expedita omnis libero natus et. Repellendus ut tenetur molestias voluptas. Perspiciatis nisi et illum aut aut vel repudiandae.                                         | 2017-07-25 12:22:50 | 2017-07-25 12:22:50 |
|       6 | 木村      | 裕美子     | タナカ          | ヒロキ          | hiroshi53   | 033bfd0493b72efd0ff60bc15c7eeb3b2e054501 | ztanabe@tanabe.biz          | 3155238  | 山田市       | 1996-01-02 |      3 | 5476616628100007 | Assumenda consectetur ea sed et omnis alias fugiat quo. Porro nihil similique sint laudantium asperiores blanditiis. Error dolores vitae quia explicabo facilis deleniti distinctio.      | 2017-07-25 12:22:50 | 2017-07-25 12:22:50 |
|       7 | 吉本      | 陽一       | キムラ          | ヒデキ          | akira27     | 51de6afc65f535ae58f927d698f07e60e04c7746 | rika59@suzuki.com          | 6457702  | 田辺市       | 2010-04-12 |      2 | 5388155063289311 | Nesciunt qui beatae ut officia qui error autem. Temporibus alias earum ullam incidunt quo recusandae enim qui. Sed atque veritatis sed ad ullam qui. Repellendus est nostrum et pariatur. | 2017-07-25 12:22:50 | 2017-07-25 12:22:50 |
|       8 | 渡辺      | 翔太       | ササダ          | クミコ          | uno.momoko  | fa2d16d5f2acffd5aeeaab6791fe64c9f70a9b2f | stanabe@uno.com          | 5849600  | 伊藤市       | 2012-06-09 |      1 | 5274550197820022 | Odio quasi sunt tempora. Molestias aut qui sed quos beatae eum accusantium. Non dolores quam veniam et ab quidem nostrum repellendus. Qui ducimus et optio et.                            | 2017-07-25 12:22:50 | 2017-07-25 12:22:50 |
|       9 | 坂本      | 翔太       | ナカツガワ      | ナオキ          | akira.kudo  | 4af41e536bf19fa3cb0527304adad0de76260e82 | suzuki.momoko@mail.goo.ne.jp | 8609563  | 宮沢市       | 2005-10-23 |      3 | 5231530310398512 | Qui id neque molestiae facere aut et consequatur. Delectus ea voluptatibus provident atque assumenda maxime eum. At quidem sint accusamus. Eaque sed voluptate quo sint non non.          | 2017-07-25 12:22:50 | 2017-07-25 12:22:50 |
|      10 | 野村      | 翼         | ヒロカワ        | ナオコ          | taro.kudo   | f8a63d0010c99d6403e0c1f458005b934ec03f8c | kana.tanabe@mail.goo.ne.jp   | 5804069  | 桐山市       | 1988-12-25 |      2 | 5140671281503530 | Dolorem consequatur nulla alias perspiciatis ut. Tenetur modi cumque incidunt dolor.                                                                                                      | 2017-07-25 12:22:50 | 2017-07-25 12:22:50 |
+---------+-----------+------------+-----------------+-----------------+-------------+------------------------------------------+------------------------------+----------+--------------+------------+--------+------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+---------------------+



mysql> use mogemoge;
mysql> select * from members;

+----+----------------------+---------------------+---------------------+
| id | member_code          | created             | updated             |
+----+----------------------+---------------------+---------------------+
|  1 | 86190539096622228312 | 2017-07-25 12:22:51 | 2017-07-25 12:22:51 |
|  2 | 77322186584623078448 | 2017-07-25 12:22:51 | 2017-07-25 12:22:51 |
|  3 | 17169562241415794809 | 2017-07-25 12:22:51 | 2017-07-25 12:22:51 |
|  4 | 86738824931379981947 | 2017-07-25 12:22:51 | 2017-07-25 12:22:51 |
|  5 | 23125815173540252188 | 2017-07-25 12:22:51 | 2017-07-25 12:22:51 |
|  6 | 81839177491562485300 | 2017-07-25 12:22:51 | 2017-07-25 12:22:51 |
|  7 | 82938165381845652192 | 2017-07-25 12:22:51 | 2017-07-25 12:22:51 |
|  8 | 87208503292784158954 | 2017-07-25 12:22:51 | 2017-07-25 12:22:51 |
|  9 | 80172779107984112104 | 2017-07-25 12:22:51 | 2017-07-25 12:22:51 |
| 10 | 22825755425594828330 | 2017-07-25 12:22:51 | 2017-07-25 12:22:51 |
+----+----------------------+---------------------+---------------------+

Reference

5分でできる♪ AWS Lambda で EC2 Event を Slack 通知

以前 AWS EC2 メンテ通知のイベントチェックスクリプトを作成しました。
合わせて、対象インスタンスを停止・起動する様にしました。

kenzo0107.hatenablog.com

これを AWS Lamda で Slack 通知させる様にし
毎朝メンテの必要なイベントがわかる様にしました。

事前準備

macOS%$ pip install lambda-uploader awscli
macOS%$ aws configure --profile <profile>

プロジェクト clone

GitHub - kenzo0107/AWSEC2Events2Slack: AWS ec2 event notification to Slack

macOS%$ git clone https://github.com/kenzo0107/AWSEC2Events2Slack
macOS%$ tree AWSEC2Events2Slack
.
├── README.md
├── event.json
├── lambda.json
├── lambda_function.py
└── requirements.txt

各種環境に合わせて情報編集

{
    "name": "AWSEvent2Slack",
    "description": "Notificate AWS events to Slack",
    "region": "ap-northeast-1",
    "handler": "lambda_function.lambda_handler",
    "role": "arn:aws:iam::xxxxxxxxxxxx:role/lambda-check-events-to-slack",
    "timeout": 60,
    "memory": 128,
    "variables":
    {
        "SLACK_INCOMING_WEBHOOK":"https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX",
        "SLACK_CHANNEL":"#channel",
        "SLACK_USERNAME":"AWSEvent2Slack",
        "SLACK_ICON_URL":"http://i.imgur.com/6RCTdfi.png"
    }
}
Item Explain
role EC2リソースをdescribeする権限を所持したポリシーをアタッチ
variables 通知先Slack情報

AWS Lambda へソースアップロード

macOS%$ lambda-uploader --profile <profile>

λ Building Package
λ Uploading Package
λ Fin

AWSコンソールより Lambda 確認

登録されていることがわかります。

https://camo.githubusercontent.com/43c524e70a16dfafe29dfad03c3340afd75cc1db/687474703a2f2f692e696d6775722e636f6d2f473470383565622e706e67

テスト実行

イベントを取得しSlackに通知させる様にすることができました。

https://camo.githubusercontent.com/a8d87244b9139795b02f3292044ee38a9783bf6b/687474703a2f2f692e696d6775722e636f6d2f456d65327577372e706e67

トリガー設定

CloudWatch スケジュール式で cron 設定し 毎朝届ける様に指定しました。

f:id:kenzo0107:20170718213805p:plain

総評

lambda-uploader でのアップロードにより
ローカルで開発→テスト→デプロイ
とバージョン管理が明確になって良いです。

但し、一点気になる点はアップロード後、ソースがコンソール上で見えません。

具体的には

Lambda 関数 「AWSEvent2Slack」のデプロイパッケージが大きすぎて、インラインコード編集を有効にできません。ただし、関数を今すぐ呼び出すことはできます。

とコンソール上に表示されます。

前まで zip にまとめてアップロードするシェルを書いていたけど
その時はソースは見ることができました。

ローカルで挙動確認しておりコンソール上では見えなくても今のところ支障なしです。

以上 参考になれば何よりです。

Mackerel で Docker の起動状態確認

f:id:kenzo0107:20170714223239p:plain

概要

Docker コンテナがいつの間にか Exit していた!
なんてことを防ぐ為の Mackerel Agent の設定です。

mackerel-plugin-docker-state インストー

$ sudo mkdir -p /etc/mackerel-agent/conf.d
$ sudo curl https://raw.githubusercontent.com/ABCanG/mackerel-plugin-docker-state/master/mackerel-plugin-docker-state -o /etc/mackerel-agent/conf.d/mackerel-plugin-docker-state
$ sudo chmod +x /etc/mackerel-agent/conf.d/mackerel-plugin-docker-state
$ sudo cat <<'EOF'>/etc/mackerel-agent/conf.d/docker-state.conf
[plugin.metrics.docker-state]
command = "/etc/mackerel-agent/conf.d/mackerel-plugin-docker-state"
EOF

mackerel-agent.conf に include 設定追加

  • /etc/mackerel-agent/mackerel-agent.conf
pidfile = "/var/run/mackerel-agent.pid"
root = "/var/lib/mackerel-agent"
verbose = false
apikey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
diagnostic = true

roles = ["xxxxxxxx:xxx"]

# include conf.d/*.conf
include = "/etc/mackerel-agent/conf.d/*.conf"

...
...

Mackrel Agent 再起動

$ sudo service mackerel-agent restart

グラフ確認

しばらくするとグラフが表示されます。
※0 or 1 のみのグラフなので積み重ねグラフの方が見やすかったです

f:id:kenzo0107:20170714222015p:plain

※上記グラフではコンテナ2つが起動しています。

新規監視ルールを作成

running で検索すると出てきます。

f:id:kenzo0107:20170714223652p:plain

3分間の平均が1 より低くなったら
コンテナが停止(Exit)と見なし通知する様にしました。

総評

今回たまたま Mackerel の入ったサービスを触る機会を頂きました。

Mackerel の様なマネージドサービスを利用するメリットは
監視サーバを監視しないで良い、
という省運用コストだなぁと改めて実感。

Install latest Nginx on Ubuntu

f:id:kenzo0107:20170710213742p:plain

Just a memo.

Install Nginx

ubuntu%$ sudo su
ubuntu%$ curl http://nginx.org/keys/nginx_signing.key | sudo apt-key add -
ubuntu%$ sh -c "echo 'deb http://nginx.org/packages/ubuntu/ trusty nginx' >> /etc/apt/sources.list"
ubuntu%$ sh -c "echo 'deb-src http://nginx.org/packages/ubuntu/ trusty nginx' >> /etc/apt/sources.list"
ubuntu%$ apt-get update
ubuntu%$ apt-get install -y nginx

Install sysv-rc-conf

SysV is a runlevel configuration tool.

ubuntu%$ apt-get install -y sysv-rc-conf

Configure runlevel of nginx.

The command chkconfig is no longer available in Ubuntu. The equivalent command to chkconfig is update-rc.d. This command nearly supports all the new versions of ubuntu.

  • chkconfig —> sysv-rc-conf
ubuntu%$ sysv-rc-conf nginx on

Show runlevel of nginx

ubuntu%$ sysv-rc-conf --list nginx
nginx        0:off      1:off   2:on    3:on    4:on    5:on    6:off

Flask Python3 で 戸田市 tocoちゃんバスあと何分? Webアプリ作成♪

f:id:kenzo0107:20170707233203p:plain

Flask(フラスク) とは

Flask Official Site を参照すると冒頭に以下の文章があります。

Flask is a microframework for Python based on Werkzeug, Jinja 2 and good intentions

Flask は Python の小規模なフレームワークで、 Werkzug や Jinja 2 をベースとしています。

何がいいの?

最小限の構成で簡単な Web アプリケーションが作成できることです。
django, Rails でも簡単に出来なくもないですが、さらに手順は短く容易です。

チュートリアル

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

Flaskを利用する判断基準

  • 大規模なプロジェクトでない。(ファイル構成は自分 or チームで決定する必要がある為)
  • DB を使わない。使うにしても複雑なDB設計でない。
  • 利用するライブラリが Python 製でそのgatewayとして利用したい。

手始めに!

初心者向け記事は多数あるので割愛し
学習がてら Web アプリケーション作ったのでそちらをどうぞ♪

実際動くものとそのソースを見た方がイメージ湧くと思います。

tocoちゃんバス あと何分?

f:id:kenzo0107:20170707232036p:plain

戸田市のローカルバス toco ちゃんバスの停留所を指定しあと何分で来るかをカウントダウンするアプリです。
自分が使うので作ったら割と広まってきて嬉しい限り♪

※ちなみに戸田市役所に確認し非公式ではありますが公開許可をいただいております。  
※戸田市役所ご担当者様より「可能であれば最新の迂回情報なども載せていただけたら〜」という要望も頂きました♪

ソースはこちら♪

Github

ソースを参照頂けるとやってみたことがわかりやすいと思います。

やってみたこと

  • docker で flask ローカル開発環境作成
  • config ファイルからデータ呼び出し (config.py)
  • session 機能
  • Bootstrap 適用
  • superagent.js で非同期通信
  • flickity.js でフリッカブルに

本番動作環境

さくらVPSには CakePHP や SpringBoot のプロジェクトが乗っかっていたりとやりたい放題の環境として所持しています。

開発期間

ほぼほぼ 1週間。仕事の昼休みと日曜大工で 10時間足らずで公開出来ました。
どちらかというと js 側の学習コストが掛かった感じ。

総評

今回作成したユーザ情報を管理しない、
DBを持たないアプリにはうってつけでした。
構成が複雑になりすぎず丁度良かったです。

やはり大きな規模のプロジェクトには django が適しています。

個人的に戸田市役所に電話してWebアプリ公開の許可を頂く、
という承認申請が出来、地域貢献できる喜びが非常に大きかったです。

今後、バージョンアップしたいと思います。

Flask 利用に際して参考になれば何よりです。

以上です。

Flask Web Development: Developing Web Applications With Python

Flask Web Development: Developing Web Applications With Python

Apache 2.2.15 → 2.4.25 PHP 5.6 → 7 へアップデート on CentOS 6.9

f:id:kenzo0107:20170613223736j:plain

概要

PHP5 利用していますか?

PHP5.6 のセキュリティサポート期限は 31 Dec 2018
Supported Versions 参考

Apache/PHP アップデート、腰が重かったのですが
個人契約サーバなら誰にも迷惑かけないしいいか♪

ということで
放置気味にされた Apache2.2.15/PHP5.6 の個人のサーバを
アップデートすべく実施した内容をまとめました。

三行まとめ

  • SoftwareCollection を利用し現存Apache/PHPを残したまま、アップデート版を共存させ切り替え。のち古い Apache/PHP 削除
  • 必要モジュール (MySQLi, PHPRedis)インストー
  • PHP 7 で廃止された PHP5.6 機能やシンタックスを修正

SoftwareCollection とは?

f:id:kenzo0107:20170613224451p:plain

公式サイト によると
以下の様に説明されています。

  • 英語

    Software Collections give you the power to build, install, and use multiple versions of software on the same system, without affecting system-wide installed packages.

  • 日本語

    ソフトウェアコレクションは、システム全体でインストールされたパッケージに影響を与えることなく、同じシステム上に複数のバージョンのソフトウェアを構築、インストール、使用する能力を提供します。

同じシステム上に複数バージョンのソフトウェアをインストールできる様になる、
ということです。

SoftwareCollection インストー

$ sudo yum install centos-release-scl

httpd24 関連のモジュールインストー

$ sudo yum-config-manager --enable rhel-server-rhscl-6-rpms
$ sudo yum install httpd24-httpd httpd24-httpd-devel httpd24-mod_proxy_html httpd24-mod_session httpd24-mod_ssl
$ sudo scl enable httpd24 bash
$ sudo service httpd graceful
$ httpd -v
Server version: Apache/2.4.25 (Red Hat)
Server built:   Apr 12 2017 06:35:50

RHSCL リポジトリ利用可設定

$ sudo yum-config-manager --enable rhel-server-rhscl-7-rpms

php7 関連モジュールをインストー

# yum install -y scl-utils
# yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
# yum install -y http://rpms.remirepo.net/enterprise/remi-release-7.rpm
# yum install -y php70
# yum install -y php70-php-mysqlnd
# yum install -y php70-php-curl
# yum install -y php70-php-simplexml
# yum install -y php70-php-devel php70-php-gd php70-php-json php70-php-mcrypt php70-php-mbstring php70-php-opcache php70-php-pear php70-php-pecl-apcu php70-php-pecl-geoip php70-php-pecl-imagick php70-php-pecl-json-post php70-php-pecl-memcache php70-php-pecl-xmldiff php70-php-pecl-zip php70-php-pspell php70-php-soap php70-php-tidy php70-php-xml php70-php-xmlrpc

mysqli インストー

# yum --enablerepo=remi-php70 install php-mysqli

PHP7 用 phpredis インストー

# cd /usr/local/src
# git clone https://github.com/phpredis/phpredis.git
# cd phpredis
# git checkout php7
# phpize
# ./configure
# make
# make install
# echo 'extension=redis.so' > /etc/opt/rh/rh-php70/php.d/redis.ini

php-fpm 再起動

# /etc/init.d/php70-php-fpm restart

httpd 再起動

# /etc/init.d/httpd24-httpd restart

ここまでで PHP7 で動作する環境が整っているかと思います。
エラーログを見ながら修正に当たってください。

PHP 7 で廃止された構文を修正

PHP Parse error: syntax error, unexpected ‘new’ (T_NEW)

  • &= new <クラス名> の指定が不可となり、 = new <クラス名> にする必要があります。
&= new Class
↓
= new Class

PHP Fatal error: Cannot use ‘String’ as class name as it is reserved

  • PHP7 では class String, Int と型名の Class を作成できなくなりました。

自分は以下の様に修正しました。
※ 適宜プロジェクトのコーディングルールに則ってご変更ください。

class String {
↓ 
class Stringer {
class Int {
↓ 
class Intger {

プロジェクトによってはもっと色々出てくると思いますので
適宜修正ください。

総評

放置されがちになるミドルウェアのアップデートは小まめにやっておきたいですね。
脆弱性の定期的な棚卸しせねば

業務でアップデートするのであれば
アップデートする環境を別途用意してアップデートする、
そこでミドルウェア、アプリケーションのコードレベルでのアップデート手順をまとめ
本番環境で実施。

機能(url)毎に正しく動いたものだけプロキシで PHP7 へ流す
というのもアリかなと思います。

以上です。

参考

Install PHP7, PECL, PEAR on MacOS

f:id:kenzo0107:20170604224801p:plain

備忘録です。
Azure で SQL Server に接続する際に必要でした。
忘れない為の自分への一筆。

PHP 7 インストー

$ brew update
$ brew install homebrew/php/php70
$ echo 'export PATH="$(brew --prefix homebrew/php/php70)/bin:$PATH"' >> ~/.bashrc
$ source ~/.bashrc
$ php -v

PHP 7.0.19 (cli) (built: May 21 2017 11:56:11) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies

PHP 7 で Pecl, Pear インストー

$ curl -O http://pear.php.net/go-pear.phar
$ sudo php -d detect_unicode=0 go-pear.phar

Below is a suggested file layout for your new PEAR installation.  To
change individual locations, type the number in front of the
directory.  Type 'all' to change all of them or simply press Enter to
accept these locations.

 1. Installation base ($prefix)                   : /usr/local/Cellar/php70/7.0.19_11
 2. Temporary directory for processing            : /tmp/pear/install
 3. Temporary directory for downloads             : /tmp/pear/install
 4. Binaries directory                            : /usr/local/Cellar/php70/7.0.19_11/bin
 5. PHP code directory ($php_dir)                 : /usr/local/Cellar/php70/7.0.19_11/share/pear
 6. Documentation directory                       : /usr/local/Cellar/php70/7.0.19_11/docs
 7. Data directory                                : /usr/local/Cellar/php70/7.0.19_11/data
 8. User-modifiable configuration files directory : /usr/local/Cellar/php70/7.0.19_11/cfg
 9. Public Web Files directory                    : /usr/local/Cellar/php70/7.0.19_11/www
10. System manual pages directory                 : /usr/local/Cellar/php70/7.0.19_11/man
11. Tests directory                               : /usr/local/Cellar/php70/7.0.19_11/tests
12. Name of configuration file                    : /usr/local/etc/php/7.0/pear.conf

// インストール先指定
1-12, 'all' or Enter to continue: (「1」と入力しEnter)

(Use $prefix as a shortcut for '/usr/local/Cellar/php70/7.0.19_11', etc.)
Installation base ($prefix) [/usr/local/Cellar/php70/7.0.19_11] : (「/usr/local/pear」と入力しEnter)




Below is a suggested file layout for your new PEAR installation.  To
change individual locations, type the number in front of the
directory.  Type 'all' to change all of them or simply press Enter to
accept these locations.

 1. Installation base ($prefix)                   : /usr/local/pear
 2. Temporary directory for processing            : /tmp/pear/install
 3. Temporary directory for downloads             : /tmp/pear/install
 4. Binaries directory                            : /usr/local/pear/bin
 5. PHP code directory ($php_dir)                 : /usr/local/pear/share/pear
 6. Documentation directory                       : /usr/local/pear/docs
 7. Data directory                                : /usr/local/pear/data
 8. User-modifiable configuration files directory : /usr/local/pear/cfg
 9. Public Web Files directory                    : /usr/local/pear/www
10. System manual pages directory                 : /usr/local/pear/man
11. Tests directory                               : /usr/local/pear/tests
12. Name of configuration file                    : /usr/local/etc/php/7.0/pear.conf

// バイナリディレクトリ指定
1-12, 'all' or Enter to continue: (「4」と入力しEnter)

(Use $prefix as a shortcut for '/usr/local/pear', etc.)
Binaries directory [$prefix/bin] : /usr/local/bin


Below is a suggested file layout for your new PEAR installation.  To
change individual locations, type the number in front of the
directory.  Type 'all' to change all of them or simply press Enter to
accept these locations.

 1. Installation base ($prefix)                   : /usr/local/pear
 2. Temporary directory for processing            : /tmp/pear/install
 3. Temporary directory for downloads             : /tmp/pear/install
 4. Binaries directory                            : /usr/local/bin
 5. PHP code directory ($php_dir)                 : /usr/local/pear/share/pear
 6. Documentation directory                       : /usr/local/pear/docs
 7. Data directory                                : /usr/local/pear/data
 8. User-modifiable configuration files directory : /usr/local/pear/cfg
 9. Public Web Files directory                    : /usr/local/pear/www
10. System manual pages directory                 : /usr/local/pear/man
11. Tests directory                               : /usr/local/pear/tests
12. Name of configuration file                    : /usr/local/etc/php/7.0/pear.conf

// 以上で基本設定が済んだのでインストールを開始する
1-12, 'all' or Enter to continue: (何も入力せずEnter)

// インストールが開始されます。
Beginning install...
Configuration written to /usr/local/etc/php/7.0/pear.conf...
Initialized registry...
Preparing to install...
installing phar:///Users/kenzo.tanaka/azure/go-pear.phar/PEAR/go-pear-tarballs/Archive_Tar-1.4.2.tar...
installing phar:///Users/kenzo.tanaka/azure/go-pear.phar/PEAR/go-pear-tarballs/Console_Getopt-1.4.1.tar...
installing phar:///Users/kenzo.tanaka/azure/go-pear.phar/PEAR/go-pear-tarballs/PEAR-1.10.4.tar...
installing phar:///Users/kenzo.tanaka/azure/go-pear.phar/PEAR/go-pear-tarballs/Structures_Graph-1.1.1.tar...
installing phar:///Users/kenzo.tanaka/azure/go-pear.phar/PEAR/go-pear-tarballs/XML_Util-1.4.2.tar...
install ok: channel://pear.php.net/Archive_Tar-1.4.2
install ok: channel://pear.php.net/Console_Getopt-1.4.1
install ok: channel://pear.php.net/Structures_Graph-1.1.1
install ok: channel://pear.php.net/XML_Util-1.4.2
install ok: channel://pear.php.net/PEAR-1.10.4
PEAR: Optional feature webinstaller available (PEAR's web-based installer)
PEAR: Optional feature gtkinstaller available (PEAR's PHP-GTK-based installer)
PEAR: Optional feature gtk2installer available (PEAR's PHP-GTK2-based installer)
PEAR: To install optional features use "pear install pear/PEAR#featurename"

The 'pear' command is now at your service at /usr/local/bin/pear

** The 'pear' command is not currently in your PATH, so you need to
** use '/usr/local/bin/pear' until you have added
** '/usr/local/bin' to your PATH environment variable.

Run it without parameters to see the available actions, try 'pear list'
to see what packages are installed, or 'pear help' for help.

For more information about PEAR, see:

  http://pear.php.net/faq.php
  http://pear.php.net/manual/

Thanks for using go-pear!

PECL インストール確認

$ which pecl
/usr/local/bin/pecl

$ pecl version
PEAR Version: 1.10.4
PHP Version: 7.0.19
Zend Engine Version: 3.0.0
Running on: Darwin pc-12-332.local 16.5.0 Darwin Kernel Version 16.5.0: Fri Mar  3 16:52:33 PST 2017; root:xnu-3789.51.2~3/RELEASE_X86_64 x86_64

PEAR インストール確認

$ which pear
/usr/local/bin/pear

PEAR Version: 1.10.4
PHP Version: 7.0.19
Zend Engine Version: 3.0.0
Running on: Darwin pc-12-332.local 16.5.0 Darwin Kernel Version 16.5.0: Fri Mar  3 16:52:33 PST 2017; root:xnu-3789.51.2~3/RELEASE_X86_64 x86_64

以上です。

詳細! PHP 7+MySQL 入門ノート

詳細! PHP 7+MySQL 入門ノート