GoとMongoDBのコンテナでフロントとバックエンドを分けてみる

GoとMongoDBを使って、DBのデータを表示する簡単なWebアプリケーションを作成します。本記事は、過去に投稿したコンテナでフロントとバックエンドを分けてみるで作成したWebアプリケーションのデータ格納先をMongoDBにしたものです。

以下の流れで紹介します。

  • dbコンテナを作成する
  • searcherコンテナを作成する
    • ソースコードを作成する
    • コンテナイメージを作成する
  • webコンテナを作成する
  • アプリケーションを起動する

dbコンテナを作成する


以下の記事で作成したMongoDBのコンテナを利用します。

mongodbコンテナの起動時に初期データを登録してみる

コンテナ起動時に、recommendデータベースcategoriesコレクションに以下のデータが保管されています。

[
  { "name": "スポーツ" },
  { "name": "文化" },
  { "name": "娯楽" },
  { "name": "食事" },
  { "name": "お酒" },
  { "name": "イベント" },
  { "name": "ドライブ" },
  { "name": "文化" }
]

searcherコンテナを作成する


dbコンテナからデータを取得し、json形式で出力するsearcherコンテナを作成します。

ソースコードを作成する


MongoDBからデータを取得し、json形式で出力するgolangを作成します。
MongoDBからデータを取得する方法は、mongodbからデータを抽出するgolangを書くで解説しています。

package main

import (
    "fmt"
    "log"
    "net/http"
    "encoding/json"
    "time"
    "context"
    "os"
    "github.com/gorilla/mux"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
    "go.mongodb.org/mongo-driver/bson"
)

type category struct {
    Categories []struct{
      Name string `json:"name"`
    }`json:"categories"`
}

func main() {
    r := mux.NewRouter()
    // localhost:8082/publicでpublicハンドラーを実行
    r.Handle("/public", public)

    //サーバー起動
    if err := http.ListenAndServe(":8082", r); err != nil {
        log.Fatal("ListenAndServe:", nil)
    }
}

var public = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    //MongoDBの認証情報
    credential := options.Credential{
      Username: "root",
      Password: "password",
    }

    //MongoDBへの接続
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    connect, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://db:27017").SetAuth(credential))
    defer connect.Disconnect(ctx)

    //collectionの取得
    collection, err := connect.Database("recommend").Collection("categories").Find(context.Background(), bson.M{})
    if err != nil { log.Fatal(err) }
    var results []bson.M
    if err = collection.All(context.TODO(), &results); err != nil {
      log.Fatal(err)
    }

    //取得したコレクションの_idエントリを削除
    for _, entry_map := range results {
      delete(entry_map, "_id")
    }

    //bson.Mのデータをjson形式に変換
    json_result, err := json.Marshal(results)
    if err != nil {
        fmt.Println("JSON marshal error: ", err)
        return
    }

    //category構造体にJson形式の値を代入
    var output category
    if err := json.Unmarshal(json_result, &output.Categories); err != nil {
        log.Fatal(err)
        os.Exit(1)
    }

    //読み込んだJsonの表示
    json.NewEncoder(w).Encode(output)

})

コンテナイメージを作成する


Dockerfileを書いてコンテナイメージをビルドします。

ディレクトリ構造は以下の通りです。

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

Dockerfileは以下の通りです。

FROM golang:latest

# コンテナ作業ディレクトリの変更
WORKDIR /go/src/searcher
# ホストOSの ./src の中身を作業ディレクトリにコピー
COPY ./src .
RUN go get -u github.com/gorilla/mux
RUN go get -u "go.mongodb.org/mongo-driver/mongo"
RUN go build -o searcher
# ウェブアプリケーション実行コマンドの実行
CMD ["./searcher"]

以下のコマンドで作成します。

$ docker build -t searcher:latest .

webコンテナを作成する


webコンテナは以下の記事で作成したwebコンテナを流用します。以下の記事でフロントとバックエンドを分けていたので、修正する必要がありません。

goコンテナでフロントとバックエンドを分けてみる

アプリケーションを起動する


docker-composeを記述してコンテナアプリケーションを実行します。

docker-composeは以下の通りです。

version: '3'
services:
  db:
    container_name: db
    image: mongo-db:latest
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: password
    ports:
      - "27017:27017"
  searcher:
    container_name: searcher
    image: searcher:latest
    depends_on:
      - db
    links:
      - db
    ports:
      - "8082:8082"
  web:
    container_name: web
    image: web:latest
    depends_on:
      - searcher
    links:
      - searcher
    ports:
      - "8080:8080"

以下のコマンドを実行して起動します。

$ docker-compose up -d

localhost:8080にアクセスすると以下の結果が得られます。

以上です!

コメント

コメントは停止中です。