13
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Golang / React / PostgreSQLのホットリロードできる開発環境をDockerで作ってみた

Last updated at Posted at 2021-08-25

#構成

  • バックエンド: Golang
  • フロントエンド: React(TypeScript) + Tailwind CSS
  • DB: PostgreSQL

#なぜ作ろうと思ったのか
開発中に、バックエンド、フロントエンド、データベースを起動、再起動の管理を各々するのが億劫になったので、どうせならdockerで統一してしまおうというのが作ろうとしたのがきっかけです。

#docker-compose

version: "3.7"

services:
  front:
    container_name: front
    build:
      context: ./front
      dockerfile: Dockerfile
    ports:
      - 3000:3000
    working_dir: /src
    volumes:
      - ./front:/src
    env_file:
      - ./front/.env
    tty: true
    stdin_open: true

  api:
    container_name: api
    build:
      context: ./api
      dockerfile: Dockerfile
      target: build
    volumes:
      - ./api/:/go/app
    env_file:
      - ./api/.env
    command: "air -c .air.toml"
    ports:
      - "8080:8080"
      - "2345:2345"
    privileged: true
    security_opt:
      - apparmor:unconfined
    cap_add:
      - SYS_PTRACE
    tty:
      true
    depends_on:
      - db

  db:
    container_name: db
    build:
      context: ./docker/postgres
      dockerfile: Dockerfile
    ports:
      - '5432:5432'
    expose:
      - 5432
    environment:
      POSTGRES_DB: api
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
    volumes:
      - db:/var/lib/postgresql/data

volumes:
  db:
    driver: local

Dockerfile(バックエンド)

dlvとairは必須。あとは開発効率上げるためのツールとか

# Build Step
FROM golang:1.16-alpine3.14 AS build

WORKDIR /go/app/

ARG build
ARG version
ARG CGO_ENABLED=0
ARG GOOS=linux
ARG GOARCH=amd64

# いらないかも
COPY go.mod go.sum ./
RUN go mod download

RUN set -eux && \
  apk update && \
  apk add --no-cache git curl make alpine-sdk build-base && \
  go install github.com/go-delve/delve/cmd/dlv@latest && \
  go install github.com/rubenv/sql-migrate/...@latest && \
  go install github.com/swaggo/swag/cmd/swag@latest && \
  go install github.com/golang/mock/mockgen@latest && \
  curl -sSfL https://raw.githubusercontent.com/cosmtrek/air/master/install.sh | sh -s -- -b $(go env GOPATH)/bin && \
  curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin

COPY . .

RUN set -eux && \
  go build -gcflags "all=-N -l" -o api ./main.go

# Server Step
FROM alpine3.14
ENV TZ=Asia/Tokyo

WORKDIR /app

COPY --from=build /go/app/api .

RUN set -x && \
  addgroup go && \
  adduser -D -G go go && \
  chown -R go:go /app/api

CMD ["./api"]

Go1.16からgo installが使えるようになったらしいです。

こちらの記事を参考にさせていただきました。
go mod tidyとかするとツール群が消えてしまうので、go install 便利です。
https://qiita.com/eihigh/items/9fe52804610a8c4b7e41

Dockerfile(フロントエンド)

FROM node:14.17.0-alpine

ENV NODE_ENV=development
ENV LANG ja_JP.UTF-8
ENV TZ Asia/TOKYO

RUN apk add --update --no-cache \
            curl \
            git \
            bash

WORKDIR /src
COPY ["package.json", "yarn.lock", "./"]
RUN yarn install
COPY . .
ENTRYPOINT [ "yarn", "start" ]

Dockerfile(データベース)

FROM postgres:10.17
RUN localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
COPY init.sql /docker-entrypoint-initdb.d/init.sql
RUN chmod 0755 /docker-entrypoint-initdb.d/init.sql

init.sql

docker/postgres/Dockerfile
DB作成時に実行したいSQLとかを入れる。こちらは任意

golangのホットリロード対応

.air.tomlを追加

# Config file for [Air](https://github.com/cosmtrek/air) in TOML format

# Working directory
# . or absolute path, please note that the directories following must be under root.
root = "."
tmp_dir = "tmp"

[build]
# Just plain old shell command. You could use `make` as well.
cmd = "go build -o /tmp/api ./main.go"
# Binary file yields from `cmd`.
bin = "/tmp/api"
# Customize binary.
# デバッグする場合
# full_bin = "APP_ENV=dev APP_USER=air /go/bin/dlv exec /tmp/api --headless=true --listen=:2345 --api-version=2 --accept-multiclient"
# 通常実行の場合
full_bin = "APP_ENV=dev APP_USER=air /tmp/api"

# Watch these filename extensions.
include_ext = ["go", "tpl", "tmpl", "html"]
# Ignore these filename extensions or directories.
exclude_dir = ["assets", "tmp", "vendor", "front"]
# Watch these directories if you specified.
include_dir = []
# Exclude files.
exclude_file = []
# This log file places in your tmp_dir.
log = "air.log"
# It's not necessary to trigger build each time file changes if it's too frequent.
delay = 1000 # ms
# Stop running old binary when build errors occur.
stop_on_error = true
# Send Interrupt signal before killing process (windows does not support this feature)
send_interrupt = false
# Delay after sending Interrupt signal
kill_delay = 500 # ms

[log]
# Show log time
time = false

[color]
# Customize each part's color. If no color found, use the raw app log.
main = "magenta"
watcher = "cyan"
build = "yellow"
runner = "green"

[misc]
# Delete tmp directory on exit
clean_on_exit = true

GolandやVScodeのデバッグモード

以下を切り替える必要がある。これは、なんとか自動化したい...

デバッグする場合

full_bin = "APP_ENV=dev APP_USER=air /go/bin/dlv exec /tmp/api --headless=true --listen=:2345 --api-version=2 --accept-multiclient"

通常実行の場合

full_bin = "APP_ENV=dev APP_USER=air /tmp/api"

#残課題
以下は今後なんとか解決したいなと思ってます。

  • デバッグモードの切り替えを手動でする必要があるのでその解消
  • docker内でmake testを実行するとエラーが発生する(go testはエラーは発生しない)
  • dockerコマンドが長いのでmakeなどで省略したい

#参考記事
こちらの記事をかなり参考にさせてもらいました。
https://qiita.com/keitakn/items/f46347f871083356149b

13
17
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?