環境
OS : OS X El Capitan
Docker : 17.03.0-ce
docker-compose : 2
golang : 1.8
revel : 0.13.1
Mysql : 5.7.17
動機
golangでwebアプリケーションを開発しようと思ったときに,docker-composeの練習もやりたいと思ったのでやってみた.
https://github.com/youtangai/RevelOnDocker
ここにあるのでforkすれば使えます.
フォルダ構成
revel_on_docker/
├Dockerfile
├docker-compose.yml
└myapp/
なので
cd
mkdir revel_on_docker
cd revel_on_docker
でフォルダを作成しカレントディレクトリの変更
Dockerfile
#golang v1.8が準備されているimageを利用
FROM golang:1.8.0
#$GOPATHに/go/srcを追加.この後srcの下にアプリケーションフォルダを作成する為
ENV GOPATH $GOPATH:/go/src
#とりあえず更新
RUN apt-get update && \
apt-get upgrade -y
#revel,revel-cli,gorm,go-sql-driverのインストール
#revelにはORMがないので
RUN go get github.com/revel/revel && \
go get github.com/revel/cmd/revel && \
go get github.com/jinzhu/gorm && \
go get github.com/go-sql-driver/mysql
#アプリケーション(myapp)をマウントするためのディレクトリを作成
RUN mkdir /go/src/myapp
#revelはポート9000で実行されるのでポート9000の開放
EXPOSE 9000
docker-compose.yml
version: '2' #docker-composeのバージョンを指定
services:
db:
image: mysql:5.7 #mysql5.7が準備されているimageを指定
environment:
- MYSQL_ROOT_PASSWORD=secret #rootのパスワード
- MYSQL_DATABASE=revel #revelデータベースの作成
- MYSQL_USER=revel #revelユーザの作成
- MYSQL_PASSWORD=secret #revelユーザのパスワード
web:
build: . #Dockerfileをビルド
command: revel run myapp #docker-compose up の際にアプリケーション実行
volumes:
- ./myapp:/go/src/myapp #作成したフォルダにアプリケーションをマウント
ports:
- 9000:9000 #ポート9000番の開放
depends_on:
- db #dbとつなげる
myappの作成
revel new myapp
を実行すると自分の環境の$GOPATH/src以下に myappフォルダが作成されるので.
cp -r /path/to/go/src/myapp .
を実行しrevel_on_dockerにmyappをコピー
Mysql接続設定
DBの接続情報をmyapp/conf/app.confの[dev]セクションに記述する
[dev]
・・・省略・・・
#connection string for mysql
db.user = revel
db.password = secret
db.host = db
db.port = 3306
db.name = revel
db.protocol = tcp
次にmyapp/appの下にmodelsフォルダを作成.
modelsの下に接続するための処理を記述
package models
import (
"github.com/revel/revel"
"github.com/jinzhu/gorm"
"strings"
"time"
"fmt"
_"github.com/go-sql-driver/mysql"
)
var DB **gorm.DB
func InitDB() {
db, err := gorm.Open("mysql", getConnectionString())
if err != nil {
revel.ERROR.Println("FATAL", err)
panic(err)
}
db.DB()
DB = &db
}
type Model struct {
gorm.Model
ID uint `gorm:"primary_key"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
}
type Validator interface {
IsSatisfied(interface{}) bool
DefaultMessage() string
}
func getParamString(param string, defaultValue string) string {
p, found := revel.Config.String(param)
if !found {
if defaultValue == "" {
revel.ERROR.Fatal("Cound not find parameter: " + param)
} else {
return defaultValue
}
}
return p
}
func getConnectionString() string {
host := getParamString("db.host", "")
port := getParamString("db.port", "3306")
user := getParamString("db.user", "")
pass := getParamString("db.password", "")
dbname := getParamString("db.name", "")
protocol := getParamString("db.protocol", "tcp")
dbargs := getParamString("dbargs", " ")
timezone := getParamString("db.timezone", "parseTime=true&loc=Asia%2FTokyo")
if strings.Trim(dbargs, " ") != "" {
dbargs = "?" + dbargs
} else {
dbargs = ""
}
return fmt.Sprintf("%s:%s@%s([%s]:%s)/%s%s?%s", user, pass, protocol, host, port, dbname, dbargs, timezone)
}
InitDBが初期化処理なので,InitDBがアプリケーション実行時に実行されるようにする
func init() {
/*省略*/
revel.OnAppStart(models.InitDB) // init database
}
試す
revel_on_docker内で
docker-compose up
を実行し,ブラウザで localhost:9000にアクセスして
It worksと表示されれば成功です.
参考
http://qiita.com/sawadashota/items/8059ecf0415985b12a56
http://qiita.com/puttyo_bubu/items/cc320148ce69792619d3