GolangをFastCGIとしてApacheと共に動かす


tl;dt

Go言語のnet/http/fcgiを使ってGoをCGIとしてApacheで動かしました。

動かす

git clone https://github.com/nozo-moto/golang-fastcgi-try
cd golang-fastcgi-try
make docker-build
dokcer-compose up

確認

$ curl localhost:8888
{"message":"pong"}

net/http/fcgi

Go言語にはnet/http/fcgiというFastCGI protocolが実装されたパッケージがあります。

これは以下のようにhttp.Handlerをラップしてあげて使えます。今回はginを使っています。

package main

import (
    "net"
    "net/http/fcgi"

    "github.com/gin-gonic/gin"
)

func main() {
    var err error
    r := gin.Default()
    r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "pong",
        })
    })
    l, err := net.Listen("tcp", ":8080")
    if err != nil {
        panic(err)
    }
    if err := fcgi.Serve(l, r); err != nil {
        panic(err)
    }
}

動かす

以下のようなdocker-composeを用意します
以下ではてきとうなコンテナに上のGoのコードのバイナリを入れて実行しています。

version: '3.3'
services:
  www:
    image: httpd:2.4.41
    ports:
        - "8888:80"
    depends_on:
        - fcgi
    volumes:
        - ./docker/apache/conf/fcgi.conf:/usr/local/apache2/conf/extra/fcgi.conf
    command: bash -c "echo 'Include conf/extra/fcgi.conf' >> /usr/local/apache2/conf/httpd.conf && httpd-foreground"
  fcgi:
    image: nozomi0966/fastcgi-golang-try

fcgi.conf

ApacheでfastCGIを実行するための設定ファイルを書きます
上記のdocker-compose.ymlで./docker/apache/conf/fcgi.confに書いたのを読んでいます。
Apache2.4以降からmod_proxy_fcgiというモジュールが入っているのでそれを使います。
docker-composeでfcgiというホスト名で引けるように動かしているので以下のようにfcgi:8080でアクセスします。

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
SetHandler "proxy:fcgi://fcgi:8080/"

以下を実行してApacheとFastCGIを動かします。

docker-compose up

以下のようなレスポンスが返ってくれば動いてるのが確認できます。

$ curl localhost:8888
{"message":"pong"}

以上

以下のリポジトリにコードを載せています
https://github.com/nozo-moto/golang-fastcgi-try