Laravel5のお勉強 -第七回 Herokuにdeploy-

# Laravel5のお勉強
[第一回 環境構築](http://qiita.com/yu_eguchi/items/0426ea0a41489e96dd33)
[第二回 ControllerとViewの追加](http://qiita.com/yu_eguchi/items/d6ac0fa3e0014db536c3)
[第三回 Database連携(Mysql)](http://qiita.com/yu_eguchi/items/e272a8d34e714f8249df)
[第四回 モデルの作成/tinker紹介](http://qiita.com/yu_eguchi/items/419a2a081ff142ecf67f)
[第五回 テストデータの挿入/Fakerの使用](http://qiita.com/yu_eguchi/items/9af6eed45e14505f6ecc)
[第六回 CRUDの作成](http://~)
[第七回 Herokuにdeploy](http://qiita.com/yu_eguchi/items/34fce39a07c79591f4af)

# 第七回 Herokuにdeploy
## 前提条件
Mac OS yosemite
PHP 5.5以上
Mysql 5.6以上
Herokuにアカウント登録済み

## 目的
Laravel5のお勉強。
[ここ](http://laravel.jp/)が公式の日本語翻訳サイト

localで作成したアプリをHerokuに公開します。
世の中に出すことで、モチベーションをあげる
人によってドメインが異なりますが、今回私が公開したドメインは以下
http://heroku-laravel5-mysql.herokuapp.com/articles

CRUD作成で人通りの画面はできたので、公開しました。

## Herokuとは

![alt](https://d3k90kvix375hb.cloudfront.net/assets/heroku-og-cad174838a49b266550809e29026ec9bc18e056dae8f9cf523ea4237379691f9.png)

[Paas](https://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&ved=0CDkQFjABahUKEwiOo46SsN3IAhXjIKYKHbEsDAU&url=https%3A%2F%2Fja.wikipedia.org%2Fwiki%2FPlatform_as_a_Service&usg=AFQjCNHLqBzOFMKEnZt3leH4lY1_iYLcDA&sig2=o0mkL-yBIGlkFd4uBQcKeQ&bvm=bv.105841590,d.dGY)です。

Platform as a Service。
上記のリンク、wikipe見たらわかりやすいんですが、簡単に言うと、サーバを自前で立てずに、第三者が提供するプラットフォームを利用して、サービスを公開する仕組み。
自前でCentOSとか建てて、サービスを公開するのもいいのですが、コストもかかるので、Paasを使って、「サービスの作成に専念したい」、「けどある程度公開もしたいな」って時にいいかも。

社内結合環境として利用してもいいと思うし、addon使えば、Paasを提供するベンダーがある程度用意した範疇でカスタマイズもできるので便利。
※昔(新人の頃によくわからずに)、GAEを使ってましたが、今は下火なのか??あまり記事をみかけない気もする。。

## 事前準備

まずは[Heroku](https://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CB0QFjAAahUKEwiZs-L7sd3IAhXlJ6YKHXVqDWU&url=https%3A%2F%2Fwww.heroku.com%2F&usg=AFQjCNF8-hoB8iHVyZ2dDq3bYi_oSmHVtg&sig2=OxjD8lxD0LQJMRcTNcMPew&cad=rja)にアクセスしアカウントがない人は作成しよう。

とりあえず、toolbeltとか入れて、localからherokuにdeployできるようにしたいので、
PHPのハンズオンを終わらせてください。

![スクリーンショット 2015-10-25 19.17.59.png](https://qiita-image-store.s3.amazonaws.com/0/78857/c16263da-5466-e250-02a7-980ee5db53d7.png)

これのPHPをクリックすると、HerokuでPHP(pure)を公開するハンズオンが始まるので、
これを人とおり終わらせれば、tolbeltもgitも入り、準備が整う。

### MySQLの構築

PHPハンズオンが終われば、いよいよ自分のLaravelアプリでherokuを扱います。
Herokuはデフォルトでpostgressとsqliteしか扱っていないので、
MysqlはaddOnて形で組み込む必要があります。
※管理画面で事前にクレジットカードの情報を入力する必要がありますが、無料枠のまま使用します。

Laravelアプリのrootに移動し、

```
$ heroku addons:add cleardb
```

としてください。
これでherokuにMySQLが構築されます。
あとは、接続情報を取得し、環境変数に設定しないとLaravelでは使用できません。

```
heroku config
```

これでherokuの環境変数一覧が表示されます。
DBの情報は

```
CLEARDB_DATABASE_URL: mysql://[ユーザー名]:[パスワード]@[ホスト名]/[DB名]?reconnect=true
```

となってます。
なので、Herokuの環境変数に各値をセットしていきます!!
今回、database.hpには

```
$ cat -n config/database.php
     1	<?php
     2	return [
     3	    'fetch' => PDO::FETCH_CLASS,
     4	    'default' => env('DB_CONNECTION', 'mysql'),
     5	    'connections' => [
     6	        'mysql' => [
     7	            'driver'    => 'mysql',
     8	            'host'      => env('DB_HOST'),
     9	            'database'  => env('DB_DATABASE'),
    10	            'username'  => env('DB_USERNAME'),
    11	            'password'  => env('DB_PASSWORD'),
    12	            'charset'   => 'utf8',
    13	            'collation' => 'utf8_unicode_ci',
    14	            'prefix'    => '',
    15	            'strict'    => false,
    16	        ],
    17	    ],
    18	    'migrations' => 'migrations',
    19	    'redis' => [
    20	        'cluster' => false,
    21	        'default' => [
    22	            'host'     => '127.0.0.1',
    23	            'port'     => 6379,
    24	            'database' => 0,
    25	        ],
    26	    ],
    27	];
```

こうなっていると思うので、

```
'DB_HOST'
'DB_DATABASE'
'DB_USERNAME'
'DB_PASSWORD'
```

をherokuに設定していきます。

```
heroku config:set [KEY値]=[値]
```

これで設定していきます。
例)

```
heroku config:set DB_DATABASE=hogehoge
```

こんな感じです。
ちなみに、localでは、.envの中に記載された内容がここの**env('DB_DATABASE')**の中に展開されます。
.envファイルはgit管理されていないため(.gitignoreの中を見てください。)、herokuにもアップされません。
これで準備は整いました。

## herokuアプリの作成

管理画面からも作れるのですが、基本的にコマンドでやっていきます。
今回作成したLaravelアプリのルートディレクトリに移動し、以下

```
$heroku create hogehoge
※「hogehoge」はherokuで公開したアプリ名、及びドメイン名になります。ご自由に。
```

これでherokuにアプリが作成されます。
ただ、まだ枠しかないので、具体的にどんなアプリを乗せるかはここからやっていきます。

## Laravelをherokuに乗せるように修正

Laravelは環境毎に設定ファイルを使い分けることができます。
今あなたが所有しているLaravelアプリのrootで

```
cat -n .env
```

としてみてください。
ここの環境変数を元に、環境別にLaravelが使い分けます。

例)

```
$ cat -n .env
     1	APP_ENV=local
     2	APP_DEBUG=true
     3	APP_KEY=hogehoge
     4	
     5	DB_HOST=localhost
     6	DB_DATABASE=test
     7	DB_USERNAME=root
     8	DB_PASSWORD=root
     9	
    10	CACHE_DRIVER=file
    11	SESSION_DRIVER=file
    12	QUEUE_DRIVER=sync
    13	
    14	MAIL_DRIVER=smtp
    15	MAIL_HOST=mailtrap.io
    16	MAIL_PORT=2525
    17	MAIL_USERNAME=null
    18	MAIL_PASSWORD=null
    19	MAIL_ENCRYPTION=null
```

今回cacheとかMailは使わないですが、DB系は必須です。

herokuは本番環境として、今回はみなします。
なので、先ほどherokuに設定した環境変数以外にも、最終的に以下となるように設定してください。

```
$ heroku config
=== heroku-laravel5-mysql Config Vars
APP_DEBUG:            false
APP_ENV:              production
APP_KEY:              hogehoge
BUILDPACK_URL:        https://github.com/heroku/heroku-buildpack-php.git
CLEARDB_DATABASE_URL: mysql://[ユーザー名]:[パスワード]@[ホスト名]/[DB名]?reconnect=true
DB_DATABASE:          [DB名]
DB_HOST:              [ホスト名]
DB_PASSWORD:          [パスワード]
DB_USERNAME:          [ユーザ名]
LANG:                 ja_JP.UTF-8
LD_LIBRARY_PATH:      /app/php/ext:/app/apache/lib
TZ:                   Asia/Tokyo
```

とくに、Laravelでは、composer.jsonとpackage.jsonが混在する構成であるため、
herokuがphpよりも、**node.js**として認識してしまい、phpコマンドがherokuで使えなくなるという惨事があります。
なので、

```
BUILDPACK_URL:        https://github.com/heroku/heroku-buildpack-php.git
```

これが超大事になります。
設定方法は、念のためですが、

```
heroku config:set BUILDPACK_URL=https://github.com/heroku/heroku-buildpack-php.git
```

です。

最後に、念のため、composer.jsonを載せておきます。
今回は本番環境を意識しているので、require_devにしか、Fakerは載せてないです。
ここはご自由におすきにしてください。

```
$ cat -n composer.json 
     1	{
     2	    "name": "laravel/laravel",
     3	    "description": "The Laravel Framework.",
     4	    "keywords": ["framework", "laravel"],
     5	    "license": "MIT",
     6	    "type": "project",
     7	    "require": {
     8	        "php": ">=5.5.27",
     9	        "laravel/framework": "5.1.*",
    10	        "laravelcollective/html": "~5.0",
    11	        "barryvdh/laravel-debugbar": "^2.0"
    12	    },
    13	    "require-dev": {
    14	        "fzaninotto/faker": "~1.4",
    15	        "mockery/mockery": "0.9.*",
    16	        "phpunit/phpunit": "~4.0",
    17	        "phpspec/phpspec": "~2.1",
    18	        "heroku/heroku-buildpack-php": "*"
    19	    },
    20	    "autoload": {
    21	        "classmap": [
    22	            "database"
    23	        ],
    24	        "psr-4": {
    25	            "App\\": "app/"
    26	        }
    27	    },
    28	    "autoload-dev": {
    29	        "classmap": [
    30	            "tests/TestCase.php"
    31	        ]
    32	    },
    33	    "scripts": {
    34	        "post-install-cmd": [
    35	            "php artisan clear-compiled",
    36	            "php artisan optimize"
    37	        ],
    38	        "pre-update-cmd": [
    39	            "php artisan clear-compiled"
    40	        ],
    41	        "post-update-cmd": [
    42	            "php artisan optimize"
    43	        ],
    44	        "post-root-package-install": [
    45	            "php -r \"copy('.env.example', '.env');\""
    46	        ],
    47	        "post-create-project-cmd": [
    48	            "php artisan key:generate"
    49	        ]
    50	    },
    51	    "config": {
    52	        "preferred-install": "dist"
    53	    }
    54	}
```

## いよいよdeploy

もし、まだgit管理してないなら、あなたのPJをgitリポジトリに登録してください。
git管理済みなら、以下のコマンドをPJリートで叩けば完了です。

```
git push heroku master
```

これでherokuにdeployが走り、同時にcomposer.jsonが評価され、vendor系が展開されます。

次にheroku本番環境でmigrateを実行しないと、heroku上のmysqlにテーブルが何もない状態なので、

```
$ heroku run bash
Running bash on [あなたのherokuアプリ名]... up, run.1796
~ $ pwd
/app
~ $ php artisan migrate
**************************************
*     Application In Production!     *
**************************************

 Do you really wish to run this command? [y/N] (yes/no) [no]:
 > y

Migration table created successfully.
Migrated: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_100000_create_password_resets_table
Migrated: 2015_10_10_154228_create_articles_table
Migrated: 2015_10_11_091650_add_published_at_to_articles_table
```

とすれば、テーブルが作成されます。
localに戻って、mysqlに接続してみましょう。

```
mysql -h [ホスト名] -u [ユーザー名] -D [DB名] -p[パスワード]
```

ログインしたら

```
mysql> show tables;
+----------------------------------+
| Tables_in_heroku_099992742640d40 |
+----------------------------------+
| articles                         |
| migrations                       |
| password_resets                  |
| test                             |
| users                            |
+----------------------------------+
5 rows in set (0.33 sec)
```

できました。

## 本番環境にアクセス!!


```
heroku open
```

これであなたがアップしたアプリにアクセスできます。
今回はroutingが「/articles」で始まるURLなので、
私の環境なら**「http://heroku-laravel5-mysql.herokuapp.com/articles」**

で記事一覧が表示されます。
「**http://heroku-laravel5-mysql.herokuapp.com/articles/create**」で記事を入稿して、一覧を表示させてみよう。

![スクリーンショット 2015-10-25 19.51.21.png](https://qiita-image-store.s3.amazonaws.com/0/78857/4794f04d-7364-ecb6-4d99-a1480598af93.png)

## 最後に

実はherokuでmigrateする時にちょーはまった。
migrateしても「<font color="red">PDOException H0000 2002 File Not Found</font>」とかなって、焦った。
結局は、会社の先輩に相談して解決したのですが、database.phpにportとsockの記述が要らなかった。

sockはlocalhost内でクラサバでつなぐときにだけ、あれば良い。なくても良い。
portは単純に「3306」を「33060」とタイポしてただけ…。。。

栗山さん、ありがとうございました。