ドッカーを使用したGoアプリの開発

Go(またはGolang)は、 スタックオーバーフローの2022年開発者調査によると、最も愛され、求められているプログラミング言語の1つです。 他の多くの言語に比べてバイナリサイズが小さいため、開発者はコンテナ化されたアプリケーション開発にGoを使用することがよくあります。 

Mohammad Quanit 氏は、 コミュニティ オールハンズ セッションで Docker と Go の関係を探りました。 Mohammad 氏は、プロセスに関連する各コア コンポーネントを探索しながら、基本的な Go アプリケーションを Docker 化する方法を共有しました。 

これらのコンテナ化の手順を詳しく説明してください。 HTTP Web サーバーで Go アプリケーションを使用する方法に加えて、主要なベスト プラクティス、最適化のヒント、セキュリティを強化する方法について説明します。 

Go アプリケーションのコンポーネント

本格的な Go アプリケーションを作成するには、Go 固有のコンポーネントをいくつか作成する必要があります。 これらは多くのGoプロジェクトにとって不可欠であり、コンテナ化プロセスはそれらに等しく大きく依存しています。 それらを詳しく見てみましょう。 

main.go と go.mod を使う

Mohammadは、実行可能コードなしではアプリを実行できないため、 main.go 主にファイルを強調表示します。 Mohammad の場合、彼は 2 つの固有のルートを持つ単純な Web サーバーを作成しました: 機能を持つ print I/O 形式と、現在の時刻を返す形式です。

メイン。 印刷機能を備えたI / O形式のWebサーバーと、現在の時刻を返すルートを作成するGoファイル。

モハマドの例の良いところは、長すぎたり複雑すぎたりしないことです。 独自のWebサーバーを作成するときにこれをエミュレートすることも、さらにカスタマイズするための足がかりとして使用することもできます。

手記: ファイルの代わりに main.go を使用することもできます package main 。Webサーバーに明示的に指定する必要はありません main.go - ファイルに好きな名前を付けることができるので - しかし、コード内で定義する必要があります func main () 。 これは上記のサンプルに存在します。

コードが期待どおりに動作することを常に確認することをお勧めします。 コマンド go run main.go を入力して、アプリケーションをスピンアップします。 または、ファイルの特定の名前に置き換える main.go こともできます。 次に、ブラウザを開き、http://localhost:8081 にアクセスして、「Hello World」メッセージまたは同等のメッセージを表示します。 2つのルートがあるため、http://localhost:8081/time に移動すると、Mohammadの2番目の機能のおかげで現在の時刻が表示されます。 

次に、ファイルがあります go.mod 。 これを Go パッケージの ルート ファイル 、インポート用のモジュール パス (上図)、および依存関係の要件として使用します。 Goモジュールは、プロジェクトコードのディレクトリを選択するのにも役立ちます。 

これら2つのピースを配置したら、 Dockerfile

ドッカーファイルの作成

Dockerized Go アプリケーションをビルドしてデプロイするということは、ソフトウェア イメージから始めることを意味します。 これは (CLI を使用して) Docker Hub から直接プルできますが、 Dockerfile から始めると 、構成の柔軟性が高まります。 

このファイルは、 VS Code などのお気に入りのエディター内で作成できます。 VS Code は公式の Docker 拡張機能をサポートしているため、お勧めします。 この拡張機能は、デバッグ、オートコンプリート、および簡単なプロジェクトファイルナビゲーションをサポートしています。 

基本イメージの選択とアプリケーション コードの組み込みは非常に簡単です。 Mohammad は Go を使用しているため、 golang Docker 公式イメージを 親イメージとして指定することで開始しました Dockerfile 。 Dockerはこれから最終的なコンテナイメージをビルドします。 

好きなバージョンを選択できますが、次のような golang:1.19.2-bullseye 固定バージョンは安定していてスリムです。 このような新しいイメージバージョンも、 2022年10月のText4Shellの脆弱性から安全です。 

また、以下 Dockerfileを実行する必要があります。 

  • ソースコード用のアプリディレクトリを含める
  • ルートディレクトリからappディレクトリにすべてをコピーします
  • Goファイルをアプリディレクトリにコピーし、依存関係をインストールします
  • 構成を使用してアプリをビルドする
  • 実行時に特定のポートでリッスンするようにDockerコンテナに指示する
  • コンテナーの起動時に実行される実行可能コマンドを定義する

これらの点を念頭に置いて、モハマドが彼の基本 Dockerfileをどのように構成したかは次のとおりです。

# Specifies a parent image
FROM golang:1.19.2-bullseye

# Creates an app directory to hold your app’s source code
WORKDIR /app

# Copies everything from your root directory into /app
COPY . .

# Installs Go dependencies
RUN go mod download

# Builds your app with optional configuration
RUN go build -o /godocker

# Tells Docker which network port your container listens on
EXPOSE 8080

# Specifies the executable command that runs when the container starts
CMD [ “/godocker” ]

ここから、簡単な CLI コマンドを実行して、このファイルからイメージをビルドできます。 

ドッカービルド--rm -t [あなたのイメージ名]:アルファ。

これにより、ビルドプロセス全体で各イメージレイヤー(またはステップ)で作成された中間コンテナを削除しながら、イメージが作成されます。 また、後で参照しやすいように、画像に名前を付けます。 

次のコマンドを実行して docker image ls 、Docker によってイメージが正常にビルドされたことを確認します。

docker image ls コマンドを実行し、イメージが正常にビルドされたことを示すターミナル。

過去にイメージをプルまたはビルドして保持している場合は、CLI 出力にも表示されます。 ただし、モハマドの go-docker 画像は最新のものであるため、上部にリストされていることがわかります。 

運用環境のワークロードを変更する

本番環境のGoアプリケーションで必然的に発生するコードや依存関係の変更を考慮する場合はどうすればよいでしょうか。 Mohammadによると、オリジナル Dockerfile を微調整し、いくつかの指示を追加して、変更が表示され、ビルドプロセスが成功するようにする必要があります。

FROM golang:1.19.2-bullseye

WORKDIR /app

# Effectively tracks changes within your go.mod file
COPY go.mod .

RUN go mod download

# Copies your source code into the app directory
COPY main.go .

RUN go mod -o /godocker

EXPOSE 8080

CMD [ “/godocker” ]

これらの変更を行った後、同じ docker build コマンドを実行 docker image ls する必要があります。 次に、新しいイメージを実行します。 次のコマンドを入力して、イメージからコンテナーを起動します。 

docker run -d -p 8080:8081 --name go-docker-app [あなたのイメージ名]:アルファ

コンテナのリストを生成するコマンドを入力して docker ps 、これが機能することを確認します。 Docker Desktop がインストールされている場合は、Docker ダッシュボードから [コンテナー] タブにアクセスして、一覧で新しい コンテナー を見つけることもできます。 これはイメージのビルドにも適用され、代わりに [イメージ] タブを使用します。 

万丈! Mohammad のステップをたどることで、機能している Go アプリケーションをコンテナ化することに成功しました。 

おすすめの方法と最適化

Goアプリケーションは仕事を成し遂げますが、Mohammadの最終的な画像は913MBとかなり大きいです。 クライアント (またはエンド ユーザー) は、このような大量のファイルをダウンロードする必要はありません。 

Mohammadは 、マルチステージビルドを使用して 、画像レイヤー間で必要なコンポーネントのみをコピーフォワードすることをお勧めします。 ビルダーイメージとして golang:version から始めますが、2番目のビルドステージを定義し、次のような alpine スリムな代替ステージを選択すると、イメージサイズを縮小するのに役立ちます。 これに取り組む ための彼の段階的なアプローチを見ることができます 。 

これは有益であり、多くのユースケースで一般的です。 ただし、マルチステージビルドで使用することで FROM scratch 、さらに一歩進めることができます。 この空のファイルは、私たちが提供する最小のファイルで、静的バイナリを実行可能ファイルとして受け入れるため、Goアプリケーションの開発に最適です。 

スクラッチ イメージの詳細については、Docker Hub を参照してください。ハブにいるにもかかわらず、プルするのではなく、直接 Dockerfile 追加 scratch することしかできません。 

今すぐGoアプリケーションを開発

Mohammad Quanitは、新しいGoユーザーと経験豊富なGoユーザーの両方に利益をもたらすことができるいくつかのユーザーフレンドリーな開発ワークフローの概要を説明しました。 彼の手順とベスト プラクティスに従うことで、スリムでパフォーマンスの高いクロスプラットフォームの Go アプリを作成できます。 Docker と Go は本質的にうまく連携しているため、コンテナ化によって何が可能になるかを調べることもお勧めします。 

もっと詳しく知りたいですか?