【Go】Go言語Web開発プロジェクト Part1.5 - Goが入ったコンテナをdocker-composeで構築するまで -

## 前回のおさらい

前回はGo言語によるWeb開発を進めるための環境構築を行いました。今回はGoコンテナの構築を行っていきます。つまりはまた環境構築です汗

## gooseによるマイグレーション

前回の記事の最後にgom経由でインストールしたマイグレーションツールgooseを利用して実際にマイグレーションを行っていきたいと思います。goose経由でDBアクセスを確認するためにまずは設定ファイルを書きます。
サンプルファイルがパッケージインストールを行ったsrc配下のディレクトリに存在しますので、このファイルをコピーしておきます。

```bash
% mkdir db
% cd db/
% cp $GOPATH/bitbucket.org/liamstask/goose/db-sample/dbconf.yml .
```

```go:db/dbconf.yml
test:
    driver: postgres
    open: user=liam dbname=tester sslmode=disable

development:
    driver: postgres
    open: user=liam dbname=tester sslmode=disable

production:
    driver: postgres
    open: user=liam dbname=tester sslmode=verify-full

customimport:
    driver: customdriver
    open: customdriver open
    import: github.com/custom/driver
    dialect: mysql

environment_variable_config:
    driver: $DB_DRIVER
    open: $DATABASE_URL
```

ひとまずdevelopmentだけ書き換えてみましょう。ここはDockerでサーバーを構築するために各パラメーターは環境変数で指定できるようにしておきます。

```yaml:/dbconf.yml
development:
    driver: postgres
    open: host=$DAIRY_REPORT_DEVELOPMENT_HOST user=$DAIRY_REPORT_DEVELOPMENT_USERNAME password=$DAIRY_REPORT_DEVELOPMENT_PASSWORD dbname=$DAIRY_REPORT_DEVELOPMENT_DATABASE sslmode=disable

```

ここで一旦GoのWebサーバーがdocker-composeで構築できるか試してみましょう。

## Docker化の事前準備

### Gomfile.lockを生成しておく

```bash
% gom lock
Gomfile.lock is generated

% cat Gomfile.lock  
gom 'bitbucket.org/liamstask/goose/cmd/goose', :commit => '8488cc47d90c8a502b1c41a462a6d9cc8ee0a895'
```

### docker-compose.ymlの設定

dockerではひとまずWebサーバー用のGoが入ったコンテナとPostgreSQLサーバーが入ったコンテナを構築するようにしておきます。

```yaml:docker-compose.yml
version: '3'
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    command: go run main.go
    links: [db]
    environment:
    - DAIRY_REPORT_DEVELOPMENT_HOST=db
    - DAIRY_REPORT_DEVELOPMENT_DATABASE=dairy_report_development
    - DAIRY_REPORT_DEVELOPMENT_USERNAME=dairy_report
    - DAIRY_REPORT_DEVELOPMENT_PASSWORD=dairy_report
    ports:
    - 8080:8080
  db:
    image: postgres:latest
    environment:
    - POSTGRES_USER=dairy_report
    - POSTGRES_PASSWORD=dairy_report
    ports:
    - 5432:5432
```

### Dockerfile

次にGoコンテナイメージビルド準備のための設定記述を書きます。Goのテストコード駆動でもしかしたらWebDriverとか今後必要かなとか思いましたが、ひとまず必要な設定のみ入れておきます。前回direnvを利用し、プロジェクト毎の設定を切り分けていたのでそれをそのまま使ってあげましょう。

```docker:Dockerfile
FROM golang:1.11.0

RUN apt update

# PostgreSQLのClientをインストール
RUN apt install -y postgresql-client

# direnvをインストール
RUN apt install -y direnv
RUN echo 'eval "$(direnv hook bash)"' >> ~/.bashrc

RUN mkdir -p dairy_report/db
WORKDIR /dairy_report
ADD .envrc .envrc
RUN direnv allow
ADD Gomfile Gomfile
ADD Gomfile.lock Gomfile.lock
ADD db/dbconf.yml db/dbconf.yml
# gomだけgo getで取得
RUN go get github.com/mattn/gom
RUN gom install

ADD . /dairy_report
```

この時、gom installで導入したパッケージは.dockerignoreでvendor/ディレクトリの追加を除外するのがミソです(当初vendorディレクトリも追加していたのですが、プラットフォームの違いで実行できませんでした)。

```docker:.dockerignore
vendor/
```

これによりdocker-composeでGoコンテナとDBコンテナが立ち上がるようになりました。

```bash
% docker-compose build
% docker-compose up -d
Starting dairy_report_db_1 ... done
Starting dairy_report_web_1 ... done
% docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
5fbdee977b74        dairy_report_web    "go run main.go"         24 hours ago        Up 2 seconds        0.0.0.0:8080->8080/tcp   dairy_report_web_1
87b22f7b7cdd        postgres:latest     "docker-entrypoint.s…"   24 hours ago        Up 3 seconds        0.0.0.0:5432->5432/tcp   dairy_report_db_1
```

goose statusによりDB接続できているか確認ができます。

```bash
% goose status
2018/09/29 01:54:44 pq: database "dairy_report_development" does not exist
```

まだ`dairy_report_development`が作成されていないため、SQLコマンドで作成してあげましょう(gooseはマイグレーションツールのみでDBの作成自体はできませんでした)。

```bash
# psql -hdb -Udairy_report
Password for user dairy_report: 
dairy_report=# CREATE DATABASE dairy_report_development;
CREATE DATABASE
t# goose status
goose: status for environment 'development'
    Applied At                  Migration
    =======================================
```

## まとめ

という訳で今回はまた環境構築の話でした。コードをゴリゴリ書こうと思ってて思いの外環境構築に時間を使うのはいけませんね、、、とは言え、これも大事なので予定とは大分違いましたが(そのためPart1.5にした)ここに残しておきます。
次回からちゃんとコードを書いていきます汗

## 参考文献

今回はなし

## シリーズ

[Part1](https://qiita.com/himrock922/items/1d70686aabaac49b54fd) ← [Part1.5](https://qiita.com/himrock922/items/b0a1173be4bf078db023) → [Part2](https://qiita.com/himrock922/items/299ddde2ca3417ae6895)