Go で書いた Web アプリケーションを UNIX ドメインソケットで公開

カテゴリー: 学習  閲覧数:310 配信日:2018-04-28 15:53


nginxユーザーのユーザIDやグループIDを表示してみる


# id nginx
uid=994(nginx) gid=992(nginx) groups=992(nginx)

$ go run index.go

mkdir /var/run/go/: file exists
chown not permitted


ファイル操作


mkdir
・既にある場合エラーとなるため、コメントアウト

下記ファイルは動作確認できたので、既に削除済
▼/var/www/◇◇/go-demo.w4c.work/index.go
package main

import (
    "os"
    "fmt"
    "net"
    "net/http"
    "net/http/fcgi"
)

func handler(res http.ResponseWriter, req *http.Request) {
    fmt.Fprint(res, "Hello World!")
}

func main() {
//    if err := os.Mkdir("/var/run/go/", 0777); err != nil {
//        fmt.Println(err)
//    }
    os.RemoveAll("/run/go/go-fcgi.sock")
    l, err := net.Listen("unix", "/run/go/go-fcgi.sock")
    if err != nil {
        return
    }
    os.Chmod("/run/go/go-fcgi.sock", 0777)
    if err := os.Chown("/run/go/go-fcgi.sock", 994, 992); err != nil {//uid=994,gid=992
        fmt.Println("chown not permitted")
    }
    http.HandleFunc("/", handler)
    fcgi.Serve(l, nil)
}


下記ファイルは現在も運用中
▼/var/www/◇◇/go-demo.w4c.work/demo/a2.go
package main

import (
   "os"
   "fmt"
   "net"
   "net/http"
   "net/http/fcgi"
   "path/filepath"
)

func handler(res http.ResponseWriter, req *http.Request) {
   fmt.Fprint(res, "Hellow World! こんにちは 世界!")
}

func main() {
//    if err := os.Mkdir("/var/run/go/", 0777); err != nil {
//        fmt.Println(err)
//    }
   exe, err := os.Executable()
   os.RemoveAll("/run/go/app/" + filepath.Base(exe) + ".sock")
   l, err := net.Listen("unix", "/run/go/app/" + filepath.Base(exe) + ".sock")
   if err != nil {
       return
   }
   os.Chmod("/run/go/app/" + filepath.Base(exe) + ".sock", 0777)
   if err := os.Chown("/run/go/app/" + filepath.Base(exe) + ".sock", 994, 992); err != nil {//uid=994,gid=992
       fmt.Println("chown not permitted")
   }
   http.HandleFunc("/", handler)
   fcgi.Serve(l, nil)
}


Go言語入門(ファイル・ディレクトリ操作)
逆引きGolang (ファイル)

コマンド起動


ファイル内容を変更する度に、下記コマンド入力が必要
$ sudo go run index.go
・最初にsocketファイル削除しないと動作しない
・理由不明
▼index.go
package main
import (
   "os"
   "fmt"
   "net"
   "net/http"
   "net/http/fcgi"
)

func handler(res http.ResponseWriter, req *http.Request) {
   fmt.Fprint(res, "113H33ello World!sss22")
}

func main() {
//    if err := os.Mkdir("/var/run/go/", 0777); err != nil {
//        fmt.Println(err)
//    }
   os.RemoveAll("/run/go/go-fcgi.sock")
   l, err := net.Listen("unix", "/run/go/go-fcgi.sock")
   if err != nil {
       return
   }
   os.Chmod("/run/go/go-fcgi.sock", 0777)
   if err := os.Chown("/run/go/go-fcgi.sock", 994, 992); err != nil {//uid=994,gid=992
       fmt.Println("chown not permitted")
   }
   http.HandleFunc("/", handler)
   fcgi.Serve(l, nil)
}


UNIX ドメインソケットファイルの置き場


ソケットファイルの置き場
・/var/run を経由するよう設定

注意事項(2018/8/16に追記)
・下記を設定しなくても、Go で書いた Web アプリケーションを UNIX ドメインソケットで公開できる
・しかし、何かのタイミングでCentOSを再起動した際、トラブルに見舞われる
・設定しておくに越したことはないが、内容が分かりづらいので、身をもってトラブルを体験してから試してみた方が良いかも

/usr/lib/tmpfiles.d/に設定ファイルを追記
CentOS7再起動時に、/run 直下に作成したディレクトリを削除しないようにする
・「/run/go/app」ディレクトリを作成するようにしているが、「/run/go」ディレクトリで良かったと思われ
・d /var/run/app 777 [UID] [GID]
d /run/go/app 777 root root

最初にsocketファイル削除するか、終了時に(次回のために)UNIXソケットのファイルを削除するか
Golang で書いた Web アプリケーションを UNIX ドメインソケットで公開
golang製WAFのgojiでfastcgiを使ってnginxと連携する
終了時にUNIXソケットのファイルを削除するようにするのは、なぜですか?