taisablog

taisa's engineer blog

Go

DockerでGoのWebサーバーを起動する

投稿日:


ミニマムにやっておかないと忘れがちなのでメモ

サンプル用Goサーバを作成する

package main

import (
	"encoding/json"
	"net/http"
)

type User struct {
	FirstName string `json:"firstName"`
	LastName  string `json:"lastName"`
}

func users(w http.ResponseWriter, req *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	user := User{
		FirstName: "John",
		LastName: "Doe",
	}
	var users []User
	users = append(users, user)
	json.NewEncoder(w).Encode(users)
}

func main() {
	http.HandleFunc("/users", users)
	http.ListenAndServe(":8002", nil)
}

普通に起動して動作確認をします。

$ go run main.go

http://localhost:8002/usersにアクセスするとJSON結果が出力されます。

[
  {
    "firstName": "John",
    "lastName": "Doe"
  }
]

Dockerfile

Dockerfileを作成します。alpineをつけるとよりミニマムなイメージができます。参考(https://hub.docker.com/_/golang?tab=description

FROM golang:1.14
#FROM golang:1.14-alpine

# コンテナログイン時のディレクトリ指定
WORKDIR /opt/sandbox-docker-go

# ホストのファイルをコンテナの作業ディレクトリにコピー
COPY . .
# ADD . .

# ビルド
RUN go build -o app main.go

# 起動
CMD ["/opt/sandbox-docker-go/app"]

構成

$ tree
.
├── Dockerfile
└── main.go

ビルド

$ docker build -t sandbox-docker-go .
[+] Building 3.0s (9/9) FINISHED                                                                                                                                                                                                        
 => [internal] load build definition from Dockerfile                                                                                                                                                                               0.0s
 => => transferring dockerfile: 361B                                                                                                                                                                                               0.0s
 => [internal] load .dockerignore                                                                                                                                                                                                  0.0s
 => => transferring context: 2B                                                                                                                                                                                                    0.0s
 => [internal] load metadata for docker.io/library/golang:1.14                                                                                                                                                                     1.8s
 => [1/4] FROM docker.io/library/golang:1.14@sha256:d31a307a7e42116adb00d8d70971dbf228460904dd9b6217e911d088aa4b650c                                                                                                               0.0s
 => [internal] load build context                                                                                                                                                                                                  0.0s
 => => transferring context: 605B                                                                                                                                                                                                  0.0s
 => CACHED [2/4] WORKDIR /opt/sandbox-docker-go                                                                                                                                                                                    0.0s
 => [3/4] COPY . .                                                                                                                                                                                                                 0.0s
 => [4/4] RUN go build -o app main.go                                                                                                                                                                                              1.0s
 => exporting to image                                                                                                                                                                                                             0.1s
 => => exporting layers                                                                                                                                                                                                            0.1s
 => => writing image sha256:b59f0afdb5a50873182e88aa7e65836b15049b8a8e3d8a3644a856cc438e3610                                                                                                                                       0.0s
 => => naming to docker.io/library/sandbox-docker-go   

Dockerイメージが作成されました。

$ docker images
REPOSITORY                                   TAG                 IMAGE ID            CREATED             SIZE 
sandbox-docker-go                            latest              b59f0afdb5a5        30 seconds ago      817MB

コンテナ起動

$ docker run -p 8002:8002 -td --name sandbox-docker-go b59f0afdb5a5<br>8fe6ad253218c6c700eb91f458eed99cc8bfbd0ea03423d21a6a42d851268409

プロセスチェック

$ docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
8fe6ad253218        b59f0afdb5a5        "/opt/sandbox-docker…"   26 seconds ago      Up 26 seconds                           infallible_williams

http://localhost:8002/usersにアクセスして動作確認をします。

[
  {
    "firstName": "John",
    "lastName": "Doe"
  }
]

コンテナ再起動

$ docker restart cb8f814837cf

コンテナ停止

$ docker stop cb8f814837cf

コンテナ起動

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                       PORTS               NAMES
cb8f814837cf        b59f0afdb5a5        "/opt/sandbox-docker…"   3 minutes ago       Exited (2) 52 seconds ago                        reverent_snyder

$ docker start cb8f814837cf

コンテナプロセスkill

$ docker kill cb8f814837cf

コンテナ削除

$ docker rm cb8f814837cf

イメージ削除

$ docker images
REPOSITORY                                   TAG                 IMAGE ID            CREATED             SIZE
sandbox-docker-go                            latest              b59f0afdb5a5        13 minutes ago      817MB

$ docker rmi b59f0afdb5a5

-Go

執筆者:

関連記事

GORMでよく使うSQLの書き方

GORMでよく使うSQLの書き方をメモとして残しておきます。詳細は記事最後の参考リンクの公式ドキュメントで確認できます。 CREATE insertするだけであれば create を利用します。 db.Create(&models.User{Name: “user”}) # 実行SQL INSERT INTO “users” (“created_at”,”updated_at”,”name”,”email”) VALUES (‘2020-04-25 11:22:00′,’2020-04-25 11:22:00′,’user’,0) UPDATE 特定のフィールドだけ更新したい場合、 Update と Updates を使います。 update 一つのフィールドだけアップデートします。 user := &models.User{Name: “user”} db.Create(user) db.Model(user).Update(“name”, “user2”) # 実行SQL INSERT INTO “users” (“created_at”,”updated_at”,”name”,”email”) VALUES (‘2020-04-25 11:34:39′,’2020-04-25 11:34:39′,’user’,”) UPDATE “users” SET “name” = ‘user2’, “updated_at” = ‘2020-04-25 11:34:39’ WHERE “users”.”id” = 5 updates updates は map を利用して複数のフィールドをアップデートします。 user := &models.User{Name: “user”} db.Create(user) db.Model(user).Updates(map[string]interface{}{“name”: “user3”, “email”: “g5.taisa831@gmail.com”}) # 実行SQL INSERT INTO “users” (“created_at”,”updated_at”,”name”,”email”) VALUES (‘2020-04-25 11:39:52′,’2020-04-25 11:39:52′,’user’,”) UPDATE “users” SET “email” = ‘g5.taisa831@gmail.com’, “name” = ‘user3’, “updated_at” = ‘2020-04-25 11:39:52’ WHERE “users”.”id” = 6 SAVE Save は SQL を実行する際にすべてのフィールドを含みます。フィールドを指定しなくても空にはなりません。 user := &models.User{Name: …

Go言語 GORM+GinでTODOリストを作ってみた

前回の「Go言語 ORMライブラリ GORMの使い方」に続いて「GORM+Gin」でTODOリストを作ってみました。使い方は「GitHubのREADME」を参考にしました。できたものは下記URLから確認できます。装飾は別途やれればと。 http://gin.taisablog.com/todo 事前情報 Webフレームワーク:Gin (https://github.com/gin-gonic/gin) ORM:GORM (https://gorm.io/docs) DB:MySQL ルーティングは通常のフォームだとPUT/DELETEが使えないので以下のようにしました。 [GIN-debug] GET /todo –> main.main.func1 (3 handlers) // 一覧表示 [GIN-debug] POST /todo –> main.main.func2 (3 handlers) // 新規作成 [GIN-debug] GET /todo/:id –> main.main.func3 (3 handlers) // 編集画面表示 [GIN-debug] POST /todo/edit/:id –> main.main.func4 (3 handlers) // 編集 [GIN-debug] POST /todo/delete/:id –> main.main.func5 (3 handlers) // 削除 main.goだけで作成した場合 main.goに全ての処理を記述しています。 package main import ( “github.com/gin-gonic/gin” “github.com/jinzhu/gorm” _ “github.com/jinzhu/gorm/dialects/mysql” “net/http” “strconv” ) type Todo struct { gorm.Model Text string Status uint64 } func main() { db, err := gorm.Open(“mysql”, “gorm:gorm@/sandbox_gin?charset=utf8mb4&parseTime=True&loc=Local”) if err != nil { panic(“データベースへの接続に失敗しました”) } defer db.Close() db.LogMode(true) db.AutoMigrate(&Todo{}) r := …

[Golang]Goのio/ioutilパッケージは分かりやすくて使いやすい

Goのioパッケージは主にインターフェースになっていて他のパッケージで多く実装されています。またioパッケージにもパブリックな関数がありファイルの入出力はできますが少し細かい処理になります。io/ioutilパッケージを使うとファイルの入出力処理が簡単にできます。以下にio/ioutilパッケージを使った処理とそれに対するテストコードを記載します。 io/ioutil/ioutil.go ReadAll() func ReadAll() string { file, _ := os.Open(“testdata/src.txt”) b, _ := ioutil.ReadAll(file) return string(b) } ReadAllテスト func TestReadAll(t *testing.T) { str := ReadAll() if str != “0123456789” { t.Errorf(“TestReadAll Error. %s”, str) } } ReadFile() func ReadFile() string { b, _ := ioutil.ReadFile(“testdata/src.txt”) return string(b) } ReadFileテスト func TestReadFile(t *testing.T) { str := ReadFile() if str != “0123456789” { t.Errorf(“TestReadAll Error. %s”, str) } } WriteFile() func WriteFile() string { b := []byte(“0123456789”) _ = ioutil.WriteFile(“testdata/dst.txt”, b, os.ModePerm) b, _ = ioutil.ReadFile(“testdata/dst.txt”) return string(b) } WriteFileテスト func TestWriteFile(t *testing.T) { str := WriteFile() if str != “0123456789” …

Golang 1.13 released! The difference from 1.12 to 1.13

Golang 1.13 was released in 3 September 2019. This post has difference from 1.12 to 1.13. I check the changes at the release notes and difference of src. Release Notes Go 1.13 Release Notes The latest Go release, version 1.13, arrives six months after Go 1.12. Most of its changes are in the implementation of the toolchain, runtime, and libraries. As always, the release maintains the Go 1 promise of compatibility. We expect almost all Go programs to continue to compile and run as before. Diff on GitHub Release branch.go1.13 by taisa831 · Pull Request #1 · taisa831/go This PR …

no image

docker-compose&dockerizeでGo+MySQLのWebサーバーを起動する

docker-composeでGo + MySQLを起動する場合、MySQLの起動を待ってGoのWebサーバーを起動する必要があります。実現するにはどうやらスクリプトを書かないとだめらしいですが、dockerizeを使うと簡単に実現できます。 サンプル用Goサーバを作成する 起動時にusersテーブルを作成し、リクエスト時にusersテーブルにレコードをinsertする簡単なサンプルアプリケーションです。 package main import ( “database/sql” “encoding/json” “fmt” “log” “net/http” “os” _ “github.com/go-sql-driver/mysql” “github.com/joho/godotenv” ) type User struct { FirstName string `json:”firstName”` LastName string `json:”lastName”` } var db *sql.DB func main() { err := godotenv.Load() if err != nil { log.Fatal(err) } db = Conn() defer db.Close() _, err = db.Exec(“CREATE TABLE IF NOT EXISTS users(id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, firstname VARCHAR(255) NOT NULL, lastname VARCHAR(255) NOT NULL)”) if err != nil { log.Fatal(err) } http.HandleFunc(“/users”, users) err = http.ListenAndServe(os.Getenv(“LISTEN_PORT”), nil) if err != nil { log.Fatal(err) } } func Conn() *sql.DB { db, err …