Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Viacheslav Poturaev
Viacheslav Poturaev

Posted on

     

Using Nginx as a proxy to multiple Unix sockets

TL;DRListening port may be a contended resource on a busy shared machine, unix sockets are virtually unlimited. Nginx can expose them with a single port and prefixed URLs.

In some situations you may want to run many (instances of) applications on a single machine. Each instance may need to provide internal information (e.g. Prometheus/metrics, profiling/debug handlers) over restricted HTTP.

When number of instances grows it becomes a burden to provision listening ports without conflicts. In contrast, using Unix sockets allows for more transparency (readable filenames) and scalability (easy to come up with unique name).

Here is a small demo program written in Go that would serve trivial HTTP service with Unix socket.

packagemainimport("context""flag""io/fs""log""net""net/http""os""os/signal")funcmain(){varsocketPathstringflag.StringVar(&socketPath,"socket","./soc1","Path to unix socket.")flag.Parse()ifsocketPath==""{flag.Usage()return}listener,err:=net.Listen("unix",socketPath)iferr!=nil{log.Println(err.Error())return}// By default, unix socket would only be available to same user.// If we want access it from Nginx, we need to loosen permissions.err=os.Chmod(socketPath,fs.ModePerm)iferr!=nil{log.Println(err)return}httpServer:=http.Server{Handler:http.HandlerFunc(func(writerhttp.ResponseWriter,request*http.Request){log.Println(request.URL.String())if_,err:=writer.Write([]byte(request.URL.String()));err!=nil{log.Println(err.Error())}}),}// Setting up graceful shutdown to clean up Unix socket.gofunc(){sigint:=make(chanos.Signal,1)signal.Notify(sigint,os.Interrupt)<-sigintiferr:=httpServer.Shutdown(context.Background());err!=nil{log.Printf("HTTP Server Shutdown Error: %v",err)}}()log.Printf("Service is listening on socket file %s",socketPath)err=httpServer.Serve(listener)iferr!=nil{log.Println(err.Error())return}}
Enter fullscreen modeExit fullscreen mode

Now let's run a couple of instances in separate shells.

./soc -socket /home/ubuntu/soc1
Enter fullscreen modeExit fullscreen mode
./soc -socket /home/ubuntu/soc2
Enter fullscreen modeExit fullscreen mode

Here is a minimal Nginx config to serve those instances with URL prefixes. It would receivehttp://my-host/soc1/foo/bar, strip path prefix/soc1 and pass/foo/bar tosoc1.

server {    listen 80 default;    location /soc1/ {        proxy_pass http://soc1/;    }    location /soc2/ {        proxy_pass http://soc2/;    }}upstream soc1 {    server unix:/home/ubuntu/soc1;}upstream soc2 {    server unix:/home/ubuntu/soc2;}
Enter fullscreen modeExit fullscreen mode

Every Unix socket is defined asupstream and has/location statement inserver.

It is also possible to use Unix sockets directly in/location, like in

    location /soc1/ {        proxy_pass http://unix:/home/ubuntu/soc1;    }
Enter fullscreen modeExit fullscreen mode

however it has an unwanted limitation that you can not add trailing/ toproxy_pass. And this means that URL will be passed as is, e.g.soc1 will receive/soc1/foo instead of/foo.

To avoid such limitation we can use named upstream and add trailing/ toproxy_pass.

    location /soc1/ {        proxy_pass http://soc1/; # Mind trailing "/".    }
Enter fullscreen modeExit fullscreen mode

Top comments(1)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
azcraft profile image
AzCraft
A guy interested in programming, linux, tech stuff, gaming and pretty much everything.
  • Education
    Currently going to university
  • Joined

Thanks a lot, that was very useful to me. :D

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Born in the snows of Siberia, wandering around the world, seeking the gold.
  • Location
    Berlin
  • Work
    Staff Engineer at Adjust
  • Joined

More fromViacheslav Poturaev

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp