[Go] さくらのWebサーバーでGoのCGIを動かす

自分がやたら多用しているテクなのですが、Go で作った Web アプリケーションは簡単に CGI に変換することができます。

例えば、こんな感じです。

package main

import (
	"net/http"
	//"net/http/cgi"
	"os"

	"github.com/go-chi/chi"
)

func main() {
	rootPath := os.Getenv("SCRIPT_NAME")

	r := chi.NewRouter()
	
	r.Get(rootPath + "/", pingHandler)
	http.ListenAndServe(":9999", r)
	// cgi.Serve(r)
}

よくある Go で作られた Web サービスです。

このコメントアウトを解除し、その上の行を代わりにコメントアウトするだけで、CGI として動かすことが出来ます。

HTTPサーバーを立てる場合と CGI として動かす場合で違うのは、rootPath があることです。

前者と後者では渡されるパスが違うので、このようにして調節する必要があります。HTTPサーバーを立てる場合ではrootPath は空白になります。

自分はこうして作った CGI をさくらの Webサーバーでよく動かしています。

別にさくらのWebサーバーが特別優れているとかではないのですが、昔から契約していて、データベースもついているし、比較的自由度が高いので使い続けています。

さくらのWebサーバーで動かすためには、さくらのWebサーバー上でコンパイルするか、クロスコンパイルが必要ですが、さくらのWebサーバー上でのコンパイルはどうも失敗してしまいます。

そのため、クロスコンパイルすることにします。そのためには、まず自分の契約しているさくらのWebサーバーのOSを知る必要があります。

さくらの Webサーバーにログインして、uname -a を叩きましょう。

[nemucure@www4129 ~]$ uname -a
FreeBSD www4129.sakura.ne.jp 11.2-RELEASE-p15 FreeBSD 11.2-RELEASE-p15 #0: Fri Aug 19 12:13:37 JST 2022     root@www3666.sakura.ne.jp:/usr/obj/home/pkg/src/sys/GENERIC  amd64

このように、OS は FreeBSD のamd64 であることがわかります。自分はそうだっただけで、人によっては違うかもしないので、よく確認しましょう。

後は簡単です。ローカルでビルドする時に、以下のようなコマンドを打ちましょう。

GOOS=freebsd GOARCH=amd64 go build -o app

ここで注意したいのは、CGI として動かす場合は、app.cgi みたいな名前にしたいところなのですが、それでビルドするとなぜかサーバー上で動作しません。

[nemucure@www4129 ~/tmp/sandbox]$ ./app.cgi 
Illegal instruction

.cgi じゃない拡張子で生成したあと、いったんサーバーにアップロードし、そこで名前を .cgi に変えるとうまくいきます。

ローカルで名前を.cgiに変えても動かないようなので注意です。

これは原因が全くわからないので、ご存知の方がいらっしゃいましたらお問い合わせフォームから教えていただきたいです。

あとは、アクセスするだけです。最近作ったお小遣い帳の api を叩いてみます。

https://nemucure.sakura.ne.jp/okodukai-api/api.cgi/

ちゃんと Hello World!が返ってきます。パスは完全一致なので、最後の / がないと 404 になるので注意です。

CGI を今の時代選択する理由はあまりないですが、自分のように需要の少ない個人向けサービスを粗製乱造している人にとってはありがたいテクニックです。