4
1

Docker 環境で Go Gin Webサービスを起動する

Last updated at Posted at 2023-08-14

Docker 環境で Go Gin Webサービスを起動する

こんにちは、@studio_meowtoon です。今回は、WSL Ubuntu の Docker 環境で、Go Gin Web アプリケーションをコンテナーとして起動する方法を紹介します。
gin_on_docker.png

目的

Windows 11 の Linux でクラウド開発します。

こちらから記事の一覧がご覧いただけます。

実現すること

ローカル環境の WSL Ubuntu の Docker 環境で、Dockerfile からビルドした Go Gin Web サービスのカスタムコンテナーイメージを起動します。

ネイティブイメージ形式のアプリをコンテナーとして起動

実行環境

要素 概要
terminal ターミナル
Ubuntu OS
Docker コンテナー実行環境

Web サービス コンテナー

要素 概要
app-hello-gin カスタムコンテナー
app ネイティブイメージ アプリケーション
gin Web サーバー機能を含む

技術トピック

Gin とは?

こちらを展開してご覧いただけます。

Gin (ジン)

Gin は、Go 言語向けの軽量で高速な Web フレームワークです。

キーワード 内容
高速性 Gin は非常に高速で軽量なフレームワークであり、HTTP ルーティングやハンドリングの性能が優れています。これにより、高負荷なアプリケーションでも高い処理能力を発揮します。
最小構成 Gin は最小限の機能を提供するため、不要な機能やコードが含まれません。これにより、アプリケーションのサイズや起動時間を最小限に抑えることができます。
パフォーマンス重視 Gin はルーティングやミドルウェアの処理において、最適化されたアプローチを採用しています。これにより、アプリケーション全体のパフォーマンスが向上します。
豊富なミドルウェア Gin はミドルウェアのサポートを提供し、リクエスト/レスポンスの前後で機能を拡張できます。認証、ロギング、エラーハンドリングなど、多くのミドルウェアが用意されています。
学習しやすさ シンプルなルーティングとクリーンなコード構造により、新しい開発者が迅速に学び始め、プロジェクトに参加することが容易です。
活発なコミュニティ Gin は人気があり、アクティブなコミュニティが存在します。ドキュメントやリソースが豊富で、問題を解決するためのサポートが得られます。

Dockerfile とは?

こちらを展開してご覧いただけます。

Dockerfile

Dockerfile は、Docker コンテナーを構築するためのテキストファイルです。Docker コンテナーはアプリケーションやサービスを実行するための環境を含む軽量でポータブルな仮想化ユニットです。

キーワード 内容
スクリプト形式 Dockerfile はシンプルなスクリプト形式で記述されるため、コンテナーのビルドプロセスを自動化することが容易です。
レイヤー構造 Docker イメージは Dockerfile の各命令が実行される際にレイヤーとして生成され、再利用やキャッシュが可能な構造となっています。
バージョン管理 Dockerfile はテキストベースであるため、コードと同様にバージョン管理システムで管理しやすいです。
ポータビリティ Dockerfile により、アプリケーションとその依存関係が1つのコンテナイメージにパッケージ化されるため、異なる環境間での移植性が高まります。
自動化と効率化 Dockerfile を使用することで、アプリケーションのビルドや環境構築を自動化できます。これにより、手動での作業時間やヒューマンエラーが減り、開発・デプロイプロセスが効率的になります。
再現性 Dockerfile はビルド手順を完全に定義するため、異なる環境で同じアプリケーションを再現できます。これにより、開発、テスト、本番環境間での一貫性が確保されます。
環境の分離 Docker コンテナーはホストシステムから分離されるため、アプリケーションの依存関係やライブラリの衝突を回避し、より安全な環境で実行できます。
拡張性 Dockerfile を使用することで、カスタムイメージを作成できます。このため、特定のニーズに合わせてカスタマイズされたコンテナイメージを容易に作成できます。

開発環境

  • Windows 11 Home 23H2 を使用しています。

WSL の Ubuntu を操作しますので macOS の方も参考にして頂けます。

WSL (Microsoft Store アプリ版) ※ こちらの関連記事からインストール方法をご確認いただけます

> wsl --version
WSL バージョン: 2.2.4.0
カーネル バージョン: 5.15.153.1-2
WSLg バージョン: 1.0.61

Ubuntu ※ こちらの関連記事からインストール方法をご確認いただけます

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 24.04 LTS
Release:        24.04
Codename:       noble

Docker ※ こちらの関連記事からインストール方法をご確認いただけます

$ docker --version
Docker version 27.0.3, build 7d4bcd8

この記事では基本的に Ubuntu のターミナルで操作を行います。Vim を使用してコピペする方法をはじめて学ぶ人のために、以下の記事で手順を紹介しています。ぜひ挑戦してみてください。

作成する Web アプリケーションの仕様

No エンドポイント HTTPメソッド MIME タイプ
1 /api/data GET application/json

/api/data というエンドポイントに対して HTTP GET リクエストを送信すると、JSON データがレスポンスされるシンプルな Web サービスを実装します。
{"message":"Hello World!"}

Hello World を表示する手順

Go 言語のインストール

Go 言語をインストールします。

$ sudo apt update
$ sudo apt install golang

バージョンを確認します。

$ go version
go version go1.22.2 linux/amd64

プロジェクトの作成

プロジェクトフォルダーを作成します。
※ ~/tmp/hello-gin をプロジェクトフォルダーとします。

$ mkdir -p ~/tmp/hello-gin
$ cd ~/tmp/hello-gin

アプリケーションファイルの作成

app.go ファイルを作成します。

$ vim app.go

ファイルの内容

app.go
package main

import (
    "net/http"

    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()
    r.GET("/api/data", func(c *gin.Context) {
        response := gin.H{
            "message": "Hello World!",
        }
        c.JSON(http.StatusOK, response)
    })
    r.Run()
}
型宣言を省略せずに記述したコード
app.go
package main

import (
    "net/http"

    "github.com/gin-gonic/gin"
)

func main() {
    var router *gin.Engine = gin.Default()
    router.GET("/api/data", func(context *gin.Context) {
        var response map[string]any = gin.H{
            "message": "Hello World!",
        }
        context.JSON(http.StatusOK, response)
    })
    router.Run()
}

パッケージの追加

プロジェクトを初期化します。

$ go mod init hello-gin

Gin パッケージをインストールします。

$ go get -u github.com/gin-gonic/gin

バージョンを確認します。

$ go list -m github.com/gin-gonic/gin
github.com/gin-gonic/gin v1.10.0

ローカルで実行

ローカルで実行します。
停止するときは ctrl + C を押します。

$ go run app.go

別ターミナルから curl コマンドで確認します。

$ curl -v http://localhost:8080/api/data -w '\n'

出力

* Host localhost:8080 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:8080...
* Connected to localhost (::1) port 8080
> GET /api/data HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/8.5.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
< Date: Sat, 10 Aug 2024 17:07:06 GMT
< Content-Length: 26
<
* Connection #0 to host localhost left intact
{"message":"Hello World!"}

ここまでの手順で、ターミナルに {"message":"Hello World!"} と表示され、JSON データを取得することができました。

コンテナーイメージをビルド

Dockerfile を作成します。

$ vim Dockerfile

ファイルの内容

Dockerfile
# build the app.
FROM golang:1.22 AS build-env

# set the working dir.
WORKDIR /app

# copy the go module dependency files.
COPY go.mod go.sum ./

# download the go module dependencies.
RUN go mod download

# copy the app source code.
COPY app.go .

# build the go app binary.
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app app.go

# set up the container.
FROM debian:12-slim

# set the working dir.
WORKDIR /app

# copy the built app binary from the build-env.
COPY --from=build-env /app/app ./app

# expose the port.
EXPOSE 8080

# command to run the app.
CMD ["./app"]

Docker デーモンを起動します。

$ sudo service docker start

Docker 環境をお持ちでない場合は、以下の関連記事から Docker Engine のインストール手順をご確認いただけます。

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

$ docker build \
    --no-cache \
    --tag app-hello-gin:latest .

コンテナーイメージを確認します。

$ docker images | grep app-hello-gin
app-hello-gin    latest    dc4be79aa7e0   13 seconds ago   85.5MB

ここまでの手順で、ローカル環境の Docker にアプリのカスタムコンテナーイメージをビルドすることができました。

コンテナーを起動

ローカルでコンテナーを起動します。
※ コンテナーを停止するときは ctrl + C を押します。

$ docker run --rm \
    --publish 8080:8080 \
    --name app-local \
    app-hello-gin:latest

ここまでの手順で、ローカル環境の Docker でアプリのカスタムコンテナーを起動することができました。

コンテナーの動作確認

別ターミナルから curl コマンドで確認します。

$ curl -v http://localhost:8080/api/data -w '\n'

出力

* Host localhost:8080 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:8080...
* Connected to localhost (::1) port 8080
> GET /api/data HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/8.5.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
< Date: Sat, 10 Aug 2024 17:13:57 GMT
< Content-Length: 26
<
* Connection #0 to host localhost left intact
{"message":"Hello World!"}

ここまでの手順で、ターミナルに {"message":"Hello World!"} と表示され、JSON データを取得することができました。

コンテナーの状態を確認してみます。

$ docker ps
CONTAINER ID   IMAGE                  COMMAND   CREATED          STATUS          PORTS
     NAMES
37f0486ba648   app-hello-gin:latest   "./app"   45 seconds ago   Up 44 seconds   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   app-local

コンテナーに接続

別ターミナルからコンテナーに接続します。

$ docker exec -it app-local /bin/sh

コンテナー接続後にディレクトリを確認します。
※ コンテナーから出るときは ctrl + D を押します。

# pwd
/app
# ls -lah
total 11M
drwxr-xr-x 1 root root 4.0K Aug 10 17:12 .
drwxr-xr-x 1 root root 4.0K Aug 10 17:13 ..
-rwxr-xr-x 1 root root  11M Aug 10 17:12 app

top コマンドで状況を確認します。

# apt update
# apt install procps
# top
top - 17:15:37 up 20 min,  0 user,  load average: 0.14, 0.26, 0.16
Tasks:   3 total,   1 running,   2 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :  15949.2 total,  13308.9 free,    877.6 used,   2090.5 buff/cache
MiB Swap:   4096.0 total,   4096.0 free,      0.0 used.  15071.6 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
      1 root      20   0 1231484   7896   5568 S   0.0   0.0   0:00.02 app
     11 root      20   0    2576    860    768 S   0.0   0.0   0:00.01 sh
    201 root      20   0    8576   4512   2640 R   0.0   0.0   0:00.00 top

コンテナーの情報を表示してみます。

# cat /etc/*-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

このコンテナーは Debian GNU/Linux をベースに作成されています。つまり、Debian GNU/Linux と同じように扱うことができます。

ディレクトリ・ファイル構成

プロジェクトのファイル構成を表示してみます。

$ tree
.
├── Dockerfile
├── app.go
├── go.mod
└── go.sum

まとめ

WSL Ubuntu の Docker 環境で、Dockerfile からビルドした Go Gin Web サービスのカスタムコンテナーを起動することができました。

クラウド開発においては、Dockerfile の理解は重要です。自動ビルドツールもありますが、手動で書く必要があるケースもあります。Ubuntu を使うと Linux の知識も身に付きます。最初は難しく感じるかもしれませんが、徐々に進めていけば自信を持って書けるようになります。

どうでしたか? WSL Ubuntu で、Go Gin Web アプリケーションを手軽に実行できます。ぜひお試しください。今後も GO 言語の開発環境などを紹介しますので、ぜひお楽しみにしてください。

推奨コンテンツ

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1