docker-composeで Golang、 Mysqlの環境構築

docker-composeでGo、Mysqlの環境構築をしました。

####ディレクトリ構成

```
sample-docker-compose/
├── docker
│   ├── golang
│   │   └── Dockerfile
│   └── mysql
│       ├── Dockerfile
│       ├── init
│       │   └── create_db_table.sql
│       └── my.conf
├── docker-compose.yml
├── main.go
└── start_app.sh

```

####Golangのdockerfile

```
FROM golang:1.8
RUN apt-get update -qq && \
    apt-get install -y mysql-client vim

WORKDIR /go/src/sample_docker_compose

ADD . .
RUN go build

```

####mysqlのdockerfile

```
FROM mysql:5.7
```

```docker-compose.yml
# docker-composeのバージョン
version: '3'
# services配下に各コンテナの情報を記載する
services:
  # ここからはmysqlのコンテナに関する情報
  # "mysql"はサービス名(任意につけてok)
  mysql:
    # コンテナに名前をつけることもできる
    container_name: mysql
    # Dockerfileのあるディレクトリのパスを指定する
    build:
      context: .
      dockerfile: ./docker/mysql/Dockerfile
    # mysqlのホスト名を決める
    hostname: mysql
    # 外部に公開するポートを指定する
    # これがないと外部からアクセスできない
    ports:
      - "3306:3306"
    # mysqlの設定
    environment:
      MYSQL_USER: root
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: password
    # docker-compose run実行時に実行される
    # オプションは日本語文の字化けに対するおまじない
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci --skip-character-set-client-handshake
    # パスをボリュームとしてマウント
    # :の左側がホストディレクトリ、:の右側がコンテナ上のディレクトリ
    volumes:
      - "db-data:/var/lib/mysql"
      # 初期設定を読み込む
      - "./docker/mysql/my.conf:/etc/mysql/my.conf"
      # MySQL起動時にDBを作成する
      - "./docker/mysql/init/:/docker-entrypoint-initdb.d"
  # ここからはGolangのアプリケーションに対する情報
  sample_docker_compose:
    # mysqlのコンテナとリンク付けする
    # mysqlコンテナを起動してからsample_docker_composeを起動してくれるようになる
    links:
      - mysql
    build:
      context: .
      dockerfile: ./docker/golang/Dockerfile
    container_name: sample_docker_compose
    ports:
      - "8080:8080"
    volumes:
      - .:/go/src/sample_docker_compose
    # docker-compose run実行時に実行される
    command: sh ./start_app.sh
# トップレベルでvolumesを定義すると、各サービスからボリュームを参照できる
volumes:
  db-data:
    driver: local      
      
```

```main.go
package main

import(
    "fmt"
    "net/http"
)

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, from Docker container!")
}
```

```my.conf
[client]
port            = 3306
default-character-set=utf8mb4

[mysqld_safe]
nice            = 0

[mysqld]
skip-host-cache
skip-name-resolve
user            = mysql
port            = 3306
basedir         = /usr
datadir         = /var/lib/mysql
tmpdir          = /tmp
bind-address    = 192.168.0.88
innodb_data_home_dir            = ibdata
innodb_log_group_home_dir       = iblog
lc-messages-dir = /usr/share/mysql
character-set-server=utf8mb4
log-error      = /var/log/mysql/error.log
symbolic-links = 0
innodb_force_recovery = 3
!includedir /etc/mysql/conf.d/

[mysqldump]
default-character-set=utf8

```

```create_db_table.sql
SET CHAESET UTF8;
DROP DATABASE IF EXIST sample_docker_compose;
CREATE DATABASE IF NOT EXISTS sample_docker_compose DEFAULT CHARACTER SET utf8;

```

```start_app.sh
# !/bin/bash

# MySQLサーバーが起動するまでmain.goを実行せずにループで待機する
until mysqladmin ping -h mysql --silent; do
  echo 'waiting for mysqld to be connectable...'
  sleep 2
done

echo "app is starting...!"
exec go run main.go

```

####疑問
dockerfileやdocker-compose.ymlでタブでネストするとエラーが出てしまうのですが、
ネストの際のスペースなどにも決まりがあるのでしょうか...?
もっと勉強いたします...!

###参考資料
[@yu-crocoさんQiita 今日から始めるDocker【docker-composeを使ってGo & Mysqlをよしなに起動しよう編】](https://qiita.com/yu-croco/items/0c0d5083298f7db9e1bb)