Golangアプリケーションをデプロイする方法

How to Deploy a Golang App

Go (Golang)は、2009年にGoogleによって開発されたプログラミング言語で、コンパイルに時間がかかったり、並行プログラミングが必要だったりと、大規模システム開発における共通の問題に対処するために開発された。

さらに、Goはコンパイルされるため、インタープリタ型言語よりも高速だ。

Goの主な特徴のひとつは、ゴルーチン(Goroutines)と呼ばれる軽量スレッドによって複数のタスクを同時に実行できる並行処理のサポートだ。

Goはまた、ネットワーキングとウェブ開発を強力にサポートしていることでも知られている。Goの標準ライブラリには、HTTP、TCP/IP、その他のネットワークプロトコルのパッケージがあり、ネットワークアプリケーションを簡単に構築できます。

この記事では、Go アプリの利点、制限、デプロイオプションを探ります。さらに、Back4app のコンテナ化サービスを使用して、Go アプリケーションを作成、Docker 化、デプロイします(無料)。

Goアプリのデプロイ方法については、続きをお読みください。

ウェブ開発におけるGolangの利点

Goの人気が高まっているのは偶然ではない。アプリケーションにGoを使うことで得られる利点はたくさんある。

ハイパフォーマンス

高性能は、DropboxやUberのような企業がGoを使う主な理由のひとつです。Goは実行時間が速くなるように設計されているため、高いパフォーマンスを必要とするアプリケーションには理想的な言語です。

Goはガベージ・コレクターを採用し、オーバーヘッドのメモリ管理を削減することで、より高速な実行時間を実現しています。さらに、Goの組み込み並行性サポートを使用して、アプリケーションのパフォーマンスを向上させることができます。

スケーラビリティ

Goはスケーラブルなアプリの構築に最適です。並行処理(Concurrency)を使えば、多くのタスクを処理できるプログラムを作成できるため、素早くスケールアップする必要がある高トラフィック負荷を扱うアプリに適している。

また、Goは分散システムのサポートにも優れているため、複数のマシンで実行する必要がある大規模なアプリケーションの構築に最適だ。

囲碁は実戦テスト済み

Google、Uber、Dropboxなど、多くの人気企業が大規模アプリケーションの構築にGoを使用している。これは、Goが大規模なユーザーベース向けの複雑なアプリケーションを構築するための信頼性と安定性が実戦で検証されていることを意味する。

Goは後方互換性を強く重視しており、Golangで書かれたアプリケーションは言語が進化しても動き続けます。

素晴らしい地域サポート

Goがリリースされて以来、Goは最も急速に普及した言語の1つであり、そのため大規模で活発なコミュニティが形成されています。Goに活発なコミュニティがあるということは、リソースや質問への回答を簡単に見つけることができるということです。

Goには、開発時間を短縮するために使えるオープンソースのライブラリやツールがたくさんある。Kubernetes、Docker、Hugoのような人気のあるビルドツールは、CLIツールでCobraのようなパッケージを使用しています。

Golangの限界

Golangは高いパフォーマンスとスケーラビリティを持つプログラミング言語ですが、Goには制限があります。

特定のタスクの複雑化

Goは学ぶのも読むのも簡単かもしれませんが、特定のタスクはGoよりも他の言語の方が簡単です。Goは組み込みのGUIツールキットを必要とし、サードパーティーのパッケージはプロジェクトに複雑さをもたらすため、Goでインタラクティブなユーザーインターフェースを構築するのは難しいかもしれません。

Goの同時実行モデルは初心者には難しいかもしれない

Goの並行処理モデルは、初心者が理解し、効果的に使用するのは難しいかもしれません。Goは並行処理にゴルーチンとチャネルを使います。これは強力なツールですが、理解するのは難しいかもしれません。デッドロックやレースコンディションを避けるために、チャンネルを効果的に使うことを学ばなければなりません。

Goの並行処理モデルでは、コードの構造や設計についてもこれまでとは違った考え方をする必要がある。逐次的なプログラミング・モデルに慣れていると、これは難しいと感じるだろう。

他の言語に比べて成熟していないライブラリーのエコシステム

Golangの標準ライブラリは包括的で、Goアプリを作るのに必要なほとんどの機能を備えていますが、JavaやPythonのような言語のライブラリに比べると成熟していません。

Golangは比較的新しいプログラミング言語なので、人気のあるライブラリのいくつかはまだ利用できません。これは、特定のプロジェクト、特により専門的な機能を必要とするプロジェクトにとっては制限となり得ます。

加えて、Golang用のサードパーティライブラリは他の言語で利用できるものに比べてあまり普及しておらず、いくつかの機能を自分で実装する必要があるかもしれません。

Golangのデプロイメント・オプション

Goでアプリをビルドした後、いくつかのデプロイオプションがあり、それぞれに利点と欠点がある。

AWSのようなIaaSサービス、HerokuのようなPaaSサービス、Back4appやGoogle FirebaseのようなBaaSサービス、Back4App ContainersのようなCaaSサービスなど、幅広い選択肢がある。

AWSのようなIaaS(インフラストラクチャー・アズ・ア・サービス

Amazon Web Services(AWS)のようなIaaS(Infrastructure as a Service)プロバイダーは、クラウド上に所有する仮想マシンをデプロイし管理する機能を提供している。

AWSでは、Elastic Compute Cloud(EC2)のようなサービスを使って、LinuxやWindowsを実行する仮想マシン上にGolangアプリケーションをデプロイできます。Elastic Container Service (ECS)のようなサービスを使って、アプリケーションをコンテナにデプロイすることもできます。

AWSのようなIaaSサービスを利用する利点の1つは、基盤となるインフラを完全にコントロールできることだ。特定の要件に合わせて仮想マシンを構成することができる。しかし、仮想マシンを管理・維持するのはお客様の責任であり、技術的な負担も大きい。

その他のIaaSプラットフォームには次のようなものがある:

  • Linode
  • Microsoft Azure
  • Rackspace
  • Amazon Web Services (AWS)
  • DigitalOcean
  • Google Compute Engine (GCE)

HerokuのようなPlatform as a Service (PaaS)

HerokuのようなPlatform as a Service (PaaS)プロバイダは、基礎となるインフラに負担をかけることなくGolangアプリケーションをデプロイするためのプラットフォームを提供します。

Herokuはシンプルなコマンドラインインターフェイスを提供し、いくつかのコマンドを実行するだけでアプリケーションをデプロイできます。Herokuはまた、自動スケーリングとロードバランシングをサポートしており、アプリケーションの高トラフィックへの対応を容易にします。

HerokuのようなPaaSサービスを利用する利点は、インフラを気にすることなくアプリケーションの開発に集中できることです。Herokuがインフラ管理とメンテナンスをすべて行うので、時間とリソースを節約できます。

しかし、これはインフラをコントロールする力が弱く、プラットフォームの制限の中で仕事をしなければならないことを意味する。

その他のPaaSプロバイダーは以下の通り:

  • Render
  • AWS Elastic Beanstalk
  • Microsoft Azure App Service
  • DigitalOcean App Platform
  • The Fly Platform

Back4appのようなサービスとしてのバックエンド(BaaS)

Google FirebaseやBack4appのようなBackend as a Service (BaaS)プロバイダは、データベース、認証、ホスティングを含む、アプリケーションのための完全なバックエンドソリューションを提供する。Firebaseは、Golangを含むいくつかのプログラミング言語をサポートし、サービスにアクセスするためのシンプルなAPIを提供しています。

FirebaseのようなBaaSサービスを使う利点の一つは、インフラを管理することなく、アプリケーションのバックエンドを素早く簡単にセットアップできることだ。Firebaseは様々な機能とサービスを提供するが、インフラをよりコントロールする必要がある。

その他のBaaSプラットフォームには以下のようなものがある:

  • AWS Amplify
  • Cloudkit
  • Backendless
  • Back4App
  • Pocketbase

Back4app Containersのようなサービスとしてのコンテナ化

コンテナ化はアプリケーションのデプロイによく使われる。コンテナ化では、アプリケーションとその依存関係をコンテナにパッケージ化し、コンテナ技術をサポートするあらゆるプラットフォームに素早くデプロイできる。

Back4Appはサービス・プロバイダとしてのコンテナ化で、Golangアプリケーションをコンテナ内にデプロイして管理するのに使えます。

Back4Appのようなサービスプロバイダとしてコンテナ化を利用する利点の1つは、基盤となるインフラを気にすることなく、コンテナをサポートするあらゆるプラットフォームにアプリケーションをデプロイできることです。

CaaSプロバイダーがコンテナの管理とメンテナンスをすべて行うため、時間とリソースを節約できる。しかし、インフラにアクセスすることなく、コンテナ化プラットフォームの制限内で作業しなければならない場合もある。

その他のCaaSプラットフォームには以下のようなものがある:

  • AWS Container Service
  • Azure Container Service
  • Docker Enterprise
  • Google Container Engine
  • IBM Kubernetes Service
  • Oracle Container Service

Golangのデプロイメント・プロセス

ここでは、GolangアプリをBack4appのCaaSプラットフォームにデプロイする方法を学びます。

Back4appとは?

Back4appは、モバイル・アプリケーションやウェブ・アプリケーションのバックエンド・サービスを作成し、デプロイするために使用できるクラウド・オファリングです。

Back4appのCaaS機能を使って、Back4appのバックエンドサーバー上にカスタムコンテナをデプロイし、実行することができます。サーバーインフラを管理することなく、コンテナイメージを使ってアプリにカスタムロジックを追加することができます。

このセクションでは、GoでシンプルなCRUD RESTful APIを構築し、Goプログラムをコンテナ化し、コンテナをBack4appにデプロイする方法を学びます。

開発環境のセットアップ

ダウンロード・ページからマシンにGoをインストールしたら、新しいディレクトリを作成し、Goアプリ用の新しいGoプロジェクトを初期化できます。

以下のコマンドを実行して、プロジェクト用の新しいディレクトリを作成する。

mkdir deployAPI && cd deployAPI

mod initコマンドを実行して、現在の作業ディレクトリにある新しいプロジェクトをGoツールで初期化する。

こんな感じだ:

go mod init

Gorilla Muxパッケージを使ってRESTful APIを構築します。

以下のコマンドを実行して、Gorilla Muxパッケージをプロジェクトの依存関係としてインストールします。

go get -u github.com/gorilla/mux

次のステップは、RESTful APIを構築することだ。Gorilla MuxでRESTful APIを構築する最初のステップは、Goファイルに必要なパッケージをインポートすることだ。

プロジェクトに必要なインポートのリストはこちら。

import (
	"encoding/json"
	"log"
	"net/http"
	"strconv"

	"github.com/gorilla/mux"
)

インポートをリストアップしたら、アプリ用のデータベースをセットアップする必要があります。ここでは簡単のため、データの保存と取得にマップを使用します。

アプリケーションにマップを追加するには次のようにする:

var users = map[int]string{}

マップは空なので、POSTリクエストでデータを入力する必要があります。

POSTリクエストハンドラ関数

POSTリクエストは、クライアントからデータを受け取り、それを解析し、マップデータストアに保存する必要があります。

アプリケーションにコードブロックを追加して、POST リクエストハンドラを実装します:

func createUserHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	id, err := strconv.Atoi(vars["id"])
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	var data map[string]string

	err = json.NewDecoder(r.Body).Decode(&data)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	users[id] = data["name"]

	w.WriteHeader(http.StatusCreated)
}

createUserHandlerハンドラ関数は、クライアントからデータ(JSON)を受け取り、JSONを解析し、データをマップに保存する。ハンドラがマップへのデータ追加に成功すると、StatusCreated成功コードをクライアントに書き込みます。

GETリクエスト

GETリクエストでデータストアからデータを読み取ります。GETリクエストハンドラ関数は、クライアントからIDを取得し、データを検索してクライアントに返します。

アプリケーションにコードブロックを追加して、GETリクエストハンドラを実装する:

func readUserHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	id, err := strconv.Atoi(vars["id"])
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	name, ok := users[id]
	if !ok {
		w.WriteHeader(http.StatusNotFound)
		return
	}

	data := map[string]string{"name": name}

	jsonData, err := json.Marshal(data)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	w.Write(jsonData)
}

readUserHandler関数は、muxパッケージのVars関数でIDを取得し、StatusOkの成功コードとともにデータをJSONとしてクライアントに返す前に、マップを通してデータを検索する。

PUTリクエストハンドラ関数

データストアのデータをPUTリクエストで更新します。PUTリクエスト・ハンドラは、更新処理用のIDとJSONフィールドを受け取ります。

func updateUserHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	id, err := strconv.Atoi(vars["id"])
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	var data map[string]string

	err = json.NewDecoder(r.Body).Decode(&data)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	users[id] = data["name"]

	w.WriteHeader(http.StatusOK)
}

updateUserHandler関数は、vars変数でIDを受け取り、リクエストボディからJSONをデコードし、リクエストボディからのJSONデータでフィールドまたはIDを更新する。

DELETEリクエストハンドラ関数

DELETEリクエストハンドラ関数は、リクエストからフィールドIDを受け取り、データストアからフィールドを削除します。

アプリケーションにコードブロックを追加して、DELETEリクエストハンドラを実装する:

func deleteUserHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	id, err := strconv.Atoi(vars["id"])
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	delete(users, id)

	w.WriteHeader(http.StatusOK)
}

deleteUserHandler関数は、マップ名と ID を受け取るdelete関数でフィールドを削除し、StatusOkコードをクライアントに返します。

ハンドラ関数をルートにマウントする

アプリのエンドポイントを定義したら、ハンドラ関数をルーティングに割り当てる必要がある。ルートはAPIのパブリックインターフェースです。

func main() {
	r := mux.NewRouter()

	r.HandleFunc("/users/{id}", createUserHandler).Methods(http.MethodPost)
	r.HandleFunc("/users/{id}", readUserHandler).Methods(http.MethodGet)
	r.HandleFunc("/users/{id}", updateUserHandler).Methods(http.MethodPut)
	r.HandleFunc("/users/{id}", deleteUserHandler).Methods(http.MethodDelete)

	log.Fatal(http.ListenAndServe(":8080", r))
}

main関数では、rは新しいmuxルーターのインスタンスで、HandleFuncメソッドはルートとハンドラー関数を取り込む。Methods関数はルートのHTTPメソッドを指定する。

DockerでGoアプリをコンテナ化する

Dockerは最も人気のあるコンテナ化技術の1つです。DockerはGoで構築されており、GoアプリをDockerでコンテナ化して移植することができます。

新しいdockerfileを作成し、そこにビルド手順を指定する必要がある。

以下のコマンドを実行し、プロジェクトの作業ディレクトリにDockerfileを作成する。

touch Dockerfile

Dockerファイルを開き、以下のビルド手順を貼り付けて、GoアプリをDockerでコンテナ化します。

# Use an official Golang runtime as a parent image
FROM golang:latest

# Set the working directory to /app
WORKDIR /app

# Copy the current directory contents into the container at /app
COPY . /app

# Download and install any required dependencies
RUN go mod download

# Build the Go app
RUN go build -o main .

# Expose port 8080 for incoming traffic
EXPOSE 8080

# Define the command to run the app when the container starts
CMD ["/app/main"]

dockerfile のビルド手順では、プロジェクトの Go バージョン、作業ディレクトリ、アプリのファイル、dockerfile のビルド手順を指定します。

Dockerfileの内訳は以下の通り:

  • このファイルはFROM golang: latestで始まり、公式Golangイメージの最新バージョンをDockerコンテナのベースイメージとして使いたいことを指定します。
  • WORKDIR /app行は、コンテナの作業ディレクトリを/appディレクトリに設定する。
  • COPY ./appは、カレントディレクトリの内容をコンテナの/appディレクトリにコピーする。
  • RUN go mod downloadは、アプリに必要な依存関係をダウンロードします。
  • RUN go build -o main .はGoアプリをコンパイルし、/appディレクトリにmainという実行ファイルを作成します。
  • EXPOSE 8080の行は、Dockerに8080番ポートを公開するよう指示する。
  • CMD ["/app/main"]行は、コンテナ起動時に実行するコマンド(この場合はメイン実行ファイル)を指定する。

dockerfileを実行すると、Dockerはアプリのイメージをビルドし、8080番ポートにアプリを公開する。

このコマンドはコンテナを起動し、ホストマシンのポート8080をコンテナのポート8080にマップする。[http://localhost:8080](http://localhost:8080)のAPIにアクセスできるはずである。

Back4appにコンテナをデプロイする

コンテナをデプロイするには、Back4appのアカウントを作成する必要がある。

Back4appのアカウント作成手順は以下の通りです。

  1. Back4appのウェブサイトへ
  2. ランディングページの右上にあるサインアップボタンをクリックし、新しいアカウントを作成してください。
  3. 最後に、登録フォームに必要事項を記入して送信する。

Back4appアカウントを作成後、アカウントにログインし、UIの右上にあるNEW APPボタンをクリックしてください。

NEW APPボタンを押すと、アプリのデプロイ方法を選択するページに移動します。コンテナをデプロイするので、Containers as a Serviceオプションを選択する。

Back4appで新しいCaaSアプリを作成する

次に、GitHubアカウントをBack4appアカウントに接続します。Back4appにアカウント内の全てのリポジトリのソースコードへのアクセス権を与えるか、特定のプロジェクトディレクトリへのアクセス権を与えるかを選択できます。

Back4app コンテナ - GitHub リポジトリをインポートします。

デプロイしたいアプリケーション(この場合は、このチュートリアルでビルドしたアプリケーション)を選択し、[Select]をクリックします。

Back4app コンテナ - git リポジトリを選択する

選択ボタンをクリックすると、名前からブランチ、ルートディレクトリ、環境変数まで、アプリに関する情報を記入するページに移動する。

アプリケーションが必要とする環境変数をすべて入力してください。必要事項を入力したら、Create Appをクリックします。

このボタンをクリックすると、下の画像に示すように、Go アプリケーションのデプロイメント プロセスが開始されます。

Back4appコンテナデプロイメントページ

結論

コンテナ化されたGoアプリをBack4appにデプロイする方法を学びました。このチュートリアルのステップに従って、Back4app上でGo APIを実行することができます。

アプリケーションをBack4Appにデプロイすることで、バックエンドのインフラ管理を簡素化できます。Back4Appは、データの管理、アプリケーションのスケーリング、パフォーマンスのモニタリングのための強力なツールを提供します。サーバーを管理するのではなく、優れたアプリケーションを構築したいと考えている開発者には最適な選択肢です。

よくあるご質問

Back4App とは何ですか? また、アプリを展開するのに適したプラットフォームである理由は何ですか?

Back4App は、サーバーレス アーキテクチャを使用してアプリケーションを構築、ホスト、拡張できる BaaS プラットフォームです。Back4app は、基盤となるインフラストラクチャの管理を気にすることなくソフトウェア コンテナを管理および展開できるコンテナ化サービスも提供しています。

コンテナを使用して、Back4app に Rust などの他の言語をデプロイできますか?

はい、Docker などのコンテナ化テクノロジーを使用して、Back4App に Rust をデプロイできます。Back4App は、Rust を含むさまざまなプログラミング言語で記述されたアプリケーションをデプロイするために使用できる Docker コンテナをサポートしています。

Back4App でコンテナ化されたアプリケーションをスケーリングできますか?

はい、組み込みの自動スケーリング機能を使用して、Back4App でコンテナ化されたアプリケーションをスケーリングできます。自動スケーリング機能は、需要に基づいてアプリケーションのインスタンスの数を自動的にスケーリングし、アプリがトラフィックとワークロードの増加に対応できるようにします。


Leave a reply

Your email address will not be published.