Dockerを使ってPostgreSQL+Goの開発環境を作ってみた

# はじめに
GoからPostgreSQLに接続する部分がよくわかってなかったので、自分でDocker環境作って試してみた。

# 参考
ここを大いに参考にさせてもらった。
[Go PostgreSQLにつないでみる - Qiita](https://qiita.com/hiro9/items/e6e41ec822a7077c3568)
[Docker で作る postgres 環境 | Crudzoo](https://crudzoo.com/blog/docker-postgres)

# Docker
ポイントはnetworks部分を同じにしてるところ。

## ネットワークの準備

```
# docker network create postgres-test-network
# docker network ls
NETWORK ID          NAME                    DRIVER              SCOPE
xxxxxxxxxxxx        postgres-test-network   bridge              local
```


## PostgreSQL
こんな感じ。
`POSTGRES_HOST_AUTH_METHOD: true`は推奨してないって言われたけど、ローカルのお試し環境だから無視した。

```dockerfile:Dockerfile
FROM postgres:11-alpine
ENV LANG ja_JP.utf8
```

```yml:docker-compose.yml
version: '3'
services:
  db:
    build: .
    tty: true
    ports:
      - 5434:5432
    environment:
      POSTGRES_USER: root
      POSTGRES_HOST_AUTH_METHOD: trust
networks:
  default:
    external:
      name: postgres-test-network
```

これで立ち上げる

```
docker-compose up -d
```

## Go
```dockerfile:Dockerfile
FROM golang:latest
RUN mkdir /go/src/work
WORKDIR /go/src/work
ADD . /go/src/work
```

```yml:docker-compose.yml
version: '3'
services:
  app:
    build: .
    tty: true
    volumes:
      - .:/go/src/work
networks:
  default:
    external:
      name: postgres-test-network

```

これで立ち上げる

```
docker-compose up -d
```

# アクセス部分
Goの方のコンテナの中では、これを実行する。

ここをほぼほぼコピペさせてもらった。
[Go PostgreSQLにつないでみる - Qiita](https://qiita.com/hiro9/items/e6e41ec822a7077c3568)

```go:main.go
package main

import (
	"database/sql"
	"fmt"

	_ "github.com/lib/pq"
)

type EMPLOYEE struct {
    ID     string
    NUMBER string
}

func main() {
	db, err := sql.Open("postgres", "host=db port=5432 user=root sslmode=disable")
	defer db.Close()

	if err != nil {
		fmt.Println(err)
	}

    if _, err := db.Exec("CREATE TABLE employee (emp_id serial PRIMARY KEY, emp_number INTEGER);"); err != nil {
		fmt.Println(err)
	}

    // INSERT
    var empID string
    id := 4
    number := 4445
    err = db.QueryRow("INSERT INTO employee (emp_id, emp_number) VALUES($1,$2) RETURNING emp_id", id, number).Scan(&empID)

    if err != nil {
        fmt.Println(err)
    }

    fmt.Println(empID)

    // SELECT
    rows, err := db.Query("SELECT * FROM employee")

    if err != nil {
        fmt.Println(err)
    }

    var es []EMPLOYEE
    for rows.Next() {
        var e EMPLOYEE
        rows.Scan(&e.ID, &e.NUMBER)
        es = append(es, e)
    }
    fmt.Printf("%v", es)
}

```

`lib/pq`が入ってなかったので、`go get`した。ドライバーらしい。

```
go get github.com/lib/pq
```

いろいろ試してるとき、ネットワークつながらないって何回か言われたので、pingして確認した。
Dockerがうまいこと、DNSサーバーたてて`compose`にかいた`services`の名前で登録してくれるらしい。

```
# ping db
PING db (172.20.0.3) 56(84) bytes of data.
64 bytes from work2_postgres_db_1.postgres-test-network (172.20.0.3): icmp_seq=1 ttl=64 time=0.258 ms
```

これで。実行したら、それっぽく動いた。

```
go run main.go
```


# Posticoで確認
一応、DBの中身もGUIツールで確認した。良い感じ。
[Postico – a modern PostgreSQL client for the Mac](https://eggerapps.at/postico/)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184221/588c6451-9f84-cf84-b16d-990aff903b38.png)

![Screen Shot 2020-12-07 at 8.41.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184221/a2248882-6a79-1bbb-70c4-4673c392ba96.png)

# おわりに
ローカルでに動く環境作れたので、いろいろ試してみたい。