- 投稿日:2020-03-15T21:53:31+09:00
ローカル環境へのWordPressインストール方法
はじめに
ここでは、MAMPを使ってローカル環境にWordPressをインストールする方法について解説します。
Windows環境を想定しています。WordPress用データベースの作成
まず、WordPress用に、MySQLデータベースを作成します。
データベース名はWordPressインストール時に入力しますので、WordPress用のデータベースであることが分かりやすい名前にしておくと良いです。WordPressのインストール
WordPress公式ページにアクセスし、「Wordpressを入手」をクリックします。
すると、ダウンロードページに移ります。
ここで、WordPress X.X.Xをダウンロードをクリックすると、zipファイルがダウンロードされます。zipファイルを展開し、MAMPディレクトリのhtdocsディレクトリ下にコピーします(デフォルトの設定の場合)。
そして、「localhost:80/wordpress」にアクセスします(Macの場合はlocalhost:8888)。
すると、以下のような画面が出てくるので、「さあ始めましょう!」をクリックします。すると、データベースにアクセスするための情報の入力を求められるので、上で作成したデータベース名などを入力します。
「インストール実行」をクリックすると、WordPressがインストールされます。
その後、管理画面にログインするためのユーザー名やパスワードを作成すると、ローカル環境でWordPressを利用できるようになります。
まとめ
ここでは、ローカル環境にWordPressをインストールする方法について解説しました。
WordPressはレンタルサーバーにインストールすることが多いと思いますが、ローカル環境にもインストールしておくと、公開前のサイトの記事の下書きをストックしておいたりなどの使い方ができます。
- 投稿日:2020-03-15T19:16:18+09:00
【Laravel】 外部制約キーを migration で設定しようとしたらエラー
何が起きたか
hoge
テーブルにusers
テーブルのid
で外部制約キーを設定しようと migrate 実行時にエラーが結論
bigInteger
で制約を付けたいカラムにを定義しないと、migration
ファイル作成時に記述されている$table->id()
と型が異なってしまう知っていればつまづくポイントにもならないと思いますが、自分の備忘録として・・・
エラーパターン
migration
// users テーブル public function up() { Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('login_id'); $table->string('password'); $table->timestamps(); }); }// hoge テーブル public function up() { Schema::create('hoge', function (Blueprint $table) { $table->id(); $table->string('name'); $table->integer('user_id')->unsigned(); $table->timestamps(); $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); }); }エラー内容
エラーを見ると
Cannot add foreign key constraint
...エラーが起きたのどこだろ
MySqlの場合下記実行でエラー内容の詳細が見れる。
SHOW ENGINE INNODB STATUS;
status
カラムのLATEST FOREIGN KEY ERROR
とある部分を見るとCannot find an index in the referenced table where the referenced columns appear as the first columns, or column types in the table and the referenced table do not match for constraint.エラーに従って
users
のid
とhoge
のuser_id
をチェックすると
users.id
はBIGINT
hoge.user_id
はINT
型が違った
修正内容
hoge
テーブルのuser_id
定義を変更してやればOK// hoge テーブル 修正後 public function up() { Schema::create('hoge', function (Blueprint $table) { $table->id(); $table->string('name'); $table->bigInteger('user_id')->unsigned(); $table->timestamps(); $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); }); }
- 投稿日:2020-03-15T15:23:15+09:00
[db]skeemaというMySQL系データベースのDDL管理ツールを使ってみた
Go言語でDBのスキーマをうまく管理してくれるツール無いの?というところで試したツールの一つ。
skeema/skeema: Schema management CLI for MySQL
ザックリ言うと、RailsでいうActiveRecord::Schemaみたいなスキーマダンプを作ってくれるやつ。環境
- macOS Catalina
- go version 1.13.4
記事執筆時点で対応しているデータベース
MySQL系のプロダクトの模様。
- MySQL 5.5, 5.6, 5.7, 8.0
- Percona Server 5.5, 5.6, 5.7, 8.0
- MariaDB 10.1, 10.2, 10.3, 10.4
準備
go get -u github.com/skeema/skeema
使い方
現在のスキーマをダンプ
下記のコマンドを適宜編集して実行する。
skeema init -h my.db.hostname -u root -p -d schemas --schema dbnameすると
schemas
ディレクトリ以下にテーブルごとにDDLがファイルが出力される。
-d
で指定したディレクトリにダンプされる。
--schema
オプション無しの場合は、ユーザーが作ったすべてのデータベース毎のディレクトリが作られ、その中にそれぞれのデータベースにあるテーブル定義が出力される。
--schema
ありの場合は、指定ディレクトリの直下にファイルが出力される。
skeema init --help
で詳細なオプションを確認できる。
この時の接続情報は.skeema
ファイルに記録されている。スキーマを変更して適用
例えば以下のように変更してみる。
CREATE TABLE `applications` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `ios_bundle_name` varchar(255) DEFAULT NULL, `android_bundle_name` varchar(255) DEFAULT NULL, `created_at` datetime NOT NULL, `updated_at` datetime NOT NULL, `deleted_at` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;↓
CREATE TABLE `applications` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(256) NOT NULL, `ios_bundle_name` varchar(255) DEFAULT '', `android_bundle_name` varchar(255) DEFAULT NULL, `created_at` datetime, `updated_at` datetime NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `name` (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;これを適用してみる。
まず差分をチェックする。
skeema diff
で実際にどのようなSQL文が発行されるかを確認できる。
今回は列の削除が含まれるので、--allow-unsafe
オプションが必要。$ skeema diff -p --allow-unsafe : -- instance: localhost:/tmp/mysql.sock USE `testdb`; ALTER TABLE `applications` DROP COLUMN `deleted_at`, MODIFY COLUMN `name` varchar(256) NOT NULL, MODIFY COLUMN `ios_bundle_name` varchar(255) DEFAULT '', MODIFY COLUMN `created_at` datetime DEFAULT NULL, ADD UNIQUE KEY `name` (`name`);次に実際に適用してみる。
$ skeema push -p --allow-unsafe : -- instance: localhost:/tmp/mysql.sock USE `testdb`; ALTER TABLE `applications` DROP COLUMN `deleted_at`, MODIFY COLUMN `name` varchar(256) NOT NULL, MODIFY COLUMN `ios_bundle_name` varchar(255) DEFAULT '', MODIFY COLUMN `created_at` datetime DEFAULT NULL, ADD UNIQUE KEY `name` (`name`); 2020-03-15 14:44:46 [INFO] localhost:/tmp/mysql.sock testdb: push completeSequel Proなどで軽く確認すると、適用されている事が分かる。
ここでは記載していないが、テーブルの追加や削除にも対応している。
削除時には--allow-unsafe
が必要。スキーマの差分を反映する
直接本番で作業した、開発環境でテーブルをGUIで変更したなどの理由で差分をDDLに反映させたい場合などがあるだろう。
そういう場合にはskeema pull
を利用できる。$ skeema pull -p Enter password: 2020-03-15 14:59:13 [INFO] Updating /path/to/schemas to reflect localhost:/tmp/mysql.sock testdb 2020-03-15 14:59:13 [INFO] Wrote /path/to/schemas/applications.sql (425 bytes)フォーマット
skeema format -p
でSQL文の整形ができる。lint
skeema lint -p
でlintできる。こんな感じ。2020-03-15 14:40:52 [INFO] Linting /path/to/schemas 2020-03-15 14:40:53 [WARN] /path/to/schemas/applications.sql:2: Column id of table applications is an auto_increment column using data type int, which is not configured to be permitted. The following data types are listed in option allow-auto-inc: int unsigned, bigint unsigned. In general, auto_increment columns should be unsigned, since behavior of auto_increment is undefined with negative numbers. 2020-03-15 14:40:53 [WARN] Found 1 warningsGitHubにインストールして使えるCIサービスもある。現在ベータ版で無料。
環境を分ける
最初に生成されるのは
production
の設定だが、develop
やstaging
など環境を追加する事も可能。
残念な事に、データベース名(scheme)は共通となっており、本番と合わせる必要がある。$ skeema add-environment development -h localhost -u root -p 2020-03-15 15:01:46 [INFO] Added environment [development] to /path/to/schemas/.skeema環境を指定する際は一番最後に付ける。
skeema pull -p development
など。
お察しの通り、何も指定しない場合はproduction
になる。
どちらかと言うと本番の時に指定させて欲しいところだが…
- 投稿日:2020-03-15T15:23:15+09:00
[db]MySQL系データベースのDDL管理ツールskeemaを使ってみた
Go言語でDBのスキーマをうまく管理してくれるツール無いの?というところで試したツールの一つ。
skeema/skeema: Schema management CLI for MySQL
ザックリ言うと、RailsでいうActiveRecord::Schemaみたいなスキーマダンプを作ってくれるやつ。環境
- macOS Catalina
- go version 1.13.4
記事執筆時点で対応しているデータベース
MySQL系のプロダクトの模様。
- MySQL 5.5, 5.6, 5.7, 8.0
- Percona Server 5.5, 5.6, 5.7, 8.0
- MariaDB 10.1, 10.2, 10.3, 10.4
準備
go get -u github.com/skeema/skeema
使い方
現在のスキーマをダンプ
下記のコマンドを適宜編集して実行する。
skeema init -h my.db.hostname -u root -p -d schemas --schema dbnameすると
schemas
ディレクトリ以下にテーブルごとにDDLがファイルが出力される。
-d
で指定したディレクトリにダンプされる。
--schema
オプション無しの場合は、ユーザーが作ったすべてのデータベース毎のディレクトリが作られ、その中にそれぞれのデータベースにあるテーブル定義が出力される。
--schema
ありの場合は、指定ディレクトリの直下にファイルが出力される。
skeema init --help
で詳細なオプションを確認できる。
この時の接続情報は.skeema
ファイルに記録されている。スキーマを変更して適用
例えば以下のように変更してみる。
CREATE TABLE `applications` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `ios_bundle_name` varchar(255) DEFAULT NULL, `android_bundle_name` varchar(255) DEFAULT NULL, `created_at` datetime NOT NULL, `updated_at` datetime NOT NULL, `deleted_at` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;↓
CREATE TABLE `applications` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(256) NOT NULL, `ios_bundle_name` varchar(255) DEFAULT '', `android_bundle_name` varchar(255) DEFAULT NULL, `created_at` datetime, `updated_at` datetime NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `name` (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;これを適用してみる。
まず差分をチェックする。
skeema diff
で実際にどのようなSQL文が発行されるかを確認できる。
今回は列の削除が含まれるので、--allow-unsafe
オプションが必要。$ skeema diff -p --allow-unsafe : -- instance: localhost:/tmp/mysql.sock USE `testdb`; ALTER TABLE `applications` DROP COLUMN `deleted_at`, MODIFY COLUMN `name` varchar(256) NOT NULL, MODIFY COLUMN `ios_bundle_name` varchar(255) DEFAULT '', MODIFY COLUMN `created_at` datetime DEFAULT NULL, ADD UNIQUE KEY `name` (`name`);次に実際に適用してみる。
$ skeema push -p --allow-unsafe : -- instance: localhost:/tmp/mysql.sock USE `testdb`; ALTER TABLE `applications` DROP COLUMN `deleted_at`, MODIFY COLUMN `name` varchar(256) NOT NULL, MODIFY COLUMN `ios_bundle_name` varchar(255) DEFAULT '', MODIFY COLUMN `created_at` datetime DEFAULT NULL, ADD UNIQUE KEY `name` (`name`); 2020-03-15 14:44:46 [INFO] localhost:/tmp/mysql.sock testdb: push completeSequel Proなどで軽く確認すると、適用されている事が分かる。
ここでは記載していないが、テーブルの追加や削除にも対応している。
削除時には--allow-unsafe
が必要。スキーマの差分を反映する
直接本番で作業した、開発環境でテーブルをGUIで変更したなどの理由で差分をDDLに反映させたい場合などがあるだろう。
そういう場合にはskeema pull
を利用できる。$ skeema pull -p Enter password: 2020-03-15 14:59:13 [INFO] Updating /path/to/schemas to reflect localhost:/tmp/mysql.sock testdb 2020-03-15 14:59:13 [INFO] Wrote /path/to/schemas/applications.sql (425 bytes)フォーマット
skeema format -p
でSQL文の整形ができる。lint
skeema lint -p
でlintできる。こんな感じ。2020-03-15 14:40:52 [INFO] Linting /path/to/schemas 2020-03-15 14:40:53 [WARN] /path/to/schemas/applications.sql:2: Column id of table applications is an auto_increment column using data type int, which is not configured to be permitted. The following data types are listed in option allow-auto-inc: int unsigned, bigint unsigned. In general, auto_increment columns should be unsigned, since behavior of auto_increment is undefined with negative numbers. 2020-03-15 14:40:53 [WARN] Found 1 warningsGitHubにインストールして使えるCIサービスもある。現在ベータ版で無料。
環境を分ける
最初に生成されるのは
production
の設定だが、develop
やstaging
など環境を追加する事も可能。
残念な事に、データベース名(scheme)は共通となっており、本番と合わせる必要がある。$ skeema add-environment development -h localhost -u root -p 2020-03-15 15:01:46 [INFO] Added environment [development] to /path/to/schemas/.skeema環境を指定する際は一番最後に付ける。
skeema pull -p development
など。
お察しの通り、何も指定しない場合はproduction
になる。
どちらかと言うと本番の時に指定させて欲しいところだが…
- 投稿日:2020-03-15T12:17:22+09:00
MySQLでdatetime型の演算をする
以下のようなテーブルがある.
MariaDB [staging]> desc guests; +---------------+----------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +---------------+----------------------+------+-----+---------+----------------+ | id | smallint(5) unsigned | NO | PRI | NULL | auto_increment | | department_id | smallint(5) unsigned | YES | MUL | NULL | | | user_id | varchar(10) | YES | | NULL | | | comment | varchar(255) | YES | | NULL | | | entered_at | datetime | NO | | NULL | | | updated_at | datetime | NO | | NULL | | | exited_at | datetime | YES | | NULL | | +---------------+----------------------+------+-----+---------+----------------+ 7 rows in set (0.036 sec)現状では,JSTでdatetime型のカラムに記録されている.
MariaDB [staging]> select * from guests; +----+---------------+----------+-----------------------------+---------------------+---------------------+---------------------+ | id | department_id | user_id | comment | entered_at | updated_at | exited_at | +----+---------------+----------+-----------------------------+---------------------+---------------------+---------------------+ | 3 | 1 | C0117123 | これはテストです〜 | 2019-08-08 02:41:20 | 2019-08-08 20:41:20 | 2020-03-02 23:00:09 |ここでは
entered_at
カラムの時刻をUTCへ修正する.UPDATE guests SET entered_at=entered_at - INTERVAL 9 HOUR修正されたことが確認できる.
MariaDB [staging]> select * from guests; +----+---------------+----------+-----------------------------+---------------------+---------------------+---------------------+ | id | department_id | user_id | comment | entered_at | updated_at | exited_at | +----+---------------+----------+-----------------------------+---------------------+---------------------+---------------------+ | 3 | 1 | C0117123 | これはテストです〜 | 2019-08-07 17:41:20 | 2019-08-08 20:41:20 | 2020-03-02 23:00:09 |
- 投稿日:2020-03-15T03:54:25+09:00
【Go】【xorm/reverse】MySQLのINT UNSIGNEDに対応する!
はいどうも~
新人のプルリクに、選択肢を2つ与えつつ「自分のチカラで考えてみそ」とレビューしたら、なぜか新米部長から横レスで「じゃあお前が決めろよ、ちなみに選択肢Bは俺的に無しだから」と来て、何が琴線?に触れたのか不明ですがとりまLGTMで済ませた昨今、いかがお過ごしでしょうか
今回は、↓でご紹介した
xorm/reverse
を改造したお話です。
- ありの~ままの~DBスキーマを、go言語ソースコードに自動変換【xorm/reverse】
https://qiita.com/yagrush/items/cc60166d85befbcbf3d6何を変えたの?
MySQL DBリバース
↓
Go言語のstructコード
↓
INT UNSIGNEDカラムが、ただのint型structフィールドになってしまう
↓
uint型になってほしい
↓
改造変更点
まずは、最新版
xorm/reverse
とxorm/xorm
の帳尻合わせ
xorm/reverse
はxorm/xorm
(xorm本体)をインポートしていて大部分依存しているのですが、xorm/xorm
のバージョンが0.81
→0.82
と上がっていたので「どうせなら最新版に合わすか」と軽い気持ちでgo.modrequire ( ・ ・ ・ xorm.io/xorm latest )と
latest
で引っ張りなおしたら、結構影響が…
このver0.01の更新でリファクタリングがあったようです。ので、まずは
xorm/reverse
を最新xorm/xorm
に合わせる修正をします。※ご注意: giteaリポジトリ上のルートは
xorm
ですが、go package名は公式サイトドメインに沿ってxorm.io
になっているようです。
cmd/reverse.go
,language/golang.go
,language/language.go
Table, Column構造体がパッケージ
core
からschemas
に移動していたので、
import "xorm.io/xorm/schemas"
を追加core.Table
,core.Column
→schemas.Table
,schemas.Column
に修正これで、最新版
xorm/xorm
をインポートしたxorm/reverse
がビルド可能になりました。リバースロジックに手を入れ…
そう単純にはいかないようです…
処理を追跡すると、
language/golang.go
のtypestring()
で呼ばれているschemas.SQLType2Type()
の中で変換が行われているようです。
これってxorm/xorm
本体側のfuncですよね……分かりました、やりましょう!
xorm/xorm
も改造しちゃいます!
xorm/xorm
最新版をgit clone
早速
xorm/xorm
をgit clone
してきます。
ディレクトリはxorm.io/reverse
と同じ階層になるようにします。$ cd ../ $ git clone https://gitea.com/xorm/xorm.git $ ls xorm/ reverse/手元の
xorm/reverse
が、同じく手元のxorm/xorm
を参照するように変更※Go Modules方式でビルドしている前提です。
reverse/go.mod
に↓を追記します。go.modreplace xorm.io/xorm => ../xormこれで
xorm.io/xorm
パッケージのライブラリだけ、ネット上に公開されているものではなく手元のディスク内のものを参照するようになります。今度こそ、リバースロジックに手を入れる!
えっと、目論見を付けたのは
schemas.Type2SQLType()
でしたね。
このfuncは…xorm/schemas/type.go
にありますね。
早速手を入れていきましょう。type.go// default sql type change to go types func SQLType2Type(st SQLType) reflect.Type { name := strings.ToUpper(st.Name) switch name { case Bit, TinyInt, SmallInt, MediumInt, Int, Integer, Serial: return reflect.TypeOf(1) case BigInt, BigSerial: return reflect.TypeOf(int64(1)) …ここに
case UInt:
を足せばいいのかなと思いますが、きっとそれだけでは済まないですね…
でもこれはこれで必要なので足します。type.gofunc SQLType2Type(st SQLType) reflect.Type { name := strings.ToUpper(st.Name) switch name { … case UInt: // ← return reflect.TypeOf(uint(1)) // ← …定数宣言部が冒頭にあるのでそれも足します。
type.govar ( … UInt = "INT UNSIGNED" // ← … SqlTypes = map[string]int{ … UInt: NUMERIC_TYPE, // ← … ) …さて、GoLandのデバッグ実行を使ってみましたが
INT UNSIGNED
カラムを持つテーブルを食わせてもSQLType2Type
のパラメータst.Name
として渡ってくる時点でUNSIGNED
が削られてしまっています……ここはひとつ、ちゃんとイチから辿ってみますか。
reverse/cmd/reverse.go
Reverse()
>runreverse()
>xorm/engine.go
DBMetas()
>loadTableInfo()
>
xorm/dialects/dialect.go
GetColumns()
>xorm/dialects/mysql.go
GetColumns()
お、ここにMySQLのカラム宣言部を解析する処理がありました。
mysql.gofunc (db *mysql) GetColumns(ctx context.Context, tableName string) ([]string, map[string]*schemas.Column, error) { … cts := strings.Split(colType, "(") colName := cts[0] colType = strings.ToUpper(colTypeBase) …ここで、例えば
INT(10) UNIQUE UNSIGNED NOT NULL
といったカラム宣言からINT
を切り出しています。
これだと確かにUNSIGNED
が切り捨てられちゃいますね。
なのでINT(X) ... UNSIGNED ...
からINT UNSIGNED
として拾い上げるよう修正します。mysql.gofunc (db *mysql) GetColumns(ctx context.Context, tableName string) ([]string, map[string]*schemas.Column, error) { … cts := strings.Split(colType, "(") //colName := cts[0] var colTypeBase string group := regexp.MustCompile(`(?i)([a-zA-Z]+).*(\sUNSIGNED?).*`).FindSubmatch([]byte(colType)) if group == nil { colTypeBase = cts[0] } else { for i, g := range group { if i == 0 { continue } colTypeBase += string(g) } } colType = strings.ToUpper(colTypeBase) …ここ、実はMySQL側のバージョンによって罠がありました。
MySQL5.xだと
INT UNSIGNED ...
とカラム宣言しても、テーブル作成時、自動的にINT(10) UNSIGNED ...
と、(10)
が付けられてしまうので↑この修正が必要です。(MySQL8.xだとこの現象は発生しません。)いずれにしろ、↑のようにしておけば大丈夫です。
実行
では
xorm/reverse
を実行してみましょう。$ cd reverse $ go run main.go -f example/my-mysql.yml※設定ファイル
my-mysql.yml
の内容は、前回記事 https://qiita.com/yagrush/items/cc60166d85befbcbf3d6 をご参照下さい。すると、例えば↓のテーブルが
CREATE TABLE `users` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `name` varchar(32) COLLATE utf8_unicode_ci NOT NULL, `created_at` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`) );↓
type User struct { Id uint Name string CreatedAt *time.Time }
Id uint
になってますねおわり
ということで、以下を修正することで
INT UNSIGNED
カラムに対応することができました。
xorm/reverse
cmd/reverse.go
language/golang.go
language/language.go
xorm/xorm
schemas/type.go
dialects/mysql.go
実際には、この修正で
BIGINT UNSIGNED
などもUNSIGNED
付きで拾ってしまうようになるので 併せて修正が必要なのですが、ほぼコピペで済むので。
記事が冗長になってしまうので、ここでは割愛します。それではまた!
- 投稿日:2020-03-15T01:32:47+09:00
golang,docker,mysqlの環境をherokuにデプロイする
はじめに
言語: golang
コンテナ: docker-compose
RDB: mysql
ORM: gorm
マイグレーション: migrateな環境をherokuにデプロイするまで結構ハマったので残す。
コード
https://github.com/pokotyan/study-slack
実行したherokuのコマンド一覧
$ cd /hoge/huga # アプリケーションのコードがあるところに移動 $ heroku container:login # ログイン $ heroku create -a app_name # herokuアプリの作成 $ heroku git:remote -a app_name # herokuリポジトリをgit登録 $ heroku addons:add cleardb:ignite # mysqlのアドオンを追加 $ heroku config # CLEARDB_DATABASE_URLが登録されていることを確認 $ heroku config:set DATABASE_URL="<ユーザー名>:<password>@tcp(<ホスト名>:3306)/<DB名>?parseTime=true" # CLEARDB_DATABASE_URLの値を元にsql.Open()に渡す用の文字列に整形 $ heroku config # DATABASE_URLが登録されていることを確認 $ heroku stack:set container # heroku.ymlを使う時はこれがいるぽい $ git push heroku master # リリースheroku.yml
heroku.ymlを使うとCI/CDみたいなことができる。アプリのルートディレクトリに置いて使う。
buildにはdockerのビルドの指定ができる。
releaseにはリリースする際に挟みたい処理があれば書くことができる。ここではマイグレーションの実行をしている。
runはプロセスタイプ1ごとに実行するコマンドを指定する。./heroku.ymlbuild: docker: web: Dockerfile worker: dockerfile: Dockerfile target: builder release: image: worker command: - make up_migrate_prod run: web: /mainDockerfile
上述のheroku.ymlが参照するDockerfile。アプリのルートディレクトリに置く。
いくつかポイントがある。./DockerfileFROM golang:alpine as builder RUN apk update \ && apk add --no-cache git curl make gcc g++ \ && go get github.com/oxequa/realize WORKDIR /app COPY go.mod . COPY go.sum . RUN go mod download COPY . . RUN GOOS=linux GOARCH=amd64 go build -o /main FROM alpine:3.9 COPY --from=builder /main . ENV PORT=${PORT} ENTRYPOINT ["/main"]ライブラリのインストール
./DockerfileRUN apk update \ && apk add --no-cache git curl make gcc g++ \ && go get github.com/oxequa/realizerealizeは開発時のホットリロードのため。
make、gcc、g++はheroku.ymlのreleaseフェーズにてmakeコマンドでマイグレーションを流せるようにするため
curlはherokuのUI上でログを残すため(※)。※ curlを入れていないとこんな感じで何も表示されない。リリースが途中で死んでもなんで落ちたかが追えなくなるので入れておいた方がいいと思う。ログを出すためにcurlが必要なことは公式にも記載されている。
ビルド
builderのイメージはheroku.ymlでイメージのビルドをする際に使ったり、マイグレーションを実行する時のイメージとして利用している。
./DockerfileFROM golang:alpine as builder./heroku.ymlbuild: docker: web: Dockerfile worker: dockerfile: Dockerfile target: builder # builderのイメージをbuildする際に使う release: image: worker # 上記のworkerのイメージをreleaseフェーズでも使う command: - make up_migrate_prod # マイグレーションを流すアプリの実行
RUN GOOS=linux GOARCH=amd64 go build -o /main
でビルドしたファイルを実行する./DockerfileFROM alpine:3.9 COPY --from=builder /main . ENV PORT=${PORT} ENTRYPOINT ["/main"]./heroku.ymlrun: web: /maindocker-compose.yml
ローカルで開発する時のみに利用するdocker-compose.yml。
realizeを使ってホットリロードするようにしている。
また、mysqlのコンテナが立ち上がる際にdocker-entrypoint-initdb.d
を利用してCREATE DATABASE
をするようにしている。herokuの本番環境ではdatabaseは
heroku addons:add cleardb:ignite
で用意されたものを利用する。
そのため、本番環境ではこのdocker-compose.ymlは利用しない。dockers/docker-compose.ymlversion: "3.5" services: mysql: container_name: push_study_db image: mysql:5.7.22 volumes: - ./mysql/:/docker-entrypoint-initdb.d/ - ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf environment: - MYSQL_ALLOW_EMPTY_PASSWORD=yes ports: - 4306:3306 app: build: context: .. target: builder volumes: - ../:/app command: realize start --server environment: - API_VERSION=development ports: - 7777:7777 depends_on: - mysql起動するポート
herokuはアプリが起動するたびにポートが変わるらしい。$PORTを指定して起動するようにする。
router.Run(":" + os.Getenv("PORT"))CLEARDB_DATABASE_URL
mysqlのアドオンを追加するとCLEARDB_DATABASE_URLという環境変数が自動で設定される。
heroku.ymlのreleaseフェーズで流れるようにしたマイグレーションだが、そのコードでは以下のようにしてdbと接続していた。dbURL := os.Getenv("CLEARDB_DATABASE_URL") db, _ := sql.Open("mysql", dbURL)リリースを実行すると
invalid memory address or nil pointer dereference
のエラーが出る。結果として、herokuが自動で作成してくれるCLEARDB_DATABASE_URLの書式をsql.Openが求めている書式に変換する必要があった。こちらの記事を参考にさせていただきました。
冒頭のherokuのコマンド一覧のところでも記載しているが、"<ユーザー名>:<password>@tcp(<ホスト名>:3306)/<DB名>?parseTime=true"
の形にしてあげる必要があった。最後に
herokuのリリース方法、色々ありすぎてまとまった情報を見つけるのが難しい。
ここで使ってるのはwebのプロセスタイプ。herokuが動くコンテナであるdynoのプロセスタイプは他にworker、one-offの計3つのプロセスタイプがあるぽい ↩