スクリプトのお勉強

Go 言語で作る!単一バイナリで動くモダンな Web UI アプリケーション

投稿日:

はじめに

Web アプリケーションを開発する際、アーキテクチャの選択は常に悩ましい問題です。「巨大なモノリスは開発が進むにつれて複雑化し、マイクロサービスは管理が煩雑になる…。」そんなジレンマを抱えている開発者は少なくないでしょう。

特に、社内管理ツールや小規模な Web サービスを開発する際に、「単機能でシンプルに保ちたいけれど、ユーザー体験(UX)も妥協したくない」というニーズは非常に高まっています。

この記事では、そんな課題を解決するための一つの答えとして、Go 言語の単一バイナリモダンなフロントエンド技術(DaisyUI + HTMX)を組み合わせた、新しい Web アプリケーションの形を提案します。

実際に動作するサンプルプロジェクトは、ここで公開しています。

このアーキテクチャが目指すもの

このアプローチのゴールは、以下の 2 つの要素を両立させることです。

  1. 圧倒的な管理のしやすさ: すべてのリソース(HTML, CSS, JavaScript)を Go の実行ファイルに埋め込むことで、デプロイは単一のバイナリファイルをコピーするだけで完了します。依存関係やランタイムの心配はもういりません。
  2. 高品質な Web UI: Go のサーバーサイドレンダリングを基本としつつも、DaisyUI(Tailwind CSS)で美しい UI を迅速に構築し、HTMX で JavaScript をほとんど書かずにリッチな動的体験を実現します。

これにより、「モノリシックな開発のシンプルさ」と「関心事の分離によるメンテナンス性」のいいとこ取りを目指します。

なぜこの技術スタックなのか?

バックエンド: Go + Echo + embed

  • Go 言語: コンパイルが高速で、クロスプラットフォーム対応のシングルバイナリを簡単に生成できます。標準ライブラリも強力です。
  • Echo フレームワーク: 高性能で拡張性の高い、Go の Web フレームワークです。ルーティングやミドルウェアの扱いが直感的で、迅速な開発をサポートします。
  • embed パッケージ: Go 1.16 から導入された標準機能で、これにより静的ファイルやテンプレートをコンパイル時にバイナリに埋め込むことができます。これが「単一バイナリ」の鍵となります。
// web/web.go
package web

import (
	"embed"
	// ...
)

//go:embed templates static
var content embed.FS // templatesとstaticディレクトリの内容をバイナリに埋め込む

// ...

//go:embedというディレクティブ一行で、指定したディレクトリがコンパイル後のバイナリに内包されます。

フロントエンド: DaisyUI + HTMX

  • Tailwind CSS & DaisyUI: Tailwind CSS は、ユーティリティファーストな CSS フレームワークで、デザインの自由度を保ちながら効率的にスタイリングが可能です。DaisyUI は、その上に構築されたコンポーネントライブラリで、「ボタン」や「カード」といった UI 部品をクラス名だけで美しく実装できます。
  • HTMX: 「なぜ JSON をやり取りするためだけに JavaScript をたくさん書く必要があるんだ?」という発想から生まれたライブラリです。HTML の属性としてサーバーへのリクエストを記述するだけで、サーバーから返された HTML フラグメントをページの特定の部分に差し込むことができます。これにより、React や Vue のような大規模なフレームワークを導入することなく、インタラクティブな UI を実現できます。
<!-- web/templates/index.html -->
<!-- ボタンをクリックすると/helloにGETリクエストを送信し、
     結果をid="message-area"の要素に差し込む -->
<button
  class="btn btn-primary mt-4"
  hx-get="/hello"
  hx-target="#message-area"
  hx-swap="outerHTML"
>
  メッセージを更新
</button>

<div id="message-area" class="mt-4 p-4 border rounded-md bg-base-200"></div>

アプリケーションの仕組み

リクエストが来てからブラウザにページが表示されるまでの流れは非常にシンプルです。

  1. 起動: main.goがアプリケーションを起動し、Echo サーバーを立ち上げます。
  2. リクエスト受付: Echo のルーターがリクエストを受け取り、対応するハンドラ関数を呼び出します。
  3. テンプレートレンダリング: ハンドラは c.Render() を呼び出し、Go の html/template エンジンを使って HTML を生成します。このとき、embedされたテンプレートファイル(index.htmlbase.html)が使われます。
  4. レスポンス返却: 生成された HTML がブラウザに返されます。
  5. 動的更新 (HTMX): ユーザーが HTMX が適用された要素(例:ボタン)を操作すると、指定されたエンドポイントに非同期リクエストが送信されます。サーバーは HTML の断片(フラグメント)を返し、HTMX がそれをページの適切な場所に差し込みます。ページ全体のリロードは発生しません。

この構成により、バックエンドは Go のロジックに集中でき、フロントエンドは HTML と CSS(クラス名)中心で記述できるため、関心事がきれいに分離されます。

動作環境

WSL2上で作成/確認しています。

  • WSL2
    • ubuntu 24.04
  • golang 1.23.11
  • nodejs v22.17.0

どうやって始めるか?

このテンプレートを試すのはとても簡単です。

1. リポジトリをクローン

git clone https://github.com/KenichiTanino/golang_echo_onebinary.git
cd golang_echo_onebinary

2. 依存関係をインストール

# Goモジュール
go mod tidy

# Node.jsパッケージ (Tailwind CSS/DaisyUI用)
npm install

3.フロントエンドアセットを準備

既にリポジトリにあるファイルを使用しても構いません

# HTMXライブラリをダウンロード
curl -o web/static/js/htmx.min.js https://unpkg.com/htmx.org@1.9.10/dist/htmx.min.js

# CSSをビルド
npx tailwindcss -i ./assets/input.css -o ./web/static/css/app.css --minify

4. 開発サーバーを起動

  go run ./cmd/app

ブラウザで `http://localhost:8080` を開いてみてください。

5. バイナリビルド

go build -o myapp ./cmd/app

生成された `myapp` という単一のファイルが、今回のアプリケーションです。このファイルをサーバーにコピーして実行するだけで、デプロイは完了です。

まとめ

Go 言語による単一バイナリのシンプルさと、DaisyUI + HTMX によるモダンなフロントエンド開発の生産性を組み合わせることで、管理が容易でありながら高品質な UI を持つ Web アプリケーションを効率的に構築できます。

このアプローチは、以下のようなプロジェクトに特に有効です。

  • 社内向けの管理画面やダッシュボード
  • 設定変更やステータス確認のための Web UI を持つ CLI ツール
  • IoT デバイスの管理インターフェース
  • 小〜中規模の Web サービス

「マイクロサービスはまだ早い、でもモノリスは避けたい」——そんな状況に対する現実的で強力な解決策として、この「Go 製シングルバイナリ Web アプリ」をぜひ試してみてはいかがでしょうか。

-スクリプトのお勉強
-

執筆者:

関連記事

poetry installでJSONDecodeError

小ネタです。OSをアップデートしたので、その他もいろいろアップデートしようとしたらエラーになったので、メモとして書いておきます。 WSL2のUbuntuを 22.04 LTSにアップデート は、さほど …

MySQL MCP Serverを設定/動作確認してみる

はじめに 今はやりの生成AIとして、LLM(ローカルAPI)とMySQLのMCP Serverを使用してチャットシステムを作ろうと思います。 その前に、前回作成したDBへのMySQL MCP Serv …

SPAMチェック for OCN の アップデート(v0.7.0)

以前、ここで書いたように、SPAMチェックのThunderbirdプラグインを作りました。 そして、Thunderbirdがアップデートしたので、Pluginもアップデートする必要があります。 正直放 …

Djangoアプリサンプル – 画像ファイルアップロード + 顔モザイク(画像アップロード編)

仕事で使用している、Djangoについて、サンプルを作成してみようと思います。ここでは、画像ファイルのアップロードと顔モザイクを行うwebアプリを作成してみようと思います。 この記事ではファイルアップ …

no image

GLP-1 メディカルダイエット 58日目

メディカルダイエットして58日目の記録をしておこうと思います。 9回目。 今回は左腹(中部)に打ちました。痛いのはいまだに慣れない。。 土曜にゲットしてした 渋谷に行ってきたが、そこの医院には相変わら …

google オプトアウト Click here to opt-out.