高速!!コマンドラインで静的herokuサイト開設(要gitスキル)

下記はunixライクなコマンドラインが利用できる前提で書かれています。

# gitのインストール
デフォルトで入ってたりするのでまずは下記コマンドで確認してみてね。

```text:コマンド
$ git --version
```
https://git-scm.com/book/ja/v1/%E4%BD%BF%E3%81%84%E5%A7%8B%E3%82%81%E3%82%8B-Git%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB

# herokuアカウント作成
https://www.heroku.com/

# herokuクライアントインストール
https://devcenter.heroku.com/articles/heroku-command-line

# sshキー作成(herokuにpushするときいるよ)
http://webkaru.net/linux/ssh-keygen-command/

# herokuにsshキーを登録
http://blog.infinity-dimensions.com/2012/02/heroku-public-key-add.html

# コマンドラインで下記を実行
```text:コマンド
$ curl -o- https://raw.githubusercontent.com/nanananamememe/open_heroku/master/make.sh | bash
```

```text:出力結果
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   261  100   261    0     0   1003      0 --:--:-- --:--:-- --:--:--  1007
mkdir: my_site: File exists
Reinitialized existing Git repository in ~/my_site/.git/
Creating app... done, ⬢ hoge-piyo-99999
https://hoge-piyo-99999.herokuapp.com/ | https://git.heroku.com/hoge-piyo-99999.git
On branch master
nothing to commit, working directory clean
Counting objects: 4, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), 299 bytes | 0 bytes/s, done.
Total 4 (delta 0), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote: 
remote: -----> PHP app detected
remote: -----> Bootstrapping...
remote: -----> Installing platform packages...
remote:        NOTICE: No runtime required in composer.lock; using PHP ^5.5.17
remote:        - apache (2.4.20)
remote:        - nginx (1.8.1)
remote:        - php (5.6.29)
remote: -----> Installing dependencies...
remote:        Composer version 1.2.4 2016-12-06 22:00:51
remote: -----> Preparing runtime environment...
remote:        NOTICE: No Procfile, using 'web: vendor/bin/heroku-php-apache2'.
remote: -----> Checking for additional extensions to install...
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote: 
remote: -----> Compressing...
remote:        Done: 13.5M
remote: -----> Launching...
remote:        Released v3
remote:        https://hoge-piyo-99999.herokuapp.com/ deployed to Heroku
remote: 
remote: Verifying deploy.... done.
To https://git.heroku.com/hoge-piyo-99999.git
 * [new branch]      master -> master
```
これで広告表示無しのフリーのwebサイトが開設されます。
コマンドラインを実行したフォルダの直下にmy_siteというフォルダが出来ます。
herokuのアプリは自動生成され、my_siteフォルダにリモートリポジトリとして追加されています。

# webサイトを編集
```text:コマンド
$ cd my_site;
$ echo '<p><a href="test.html">test.html</a></p>' >> index.html;
$ echo 'This is a pen. This is a apple. huuunmm! Applepen!!' > test.html;
$ git add .;
$ git commit -a -m test;
$ git push heroku master;
$ heroku open;
```
どうですか？index.htmlにtest.htmlのリンクが貼られているでしょう？
あとはガンガンhtmlなりjavascriptなりcssなり書いてコミットしてプッシュしてwebサイトを構築していきましょう。

# これだけだと何なのでシェルスクリプトの説明
```bash:make.sh
#!/bin/sh
app=$1; #←引数を取得
if [ -z "$app" ];then
    app="my_site"; #←引数空ならmy_siteに
fi
mkdir $app; #←ディレクトリ作成 
cd $app; #←ディレクトリ移動
git init; #←git初期化
heroku create; #←herokuアプリ作成
echo '{}' > composer.json; #←コンポーサー設定作成、このファイルの有無でphpアプリか判断される
echo '<b>Hellow World!!</b> Yes we can!!' > index.html; #←ヘロ〜
git add .; #←composer.jsonとindex.htmlをgitのインデックスに登録
git commit -a -m first; #←コミット
git push heroku master; #←プッシュ＆デプロイーン
heroku open; #←ブラウザーに『Hellow World!』と表示されたらハッピー
```


# さらにこれだけでは何なのでアドオンでredisを使用したアプリのサンプルでも
* 実ソース https://github.com/nanananamememe/short_url
* サンプル https://infinite-forest-33516.herokuapp.com/

下記コマンドでgithubからソースをクローンしherokuアプリの作成、redisの追加までやってくれます。
「heroku-redis state creating.」と複数回出ます。
これはredisサーバーが起動中のため、その間はアプリが動かないので起動までの待機メッセージです。
「Allrady heroku-redis state created.」と出ると起動完了。ブラウザで短縮URL作成サイトが開くはずです。（たぶん）

```text:コマンド
$ curl -o- https://raw.githubusercontent.com/nanananamememe/open_heroku/master/make_short_url.sh | bash
```

```text:出力結果
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   519  100   519    0     0   1038      0 --:--:-- --:--:-- --:--:--  1040
Cloning into 'short_url'...
remote: Counting objects: 12, done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 12 (delta 0), reused 12 (delta 0), pack-reused 0
Unpacking objects: 100% (12/12), done.
Checking connectivity... done.
Creating app... done, ⬢ hoge-piyo-99999
https://hoge-piyo-99999.herokuapp.com/ | https://git.heroku.com/hoge-piyo-99999.git
Creating heroku-redis:hobby-dev on ⬢ hoge-piyo-99999... free
Your add-on is being provisioned and will be available shortly
! Data stored in hobby plans on Heroku Redis are not persisted.
redis-hoge-99999 is being created in the background. The app will restart when complete...
Use heroku addons:info redis-hoge-99999 to check creation progress
Use heroku addons:docs heroku-redis to view documentation
Counting objects: 12, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (9/9), done.
Writing objects: 100% (12/12), 2.63 KiB | 0 bytes/s, done.
Total 12 (delta 0), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote: 
remote: -----> PHP app detected
remote: -----> Bootstrapping...
remote: -----> Installing platform packages...
remote:        NOTICE: No runtime required in composer.json; requirements
remote:        from dependencies in composer.lock will be used for selection
remote:        - php (7.1.0)
remote:        - apache (2.4.20)
remote:        - nginx (1.8.1)
remote: -----> Installing dependencies...
remote:        Composer version 1.2.4 2016-12-06 22:00:51
remote:        Loading composer repositories with package information
remote:        Installing dependencies from lock file
remote:          - Installing predis/predis (v1.0.3)
remote:            Downloading: 100%
remote:        
remote:        Generating optimized autoload files
remote: -----> Preparing runtime environment...
remote:        NOTICE: No Procfile, using 'web: vendor/bin/heroku-php-apache2'.
remote: -----> Checking for additional extensions to install...
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote: 
remote: -----> Compressing...
remote:        Done: 14M
remote: -----> Launching...
remote:        Released v3
remote:        https://hoge-piyo-99999.herokuapp.com/ deployed to Heroku
remote: 
remote: Verifying deploy... done.
To https://git.heroku.com/hoge-piyo-99999.git
 * [new branch]      master -> master
heroku-redis state creating.
heroku-redis state creating.
heroku-redis state creating.
Allrady heroku-redis state created.
```

# 短縮URL作成PHPの説明
短縮URLということで http://hogehoge.heroku.com/ 以降は検索キー扱いとするので、.htaccessでリダイレクトさせる。

```text:.htaccess
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>
```

redisとの接続にpredisを使用。

```json:composer.json
{
  "require": {
     "predis/predis": "1.0.3"
  }
}
```

```php:index.php
<?php
require 'vendor/autoload.php';
Predis\Autoloader::register();
$domain = getenv('HTTP_HOST'); //ホスト名取得
$redisUrl = getenv('REDIS_URL'); //redis設定取得
if (!$redisUrl) { //redis設定が取得できなければエスケープ
    echo 'heroku-redisアドオン作成中。しばらくお待ち下さい...';
    exit;
}
$redis = new Predis\Client($redisUrl); //preisを介してredisに接続
$url = empty($_POST['url'])?null:trim($_POST['url']); //短縮対象のURLが送信されていれば変数に格納
$key = trim(getenv('REQUEST_URI'), '/'); //http://hogehoge.heroku.com/以降を検索キーとして取得
if ($url) { //短縮対象のURLが送信されていれば
    if (!preg_match('/^https?:\/\//', $url)) {　//URLの最初がhttpかhttpsかでなければ頭にhttp://を追加
        $url = 'http://' . $url;
    }
    $hash = strtr(trim(base64_encode(crc32(md5($url))), '='), '+/', '-_'); //$urlを元に検索キー生成
    $redis->set($hash, $url); //redisセット
    $redis->expire($hash, 43260); //redis保存期限の設定(秒)とりあえず | 60秒 x 60分　x 24時間 x 30日　= 43260
}
if ($key) { //検索キーが設定されていれば
    $redirect = $redis->get($key); //redisからurlを取得
    if ($redirect) { //urlが正常に取得できればリダイレクト
        header("Location: {$redirect}");
    } else {
        echo 'このURLの有効期限は切れました。';
        exit;
    }
} else {
    $jump = "http://{$domain}/{$hash}"; // 短縮後URLを作成
    require 'form.php'; //form.phpを読み込み
}
```

# シェルスクリプトの説明
```bash:make_short_url.sh
#!/bin/sh
app=$1; #引数を取得
if [ -z "$app" ];then
    app="short_url"; #引数空ならshort_urlに
fi
git clone https://github.com/nanananamememe/short_url $app; #githubより短縮URL作成のソースをクローン
cd $app; #チェーンジディレクトリ
heroku create; #ヘロクアプリ生成
heroku addons:create heroku-redis:hobby-dev; #サーバーへredisアドオンを追加
git push heroku master; #短縮URL作成のソースをヘロクにプッシュ
state=`heroku addons:info heroku-redis|grep State|awk '{print $2}'`; #redisサーバーの状態を取得
hold="creating" #状態が作成中の場合はこのメッセージ、$stateが一致した場合は延々とwhileが回ります。
while [ $state = $hold ]
do
    echo "heroku-redis state $state."; #作成中のメッセージ
    sleep 10s; #10秒待機
    state=`heroku addons:info heroku-redis|grep State|awk '{print $2}'`; #redisサーバーの状態を取得
done;
echo "Allrady heroku-redis state $state."; #redisサーバー作成完了
heroku open; #ブラウザを起動
```

以上。