Dockerを使ってみました

Dockerとは。利用するメリットについて 

Dockerは、Docker社が開発したコンテナという概念を管理するソフトウェアです。サーバーを起動する方法が、シンプルかつ、起動や処理が早いことが特徴です。 

Dockerのメリットは主に3つあります。 

①システム導入の高速化 

 OSはすでに共有して利用しているため、それらの設定は省き、システムを構築するために必要となる最低限のプログラムをインストールすればOKです。 

 そのため、すぐにプログラムを適用し、導入までのスピードを高速化することができます。 

 

②起動時間の短縮化と、多くの処理実装が可能 

 完全仮想化であれば、サーバーを起動する際にOSレベルから立ち上げていく必要があり時間がかかります。ですが、DockerではOSはすでに立ち上がっているため、その分サーバーの起動時間を短縮化することができます。 

 またリソースの使用量が少なく済むためサーバーへの負荷が低く、一度に多くのプログラム処理を実装することが可能です。 

 

③コンテナ設定の再利用が可能 

 一度作成したコンテナは、Dockerイメージを作成し、他のコンテナへ適用することにより再利用が可能です。 

 検証時やリソースを拡大したい場面にて同じ環境設定が適用されたコンテナを準備できます。 

 

Docker Desktopの導入 

Dockerで検索してDocker公式サイトに遷移します。 

ページの下の方にいくとDocker Desktopの中に「Download for ***」がありますので、使用しているOSのものをダウンロードします。 

自分の場合は「Download for Mac – Apple Chip」をダウンロードしました。 

あとは指示に従えばインストール完了できると思います。 

 

インストールが完了し、Docker Desktopを起動すると下記のような画面が表示されます。 

自分のDocker Desktopではすでに作成しているものがありますが、これらは無視してください。 

 

goファイル作成 

Dockerと連携するファイルとしてgoファイルを作成していきます。 開発環境のDevフォルダを作成し、その中にDev/go-smallitフォルダを作成します 

VSCodeまたはGoLandでgo-smallitを開きます。ここではGoLandを利用して説明していきます。 

Terminalにて下記コマンドを実行します 

go mod init smallit 

コマンド実行後、go.modファイルが作成されます。 

Dev/go-smallitフォルダにmain.goファイルを作成し、元のソースを全て消去して、https://github.com/gofiber/fiberから引用した下記ソースをコピペします。 

package main 
import "github.com/gofiber/fiber/v2" 
func main() { 
   app := fiber.New() 
    app.Get("/", func(c *fiber.Ctx) error { 
        return c.SendString("Hello, World ????!") 
    }) 

    app.Listen(":3000") 
} 

FiberとはWebフレームワークのことで、Go最速のHTTPエンジンで作成されています。 

上図のようにエラーが出ますので、パッケージであるgithub.com/gofiber/fiber/v2を取得します。 

下記コマンドを実行します。 

go get github.com/gofiber/fiber/v2 

エラーが解消されるので、一度起動してみたいと思います。 

下記コマンドを実行します。 

go run main.go 

上図のように表示されると思います。 

http://127.0.0.1:3000を開いてみます。下図のようにHello Worldが表示されたら正常に起動していることが確認できます。 

Docker-compose up実行 

Dev/go-smallitフォルダ内に下記のファイルとソースを追加します。 

 ・docker-compose.yaml 

version: '3.9' 
services: 
  backend: 
    build: . 
    ports: 
      - 8000:8000 
    volumes: 
      - .:/app 
    depends_on: 
      - db 

  db: 
    image: mysql:5.7.22 
    restart: always 
    environment: 
      MYSQL_DATABASE: smallit 
      MYSQL_USER: root 
      MYSQL_PASSWORD: root 
      MYSQL_ROOT_PASSWORD: root 
    volumes: 
      - .dbdata:/var/lib/mysql 
    ports: 
      - 33066:3306 

 

Dockerfile 

FROM golang:1.16 

WORKDIR /app 
COPY go.mod . 
COPY go.sum . 
RUN go mod download 

COPY . . 

RUN curl -sSfL 
https://raw.githubusercontent.com/cosmtrek/air/master/install.sh |
 sh -s -- -b $(go env GOPATH)/bin 

CMD ["air"] 

 

・/src/controllers/authController.go 

package controllers 

import ( 
    "github.com/gofiber/fiber/v2" 
    "golang.org/x/crypto/bcrypt" 
    "smallit/src/database" 
    "smallit/src/models" 
) 

func Register(c *fiber.Ctx) error { 
    var data map[string]string 

    if err := c.BodyParser(&data); err != nil { 
        return err 
    } 

    if data["password"] != data["password_confirm"] { 
        c.Status(400) 
        return c.JSON(fiber.Map{ 
            "message": "パスワードが一致しません", 
        }) 
    } 

    password, _ := 
bcrypt.GenerateFromPassword([]byte(data["password"]), 12) 

    user := models.User{ 
        FirstName: data["first_name"], 
        LastName:  data["last_name"], 
        Email:     data["email"], 
        Password:  password, 
    } 

    database.DB.Create(&user) 
    return c.JSON(user) 
} 

 

・/src/database/db.go 

package database 

import ( 
    "gorm.io/driver/mysql" 
    "gorm.io/gorm" 
    "smallit/src/models" 
) 

var DB *gorm.DB 

func Connect() { 
   var err error 

   DB, err = 
gorm.Open(mysql.Open("root:root@tcp(db:3306)/smallit"), 
&gorm.Config{}) 
    if err != nil { 
        panic("データベースに接続できません") 
    } 
} 

func AutoMigrate() { 
    DB.AutoMigrate(models.User{}) 
} 

 

・/src/models/user.go 

package models 

type User struct { 
    id        uint 
    FirstName string 
    LastName  string 
    Email     string 
    Password  []byte 
} 

 

・/src/routes/routes.go 

package routes 

import ( 
    "github.com/gofiber/fiber/v2" 
    "smallit/src/controllers" 
) 

func Setup(app *fiber.App) { 
    api := app.Group("api") 
    api.Post("/register", controllers.Register) 
} 

 

main.goファイルを変更します。 

main.go 

 package main 

import ( 
    "github.com/gofiber/fiber/v2" 
    "smallit/src/database" 
    "smallit/src/routes" 
) 

func main() { 
    database.Connect() 
    database.AutoMigrate() 

    app := fiber.New() 

    routes.Setup(app) 

    app.Listen(":8000") 
} 

 

また、いくつかパッケージを取得する必要がありますので、下記コマンドを実行します。 

 

go get -u gorm.io/gorm 
go get -u gorm.io/driver/mysql 
go get golang.org/x/crypto/bcrypt 
go get github.com/gofiber/fiber/v2/internal/isatty@v2.25.0 

以上でファイルの準備が整いました。最終的には下図のようなフォルダ構成になっていると思いますのでご確認ください。 


 

Docker Desktopが起動していることを確認します。他のDockerが起動していると今回作成したものが実行できませんので予め他のDockerは停止しておきます。 

下記コマンドを実行します。 

docker-compose up 

下図のように表示されたらOKです。 

 

確認 

実際にAPIが実行されるかどうか確認します。Postmanを開きます。 

POSTを選択し、URLは下記のように入力します。 

http://localhost:8000/api/register 

 続いてJSON形式で登録するデータを入力します。Bodyをクリックし、GraphQLの右隣の選択項目をJSONとします。下の項目にパラメータを入力できますので下記のように入力します。 

{ 
    "first_name": "small", 
    "last_name": "it", 
    "email": "smallit@smallit.com", 
    "password": "s", 
    "password_confirm": "s" 
} 

参考までに下図のようになっているかご確認ください。 

入力したらSendボタンをクリックします。正常に動作すればパラメータが返ってきます。 

次にDBを確認していきます。 

右端にある「Database」をクリックします。続いて「+」→「Data Source」→「MySQL」をクリックします。 

入力が必要な項目について、下記のように入力します。 

Port:33066 

User:root 

Password:root 

Database:smallit 

 

入力しましたらTest Connectionをクリックします。 

今回は下図のようなエラーが発生しました。 

Enable TLSv1.1をクリックして再度Test Connectionをクリックします。 

Succeededと表示されたら「Apply」をクリックし、「OK」を押します。 

テーブルのデータを確認します。 

Smallitテーブルに登録した内容のデータが表示されればOKです。これでDockerを利用してDBへデータを登録するところまで確認できました。 

 

 

参考URL 

Dockerとは何かを入門社向けに解説!基本コマンドも 

https://udemy.benesse.co.jp/development/system/docker.html) 

gofiber 

https://github.com/gofiber/fiber) 

gorm 

https://gorm.io/ja_JP/docs/index.html) 

air 

https://github.com/cosmtrek/air) 

 

Smallitのサービス