NGINX Unit
v. 1.23.0

Grafana§

Here, we install Grafana from sources so we can configure it to run on Unit.

  1. Install Unit with a Go language module.

    Also, make sure Unit’s Go module is available at $GOPATH.

  2. Download Grafana’s source files:

    $ go get github.com/grafana/grafana
    
  3. Update the code, adding Unit to Grafana’s protocol list. You can either apply a patch (grafana.patch):

    $ cd $GOPATH/src/github.com/grafana/grafana
    $ curl -O https://unit.nginx.org/_downloads/grafana.patch
    $ patch -p1 < grafana.patch
    

    Or update the sources manually. In conf/defaults.ini:

    #################################### Server ##############################
    [server]
    # Protocol (http, https, socket, unit)
    protocol = unit
    

    In pkg/api/http_server.go:

    import (
        // ...
        "net/http"
        "unit.nginx.org/go"
        "os"
        // ...
    )
    
    // ...
    
    switch setting.Protocol {
    
    // ...
    
    case setting.HTTP, setting.HTTPS, setting.HTTP2:
        var err error
        listener, err = net.Listen("tcp", hs.httpSrv.Addr)
        if err != nil {
            return errutil.Wrapf(err, "failed to open listener on address %s", hs.httpSrv.Addr)
        }
    case setting.SOCKET:
        var err error
        listener, err = net.ListenUnix("unix", &net.UnixAddr{Name: setting.SocketPath, Net: "unix"})
        if err != nil {
            return errutil.Wrapf(err, "failed to open listener for socket %s", setting.SocketPath)
        }
    case setting.UNIT:
        var err error
        err = unit.ListenAndServe(hs.httpSrv.Addr, hs.macaron)
        if err == http.ErrServerClosed {
            hs.log.Debug("server was shutdown gracefully")
            return nil
        }
    

    In pkg/setting/setting.go:

     const (
         HTTP              Scheme = "http"
         HTTPS             Scheme = "https"
         SOCKET            Scheme = "socket"
         UNIT              Scheme = "unit"
         DEFAULT_HTTP_ADDR string = "0.0.0.0"
     )
    
     // ...
    
     Protocol = HTTP
     protocolStr, err := valueAsString(server, "protocol", "http")
     // ...
     if protocolStr == "https" {
         Protocol = HTTPS
         CertFile = server.Key("cert_file").String()
         KeyFile = server.Key("cert_key").String()
     }
     if protocolStr == "h2" {
         Protocol = HTTP2
         CertFile = server.Key("cert_file").String()
         KeyFile = server.Key("cert_key").String()
     }
     if protocolStr == "socket" {
         Protocol = SOCKET
         SocketPath = server.Key("socket").String()
     }
     if protocolStr == "unit" {
         Protocol = UNIT
     }
    
  4. Build Grafana:

    $ cd $GOPATH/src/github.com/grafana/grafana
    $ go get ./...
    $ go run build.go setup
    $ go run build.go build
    $ yarn install --pure-lockfile
    $ yarn start
    

    Note the directory where the newly-built grafana-server is placed, usually $GOPATH/bin/; it’s used for the executable option in the Unit configuration.

  5. Run the following commands so Unit can access Grafana’s files:

    # chown -R unit:unit $GOPATH/src/github.com/grafana/grafana
    # chown unit:unit $GOPATH/bin/grafana-server
    

    Note

    The unit:unit user-group pair is available only with official packages, Docker images, and some third-party repos. Otherwise, account names may differ; run the ps aux | grep unitd command to be sure.

    For further details, including permissions, see the security checklist.

  6. Next, prepare the configuration (replace $GOPATH with its value in executable and working_directory):

    {
        "listeners": {
            "*:3000": {
                "pass": "applications/grafana"
            }
        },
    
        "applications": {
            "grafana": {
                "executable": "$GOPATH/bin/grafana-server",
                "type": "external",
                "working_directory": "$GOPATH/src/github.com/grafana/grafana/"
            }
        }
    }
    

    See Go application options and the Grafana docs for details.

  7. Upload the updated configuration. Assuming the JSON above was added to config.json:

    # curl -X PUT --data-binary @config.json --unix-socket \
           /path/to/control.unit.sock http://localhost/config/
    

    Note

    The control socket path may vary; run unitd -h or see Startup and Shutdown for details.

    After a successful update, Grafana should be available on the listener’s IP and port:

    Grafana on Unit - Setup Screen