こんにちは。Technology部のグエンと申します。
今回はDocker、VSCodeを使ったGo言語の環境構築方法を解説します。
本記事を読むと、以下のような開発環境を構築できるようになります。ご参考になりますと幸いです。
- docker-compose up -d コマンドでAPIサーバーを起動
- VSCodeを使い、リモートでデバッグできる
- ライブリロードの実施
- データベースのサーバーを起動
※本記事はMac(使用したOSはMacOS Ventura 13.4.1)の利用を前提としています。
目次
Go言語開発の環境構築方法
準備
まずは下準備として、お使いのMacに以下のアプリをインストールしてください。
- Docker : version 24.0.6
- go version go1.20.10
- VSCode IDE: 1.81.1
プロジェクトのフォルダを作成
以下のような構成でフォルダを作成します。
├─back
├─docker
│ └─go
│ └─Dockerfile
└─docker-compose.yml
- back:バックエンドのソースを配置するディレクトリ
- docker:DockerfileやDockerコンテナにマウントする設定ファイル等を配置するディレクトリ
- go:docekrフォルダ内に作成。Goに関連するDockerfileやDockerコンテナにマウントする設定ファイル等を配置するディレクトリ
- Dockerfile:goフォルダ内に作成。
- docker-compose.yml:Dockerの環境全体を紐付けおよび定義するファイル
このフォルダをVSCodeで開くと上の画像のようなイメージになります。
Dockerの初期化
APIサーバーのDocker(docker/go/Dockerfile)を定義します。
docker
FROM golang:1.20.10-alpine3.17
# このコメント以後のコメントは[/go/src/app/]フォルダーにて実行させるように指定します
WORKDIR /go/src/app/
# ホストPCの[./back]フォルダーの配置されたソースコードを[/go/src/app/]フォルダーにコピーします
COPY ./back .
# OSのインストール済みのパッケージをバージョンアップし、必要なパッケージをインストールします
RUN apk upgrade --update && \
apk --no-cache add git gcc musl-dev
次に、Docker環境(docker-compose.yml)を構成します
docker
version: '3'
services:
go:
container_name: go-api-server
platform: linux/x86_64
hostname: localhost
tty: true
build:
context: .
dockerfile: ./docker/go/Dockerfile
volumes:
- ./back:/go/src/app
動作確認
ここまでできたら、Docker内でGoのソースコードが動作するか一度確認してみましょう。簡単なGoソースコードを用意して試します。
- back/go.mod
go
module example/go
go 1.20
go
package main
import "fmt"
func main() {
fmt.Println("Hello World")
}
次に各種のDockerイメージをビルドします。上の画像にしたがって、Dockerをビルドし、各種Dockerイメージを起動してください。
docker-compose build
docker-compose up -d
続いて、下記コードでDocker内にアクセスします。
docker exec -it api-server /bin/sh
最後に、さきほど用意したback/main.goファイルを実装してみます。
go run main.go
ここまで問題なければ、上の画像のように「Hello World」と出力されます。これでDockerの初期化は完了です。
リモートデバッグの設定
VSCodeを使ってリモートでデバッグできるようにするため、Go拡張をインストールします。全部で11ステップありますので、順番に説明します。
ステップ1:
上の画像にしたがって、Extentions -> Go -> installからインストールしてください。
ステップ2:
続いて、「dlvツール」をインストールします。これはコードエディタやVSCodeでステップを実行する、実行途中の変数値を確認するなどのデバッグをおこなうために必要なライブラリです。
まずCommand + Shift + Pでコマンドパレットを開いてください(ちなみにWindowsの場合はCtrl + Shift + Pです) 。
ステップ3:
画像赤枠の箇所に「>Go: Install/Update Tools」と入力してください。
ステップ4:
dlv@lastestをチェックしてOKボタンをクリックします。
インストールが成功すると上の画像のような結果が出てきます。
ステップ5:
dlvツールのインストールコマンドをDockerfile(docker/go/Dockerfile)に追加しましょう。
docker
FROM golang:1.20.10-alpine3.17
# このコメント以後のコメントは[/go/src/app/]フォルダーにて実行させるように指定します
WORKDIR /go/src/app/
# ホストPCの[./back]フォルダーの配置されたソースコードを[/go/src/app/]フォルダーにコピーします
COPY ./back .
# OSのインストール済みのパッケージをバージョンアップし、必要なパッケージをインストールします
RUN apk upgrade --update && \
apk --no-cache add git gcc musl-dev
# (追加部分)
RUN go install github.com/go-delve/delve/cmd/dlv@latest
ステップ6:
ホスト環境からアクセスできるようにポートのマッピングを行います。docker-compose.ymlを以下のように編集してください。
docker
version: '3'
services:
go:
container_name: go-api-server
platform: linux/x86_64
hostname: localhost
ports:
- 2345:2345 # デバッグ用のポート
tty: true
build:
context: .
dockerfile: ./docker/go/Dockerfile
volumes:
- ./back:/go/src/app
ステップ7:
一度Docker環境をシャットダウンして、再度ビルドを行います。
docker-compose up -d --build
ステップ8:
ここからデバッグモードを有効にしていきます。まずは下記コードでDocker内にアクセスしてください。
docker exec -it api-server /bin/sh
ステップ9:
goプロジェクトをビルドします。
go build -gcflags "all=-N -l" -o tmp/main .
ステップ10:
デバッグモードを起動します。
dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient exec ./tmp/main
ステップ11:
以下の内容でvscodeのlaunch.json(/launch.json)を作成してください。
json
{
"version": "0.2.0",
"configurations": [
{
"name": "debug on docker",
"type": "go",
"request": "attach",
"mode": "remote",
"remotePath": "/go/src/app", //Docker内のソースコード配置するパス。
"cwd": "${workspaceRoot}/back", //ホスト環境のソースコード配置するバス
"port": 2345,
"host": "localhost",
"showLog": true
}
]
}
デバッグしてみて問題なければ、上の画像のようになっているかと思います。
ホットリロードの設定
ここまでの設定でデバッグ機能を試していただけたと思いますが、ソースコードを修正するたびにさきほど紹介したステップ5とステップ6をやり直さないといけないため実用的ではありません。
その問題を解決するために必要な、ホットリロードの実装方法についても紹介します。
ホットリロードを実装するには、Airツールを採用します。Airとはコードに変更があった場合に検知して、自動的にビルドなどの反映を行うツールです。
まずはAirツールのインストールコマンドをDockerfile(docker/go/Dockerfile)に追加します。
docker
FROM golang:1.20.10-alpine3.17
# このコメント以後のコメントは[/go/src/app/]フォルダーにて実行させるように指定します
WORKDIR /go/src/app/
# ホストPCの[./back]フォルダーの配置されたソースコードを[/go/src/app/]フォルダーにコピーします
COPY ./back .
# OSのインストール済みのパッケージをバージョンアップし、必要なパッケージをインストールします
RUN apk upgrade --update && \
apk --no-cache add git gcc musl-dev
# デバッグ用のツール
RUN go install github.com/go-delve/delve/cmd/dlv@latest
# 追加分
# ホットリロード用のツール
RUN go install github.com/cosmtrek/air@latest
# airツールを起動します
CMD ["air", "-c", ".air.toml"]
一度Docker環境をシャットダウンして、再度ビルドを行います。
docker-compose up -d --build
デバッグ機能をもう一度確認します。これで、ソースコードを修正しても自動的にデバッグできるようになりました。
データベースのサーバーを起動できるように設定する
最後に、データベースのサーバーを起動するために必要な設定を行います。以下のように、docker-compose用の設定ファイル(.env)を作成してください。
.env
# DBコンテナ名
DB_HOST=api_db_postgresql
# init時のdatabase
DB_DATABASE=apidb
# DB情報
DB_USER=postgres
DB_PASSWORD=PostGres@123
DB_PORT=5444
次に、postgresデータベース用のDockerfile(docker/postgresql/Dockerfile)を作成します。
docker
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
データベースを初期化するスクリプト(back/database/init/init_database.sql)を作成します。
sql
CREATE DATABASE IF NOT EXISTS apidb;
最後にPostgresqlデータベースを追加するために、docker-compose.ymlファイルを編集します。
docker
version: '3'
services:
go:
container_name: api-server
platform: linux/x86_64
hostname: localhost
tty: true
build:
context: .
dockerfile: ./docker/go/Dockerfile
ports:
- "2345:2345" #delve用のポート
volumes:
- ./back:/go/src/app
networks:
- private-net
# posttgresql
posttgresql-db:
container_name: posttgresql-db
build:
context: .
dockerfile: ./docker/postgresql/Dockerfile
environment:
- POSTGRES_DB=${DB_DATABASE}
- POSTGRES_USER=${DB_USER}
- POSTGRES_PASSWORD=${DB_PASSWORD}
volumes:
- db-store:/var/lib/postgresql/data
- ./back/database/init:/docker-entrypoint-initdb.d # DBを初期化
ports:
- ${DB_PORT}:5432
networks:
- private-net
volumes:
db-store:
driver: local
networks:
private-net:
driver: bridge
下記コードで動作を確認しましょう。
docker-compose up -d --build
問題なくデータベースへアクセスできれば、設定完了です。
さいごに
これで基本的なサーバーを含めるGo開発環境の立ち上げが完了しました。
今回紹介した方法では、以下のようなメリットがあります。
- 一つのコマンドで開発環境を立ち上げられるためコストを減らせる
- チームの開発環境を統一することで、開発環境の違いから生じるトラブルを防止できる
- 複数案件を並行する場合、他案件の環境とコンフリクトすることを防止できる
一方、コンテナを動かすためにCPUやメモリなど高いスペックが要求されるというデメリットもあります。案件に応じて柔軟に使い分けるのがよいでしょう。
最新情報をメルマガでお届けします!
LIGブログではAIやアプリ・システム開発など、テクノロジーに関するお役立ち記事をお届けするメルマガを配信しています。
- <お届けするテーマ>
-
- 開発プロジェクトを円滑に進めるためのTIPS
- エンジニアの生産性が上がった取り組み事例
- 現場メンバーが生成AIを使ってみた
- 開発ツールの使い方や開発事例の解説
- AIをテーマにしたセミナーの案内
- 最新のAI関連ニュースまとめ など
「AIに関する最新情報を集めたい!」「開発ツールの解説や現場の取り組みを知りたい!」とお考えの方は、ぜひお気軽に無料のメルマガをご購読くださいませ。