自分がやたら多用しているテクなのですが、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 を叩いてみます。
ちゃんと Hello World!が返ってきます。パスは完全一致なので、最後の / がないと 404 になるので注意です。
CGI を今の時代選択する理由はあまりないですが、自分のように需要の少ない個人向けサービスを粗製乱造している人にとってはありがたいテクニックです。