😸

Docker(Alpine)でGo(Golang)+MySQLの環境構築

2022/07/16に公開

はじめに

社内でGoを利用したプロジェクトを進めるべくGoの学習を始めました
参考にした書籍はGo言語ハンズオンの1章です。この環境を用いることで書籍を最後まで進めることができます。

開発環境

VSCode
Ubuntu 20.04 (WSL2)
Docker 20.10.12
docker-compose version v2.2.3
git version 2.25.1

コンテナの作成

以下のコマンドでローカルにDockerfiledocker-compose.ymlを作成します。

$ touch Dockerfile docker-compose.yml

ファイルを修正します。

Dockerfile
FROM golang:1.18.4-alpine3.16
RUN apk update && apk add git
RUN mkdir /go/src/app
WORKDIR /go/src/app
ADD . /go/src/app
docker-compose.yml
version: "3"
services: 
  app:
    build: . 
    container_name: go
    tty: true
    volumes:
      - ./app:/go/src/app
    env_file:
      - .env
    networks:
      - golang_test_network
    depends_on:
      - db

  db:
    image: mysql:8.0.27
    container_name: db
    env_file:
      - .env
    ports:
      - "3306:3306"
    volumes:
      - db:/var/lib/mysql
    networks:
      - golang_test_network

volumes:
  db:
networks:
  golang_test_network:
    external: true

注意点としては、networksを設定することで、GoコンテナからDBコンテナにdbでアクセスできるようにしています。

つぎにMySQL用の環境変数を設定する.envを作成します。

$ touch .env
MYSQL_DATABASE=myapp
MYSQL_USER=user
MYSQL_PASSWORD=password
MYSQL_ROOT_PASSWORD=password

次にテスト実行に必要なファイルを用意していきます。

$ mkdir app
$ touch ./app/main.go
main.go
package main

import (
	"fmt"
)

func main() {
	fmt.Print("Hello World!")
}

それではコンテナを起動して実行してみます。

# ネットワークの作成
$ docker network create golang_test_network

$ docker-compose build
$ docker-compose up

# 別のターミナルを開いてGoコンテナにはいる
$ docker exec -it go sh

$ go run main.go

# Hello World!と表示されれば成功

パッケージの利用

コンテナの中で以下のコマンドを実行する

$ go mod init hello-go

このファイルを作成することでhelloをパッケージとして読み込めるようにしています。

そしてhelloというディレクトリをappの中に作成して、hello.goを追加します。

# WSLターミナルで実行
$ mkdir ./app/hello
$ touch ./app/hello/hello.go

ファイルを修正します。

main.go
package main

import (
	"hello-go/hello"
	"fmt"
)

func main() {
	t:= hello.Test()
	fmt.Print(t)
}
./hello/hello.go
package hello

func Test() string {
	return "Hello World!"
}

そしてGoコンテナの中で実行します

$ go run main.go

Hello World!と表示されれば成功です

MySQLの接続確認

書籍のMySQLを利用した文章を試しに実行します
MySQL接続に必要なパッケージをインストールするためにDockerfileを修正します。

Dockerfile
FROM golang:1.18.4-alpine3.16
RUN apk update && apk add git
RUN mkdir /go/src/app
WORKDIR /go/src/app
ADD ./app /go/src/app

RUN go get -u github.com/go-sql-driver/mysql

実行ファイルを追加します。

$ touch sql.go
sql.go
package main

import (
	"database/sql"
	"fmt"
	"os"

	_ "github.com/go-sql-driver/mysql"
)


func main() {
	con, er := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(db:3306)/%s?charset=utf8&parseTime=true",
		os.Getenv("MYSQL_USER"), os.Getenv("MYSQL_PASSWORD"),
		os.Getenv("MYSQL_DATABASE")))
	if er != nil {
		panic(er)
	}
	defer con.Close()
	fmt.Print("Success!")
}
$ go run sql.go

Success!とでれば成功です

VSCodeで開発する際のポイント

VSCodeのGoの拡張機能を使う場合にローカルで拡張機能を使うと、ローカルにはGo環境がないので(コンテナ上に作成するため)エラーが多発してしまいます。

なので、Remote Containerを利用してGoコンテナの中で開発するようにしましょう。コンテナに入ったらそこで拡張機能をインストールします。

おわりに

これに加えてマイグレートの実行ができるかを確かめられれば、Go言語ハンズオンは問題なくできるはずです。

GoではRemote Containerを利用して開発するというのがいままでにない感覚だなと思いました。

参考

GitHubで編集を提案

Discussion