MastodonインスタンスをHerokuだけで立てる

最近Mastdonが流行っているらしいので
お金をかけずにMastdonインスタンスをHerokuのみで立ててみます。

注意

  • 本手順ではS3(ストレージ)を利用しないので、アイコンやヘッダーなどは保存されません。
  • 自分1人用のインスタンスにするつもりで作ってます。
  • 「Herokuのみ」に拘っており、他の無料ツールと組み合わせることもできますが、やってません。

■参考にしたサイト

■手順(インスタンス生成編)

Herokuのアカウントを持っていなければアカウント作成します。
アカウント作成はコチラから。

mastodon公式のHerokuページにて「Deploy to Heroku」ボタンをクリックする。

Herokuのアプリ新規作成画面が開くので、以下を入力します。

  • AppName: 作成するアプリ名
  • LOCAL_DOMAIN: {上記のAppName}.herokuapp.com
  • S3_ENABLED: false
  • SINGLE_USER_MODE: true

上記入力が完了したら『Deploy』ボタンをクリックします。

私の場合はここでクレジットカード情報を入力する画面が出ましたが、既にHerokuを使っていて無料枠を使い切っていたから出たのかもしれません。
ど新規でHeroku登録していれば、何も出ないかもしれません。

Deployが完了したら、Heroku管理画面の「Resources」画面にて「worker」をONにします。
右側のエンピツマークをクリックしたらON/OFFを切り替えできるようになります。

ここまでで、マストドンのインスタンス生成は完了です。

■手順(アカウント登録編)

普通ならアカウント登録をし、登録したメールアドレスに届いたメールのリンクをクリックすれば
アカウント登録は完了なのですが、今回はメールサーバーの設定もしてないので、
無理やりDBを参照して進めます。

まず、Heroku管理画面の「Resources」画面にて、『Heroku Postgres :: Database』をクリックします。
するとPostgreSQLの管理画面へ遷移するので、『View Credentials』をクリックし、
「Heroku CLI」(heroku pg:psql〜)を確認しておきます。
※後ほど利用するHeroku CLIのコマンドです。

ブラウザで『{AppName}.herokuapp.com』へアクセスするとアカウント作成画面が開くので
普通にアカウント登録します。

次に、Heroku CLIをインストールします。
インストール手順はコチラにまとまってます。

ローカルPCにPostgreSQLが入っていないなら、インストールしておきます。
Macなら以下コマンドでインストールできます。

brew install postgresql

PostgreSQLが使える状態になったら、HerokuのDBへ接続して
メールアドレス確認用のtokenを確認します。

# ローカルPCのターミナルにて、確認した「Heroku CLI」コマンドを実行
heroku pg:psql postgresql-fitted-xxxxxx --app {AppName}
# DB操作モードに切り替わるので、DBよりtokenをselectする
select email, confirmation_token from users;

上記コマンドでtokenが表示されるので、それを含めた以下のURLへブラウザでアクセスします。
https://{AppName}.herokuapp.com/auth/confirmation?confirmation_token={上記で確認したtoken}

これでメールアドレスの確認も完了し、Mastdonを利用開始できます。

【Mac】fish + oh-my-fish + pecoの導入方法

環境

OS X ElCapitan 10.11.6


fishのインストール

brewでfishをインストールする。

brew install fish

※brew自体のインストールについてはこちら参照。

次にシェル一覧にfishを追加する。

vim /etc/shells
# 以下行を追加
/usr/local/bin/fish

次に通常利用するシェルをfishに設定する。

chsh -s /usr/local/bin/fish

oh-my-fishのインストール

以下コマンドを実行するだけ。

curl -L http://get.oh-my.fish | fish

pecoのインストール

pecoはbrewとomfコマンドでインストールできる。

brew install peco
omf install peco

インストールできたら、fishの設定ファイルにpecoの設定を追記する。
fishの設定ファイルが存在しない場合は新規作成する。

vim ~/.config/fish/config.fish
# 以下行を追記する
function fish_user_key_bindings
    bind \cr peco_select_history
end

以上で設定完了です。

【Laravel】migrateで『Class ‘CreateFoooTable’ not found』が発生する

■環境

Laravel 5.1


Laravelの「migrate:rollback」や「migrate:refresh」をしようとして
『Class ‘CreateFoooTable’ not found』というエラーが発生した際の解決方法です。

この事象はmigrateで利用する「/database/migrations」ディレクトリに配置されているファイルが
autoloadされていない事が原因のようです。

解決するにはプロジェクトのrootディレクトリにて以下コマンドを実行し、autoloadを再編成します。

composer dump-autoload

※composerインストールについてはコチラ

もしサーバにcomposerを入れられない場合は作業PCにて上記コマンドを実行すると
「/vendor」ディレクトリ配下が更新されるのでサーバにアップロードしてください。

以上。

Composerのインストール方法

■環境

macOS Sierra 10.12.4
CentOS 6.8


作業用MacとCentOSサーバにComposerをインストールしたので、その際のメモです。

【Macの場合】

brewでインストールできます。

brew install homebrew/php/composer

【CentOSの場合】

CURLでインストーラを取得し、生成された実行ファイルをPATHが通っているディレクトリに移動します。

curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/bin/composer

以上

【PHP】Laravel5でカスタムバリデーションを追加する

Laravel5でカスタムバリデーションを追加した際の手順です。

■環境
Laravel 5.1

まず、サービスプロバイダーを作成して、バリデーションルールを記載します。
例えば以下のルールの社員番号があったとします。
・頭文字は「A」または「Z」
・2文字目以降は数字6桁

このバリデーションルールを『shainbangou』という名前のルールで登録するとこうなります。
【/app/providers/ValidatorServiceProvider.php】

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Validator;

class ValidatorServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Validator::extend('shainbangou', function($attr, $value, $param) {
            return preg_match('/^[A|Z][0-9]{6}$/', $value);
        });
    }
}

次にエラー文言の設定をします。
viewにて社員番号はempIdという変数名で設定されているとします。
【/resources/lang/ja/validation.php】

return [
〜〜 省略 〜〜
    'custom' => [
        'empId' => [
            'shainbangou' => '社員番号が間違っています。(A/Z + 数字6桁).',
        ],
    ],
〜〜 省略 〜〜
    'attributes' => [
        'empId' => '社員番号',
    ],
];

これで、コントローラなどのバリデーション処理で新ルール「shainbangou」が使えるようになります。

gitの履歴から特定のコミット以降の履歴だけを残してクリアする

個人で開発しているアプリケーションのgitリポジトリで履歴がグチャグチャしてしまったので、
コミット履歴をちょっと弄った時のメモです。

====================================
※注意※
gitの履歴は過去に何があったかを調べる際の手がかりになるので、
削除する理由がないのであれば残しておきましょう。
特に、他人と共同で修正しているリポジトリであれば尚更です。

====================================

履歴を残し始める直前のバージョンの状態を作る

# git clone  tmpRepo1
# cd tmpRepo1
# git checkout {残し始めたいコミットの直前のコミット番号}
# rm -rf .git
# cd ../

作業用のリポジトリを作る

# git clone  tmpRepo2
# cd tmpRepo2
# git checkout --orphan tmpBr

初期状態をコミットする

# rm -rf <.git以外の全て>
# cp -r ../tmpRepo1/* .
# git add .
# git commit -m "Initialization"

残したいコミット履歴に対して、次の処理を過去から順に繰り返し実施する

# git cherry-pick {残したいコミット}

なお、残したいコミット履歴がマージ履歴の場合は以下の手順となる

# git cherry-pick -m 1 {残したいマージコミット}
# git commit --allow-empty

コメントの編集画面が出るが、そのまま:wqして抜ける

意図した履歴が生成されたか確認

# git log

masterにプッシュする

# git checkout -B master
# git push --force

一時的に作ったブランチを削除

# git branch -d tmpBr

【golang】mapの要素順は変動する

■環境
OS X El Capitan 10.11.6
go 1.8 darwin/amd64

タイトルの件、ちょっと引っかかったのでメモです。

golangで変数にmapを格納する場合、その要素の順番は
呼び出すたびに変わります。

以下サンプルコードです。
mapをrangeで取り出しながらforで回し、標準出力する
という処理を3回繰り返します。

package main

import (
	"fmt"
)

func main() {
	// create new map
	fruitColor := make(map[string]string)
	fruitColor["pineapple"] = "yellow"
	fruitColor["apple"] = "red"
	fruitColor["grape"] = "purple"
	fruitColor["melon"] = "green"

	// printout 3 times
	for i := 1; i <= 3; i++ {
		fmt.Println(fmt.Sprintf("===== %d times =====", i))
		for name, color := range fruitColor {
			fmt.Println(fmt.Sprintf("%s is %s", name, color))
		}
	}
}

これを実行すると、このように出力されます。
要素順は変動するので、実行する度に変わると思います。

===== 1 times =====
apple is red
grape is purple
melon is green
pineapple is yellow
===== 2 times =====
grape is purple
melon is green
pineapple is yellow
apple is red
===== 3 times =====
melon is green
pineapple is yellow
apple is red
grape is purple

上記のような順不同なアプリケーションだとしても、
ユーザが画面を表示する度に順番が変わるのは気持ち悪いので
sliceを使って表示順を保持しておいた方が良いです。

sliceを使う例は以下の通りです。

package main

import (
	"fmt"
)

func main() {
	// create new map
	fruitColor := make(map[string]string)
	fruitColor["pineapple"] = "yellow"
	fruitColor["apple"] = "red"
	fruitColor["grape"] = "purple"
	fruitColor["melon"] = "green"
	// set display order
	fruitList := []string{"pineapple","apple","grape","melon"}

	// printout 3 times
	for i := 1; i <= 3; i++ {
		fmt.Println(fmt.Sprintf("===== %d times =====", i))
		for _, name := range fruitList {
			fmt.Println(fmt.Sprintf("%s is %s", name, fruitColor[name]))
		}
	}
}

これを実行すると以下のようになります。

===== 1 times =====
pineapple is yellow
apple is red
grape is purple
melon is green
===== 2 times =====
pineapple is yellow
apple is red
grape is purple
melon is green
===== 3 times =====
pineapple is yellow
apple is red
grape is purple
melon is green