gem version

Using Passenger with Go

To use Passenger with Go, you'll need to use one of the many web frameworks written in Go.

In this example we'll be using Gorilla, because it is an uncomplicated library and does not require a lot of boilerplate code.

Step 1: Install Go

Go is available from most OS' package managers. We recommend against installing manually if possible, because then you don't get updates via your package manager.

Debian & Ubuntu:

apt install -y golang-go

CentOS/Rocky/Alma:

yum install -y go-toolset

RHEL:

subscription-manager register --username $USERNAME_EMAIL --password $PASSWORD --auto-attach
subscription-manager repos --enable rhel-7-server-devtools-rpms
yum-config-manager --enable rhel-server-rhscl-7-rpms
yum install -y go-toolset-7
scl enable go-toolset-7 bash

macOS:

In order to use Homebrew to install Go on macOS, you'll need to install the command line tools, as well as Homebrew itself.

If you are physically present at the mac, you can run the following simplified commands to install everything you need:

xcode-select --install
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew install go

The following commands will install everything for you, entirely from the cli, so you can run them over ssh if need be.

touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
softwareupdate -i $(softwareupdate -l | grep "\*.*Command Line" | grep $(sw_vers -productVersion) | awk -F"*" '{print $2}' | sed -e 's/^ *//' | tr -d '\n') --verbose
rm /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew install go

Step 2: Setup your GOPATH

Choose a directory for all your Go packages, binaries and code to reside in, and then run the following commands using your chosen path. This will also test your GOPATH works by installing gorilla/mux, then checking that the gorilla/mux dir is not empty.

export GOPATH=/path/to/your/go/project/root
go get -u github.com/gorilla/mux
ls $GOPATH/src/github.com/gorilla/mux/

Step 3: Create your project

Create the file and directories you'll use for this project and cd there.

mkdir -p $GOPATH/src/localhost/testing/helloworld/
cd $GOPATH/src/localhost/testing/helloworld/
touch $GOPATH/src/localhost/testing/helloworld/main.go

Step 4: Hello world

Edit the main.go file to add the following contents:

package main

import (
  "net/http"
  "log"
  "os"
  "fmt"
  "github.com/gorilla/mux"
)

func YourHandler(w http.ResponseWriter, r *http.Request) {
  w.Write([]byte("Hello, world!\n"))
}

func main() {
  r := mux.NewRouter()

  // Routes consist of a path and a handler function.
  r.HandleFunc("/", YourHandler)

  // Get a port or choose a default
  port, ok := os.LookupEnv("PORT")
  if !ok {
    port = "80"
  }

  // Bind to a port and pass our router in
  log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), r))
}

Step 5: Build and run

Run the following commands to run the web app, which will serve the web app on port 5000, then verify that your app is being served by sending a request to the web app from another terminal.

cd $GOPATH/src/localhost/testing/helloworld/
env PORT=5000 go run main.go
# in another terminal
curl http://localhost:5000/

Step 6: Add Passenger

You will need Passenger installed, for instructions on how to install Passenger click here.

Next we will want a release build of our web app, which you can make with go build main.go, then you can move the executable into a more convenient location on your disk, such as ~/Sites/. Once you are happy with where things are, you can start your web app in Passenger by cding to the dir with the executable and running the following command: passenger start --app-start-command 'env PORT=$PORT ./main'.

Passenger requires that applications listen on a particular port that Passenger has chosen, which it provides to the application by replacing the $PORT string in its startup command with the actual port number. Regardless of how your app accepts port arguments, the startup string must be able to convert from a cli argument to what works for your app. In our example we converted the port argument to an envvar to show how one may need to change how the port is passed to your app.

You can verify that everything is working with curl http://localhost:3000. To stop Passenger simply press Ctrl+C in the terminal where you started it.

The commands to run from this section are collected here:

go build main.go
passenger start --app-start-command 'env PORT=$PORT ./main'
# in another terminal
curl http://localhost:3000
light mode dark mode
Passenger 6 Passenger 6