Docker x Golang x PostgreSQL で環境構築

# 概要

現場でGo言語の使用する予定があるのでDockerを使用して環境構築をしてみました。
ディレクトリ構成などはブログ記事など参考にしました。
（書籍なども読んでいってデファクトを見つけていきます。）

ソースコードだけ見たいという方は[こちら](https://github.com/suzu12/docker-go-postgresql-sampleapp)から見ることができます。

# 環境

- go 19.1
- PostgreSQL 15.1
- macOS Monterey version12.6

# 対象読者

- docker x Go x PostgreSQL の環境で簡単に動かしてみたい方
- dockerでの環境構築を試そうとされている方

# 目次

- [概要](#概要)
- [環境](#環境)
- [対象読者](#対象読者)
- [目次](#目次) 
- [ディレクトリ構成](#ディレクトリ構成)
- [Docker](#docker)
- [cmd](#cmd)
- [sampleプログラム](#sample-プログラム)
- [まとめ](#まとめ)
- [参考文献](#参考文献)

# ディレクトリ構成

```yaml:
.
├── app
│　　　　　　├──　database
│　　　　　　│   └── init
│   │      └── init_database.sql
│   ├── .env
│　　　　　　└──　main.go
├── build
│   └── dockerfiles
│        ├── app
│        │    └── Dockerfile
│        └── postgresql
│             └── Dockerfile
├── .env
├── .env.example
├── .gitignore
├── docker-compose.yml
└── README.md
```

# Docker

以下のファイルを用意し `cmd` に進んでください。

- docker-compose.yml

```yaml:docker-compose.yml
version: '3.8'

services:
  # golang
  app:
    container_name: ${APP_CONTAINER_NAME}
    build: # ビルドに使うDockerファイルのパス
      context: .
      dockerfile: ./build/dockerfiles/app/Dockerfile
    volumes: # マウント
      - ./app:/usr/local/go/src/sample_app/app
      - .env:/usr/local/go/src/sample_app/app/.env
    tty: true # コンテナの永続化
    depends_on:
      - db
    ports:
      - ${APP_PORT}:3000
  # posttgresql
  db:
    container_name: ${DB_HOST}
    build:
      context: .
      dockerfile: ./build/dockerfiles/postgresql/Dockerfile
    environment:
      - POSTGRES_DB=${DB_DATABASE}
      - POSTGRES_USER=${DB_USER}
      - POSTGRES_PASSWORD=${DB_PASSWORD}
    volumes:
      - db-store:/var/lib/postgresql/data
      - ./app/database/init:/docker-entrypoint-initdb.d # DBを初期化
    ports:
      - ${DB_PORT}:5432

volumes:
  db-store:

```

- Dockerfile(Go)

```dockerfile:build/dockerfiles/app/Dockerfile
FROM golang:1.19.1-alpine

RUN mkdir -p /usr/local/go/src/sample_app/app

WORKDIR /usr/local/go/src/sample_app/app

RUN apk update && apk add git
```


- Dockerfile(PostgreSQL)

```dockerfile:build/dockerfiles/postgresql/Dockerfile
FROM postgres:15.1

RUN localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8
ENV LANG ja_JP.utf8
```

- database

database初期化

ここでは、`sample_app` というデータベース名でデータベースの作成をするようにしています。


```sql:database/init/init_database.sql
CREATE DATABASE IF NOT EXISTS sample_app;
```

- .env

.env.example の内容を .env にコピーし使用してください。
あくまで sample なのでお好きな設定でご使用ください。

```config:.env
# DBコンテナ名
DB_HOST=sample_app_postgresql

# init時のdatabase
DB_DATABASE=sample_app

# DB情報
DB_USER=postgres
DB_PASSWORD=postgres
DB_PORT=5432

# app コンテナ
APP_CONTAINER_NAME=sample_app_backend
APP_PORT=30000
```

# cmd

- build してコンテナ起動

```bash:bash
docker-compose up -d --build
```

- app コンテナにアクセス

```:bash
docker-compose exec app sh
```

- db コンテナにアクセス

```:bash
docker-compose exec db bash
```

# sample プログラム

main.go にサンプルでプログラミングし、きちんと動作するかテスト

- main.go

```bash:main.go
package main

import "fmt"

func main() {
	fmt.Println("Testing")
}

```

- Testing

fmt で標準出力ができるか確認

```bash:bash
$ docker-compose exec app sh                                                                                                                                                 
[↓コンテナ内]
/usr/local/go/src/sample_app/app # ls -la
total 12
drwxr-xr-x    5 root     root           160 Jan  2 08:26 .
drwxr-xr-x    3 root     root          4096 Jan  2 08:30 ..
-rw-r--r--    1 root     root           210 Jan  2 08:33 .env
drwxr-xr-x    3 root     root            96 Jan  2 08:27 database
-rw-r--r--    1 root     root            68 Jan  2 08:29 main.go
/usr/local/go/src/sample_app/app # go run main.go
Testing
```

# まとめ

DockerでのGo x PostgreSQLの環境構築もGoの扱いもほぼ初めてなので至らない点などあるかと思います。
そのときは、ご教授いただけますと幸いです。

また、発見などありましたら記事にしていきたいと思いますのでよろしくお願いします。

最後まで読んでいただきありがとうございました！

# 参考文献

- [Goにはディレクトリ構成のスタンダードがあるらしい。](https://qiita.com/sueken/items/87093e5941bfbc09bea8)
- [GolangでMVCなAPIサーバを作るときのディレクトリ構成とプロジェクト生成コマンド](https://qiita.com/lon9/items/5239c2707b1557f76c9a)
- [GitHub sample app](https://github.com/suzu12/docker-go-postgresql-sampleapp)