This quickstart will get you going with Go on Heroku.
- Basic knowledge of Go, including the
go
command line tool and packagehttp
. - Your application must build in Go 1 using standard Go directory structure.
- A Heroku user account. Signup is free and instant.
We'll start by setting up your local workstation with the Heroku command-line client and the Git revision control system; and then logging into Heroku to upload your ssh
public key. If you've used Heroku before and already have a working local setup, skip to the next section.
See the Heroku Toolbelt site for installation.
Once installed, you'll have access to the heroku
command from your shell. Log in using the email address and password you used when creating your Heroku account:
$ heroku login
Enter your Heroku credentials.
Email: kr@example.com
Password:
Could not find an existing public key.
Would you like to generate one? [Yn]
Generating new SSH public key.
Uploading ssh public key /Users/kr/.ssh/id_rsa.pub
Press enter at the prompt to upload your existing ssh
key
or create a new one, used for pushing code later on.
It's easiest to install Go from one of the official Go packages provided by the Go team.
See the Go getting started page for full installation instructions and How to Write Go Code to learn how best to set up your local environment, including what values to use for environment variables and which directories to use. Here's a summary.
Make a directory to hold all your Go source:
$ mkdir -p $HOME/gocode/src
The go tools use env var GOPATH
to find source code to build
on your system, so put the following in your $HOME/.profile
:
GOPATH=$HOME/gocode export GOPATH
And run
$ . $HOME/.profile
to pick up this change in your current shell.
Now it’s time to create a simple “hello, world” application.
First, make a directory to hold your new Heroku app, and initialize an empty git repository there:
$ mkdir -p $GOPATH/src/example.com/server
$ cd $GOPATH/src/example.com/server
$ git init
Here’s the actual application code:
package main
import (
"fmt"
"log"
"net/http"
"os"
)
func main() {
http.HandleFunc("/", hello)
err := http.ListenAndServe(":"+os.Getenv("PORT"), nil)
if err != nil {
log.Fatal("ListenAndServe:", err)
}
}
func hello(w http.ResponseWriter, req *http.Request) {
fmt.Fprintln(w, "hello, world!")
}
The Go buildpack recognizes Go apps by the existence of a .go
source file
anywhere in the repository.
Your app and its dependencies are built all together by the go
command-line tool.
You can build your app using go get
:
$ go get
To run your web process, you need to declare what command to use.
In this case, we simply need to execute our Go program. We’ll use
Procfile
to declare how our web process type is run.
Foreman is documented in the foreman man page and Heroku's Procfile support in a separate devcenter article.
Here's a Procfile
for the sample app we've been working on:
web: server
Now that you have a Procfile
, you can start your application with Foreman:
$ foreman start
13:58:29 web.1 | started with pid 5997
Your app will come up on port 5000. Test that it's working with curl
or a web browser, then Ctrl-C to exit.
The go
tool uses the directory name of your project to name executables and determine package import paths, but the Go buildpack doesn't have direct access to this information, so you have to tell it. Cretate a file called .godir
, in your project root, containing the path from $GOPATH/src
to your project root, in this case example.com/server
:
$ echo example.com/server >.godir
We now have the three pieces of our app: application source in app.go
,
process types in Procfile
, and the path to the project. Let's put it into Git:
$ git add .
$ git commit -m init
Create the app:
$ heroku create
Creating pure-sunrise-3607... done, stack is cedar
http://pure-sunrise-3607.herokuapp.com/ | git@heroku.com:pure-sunrise-3607.git
Git remote heroku added
and tell it to use the Go Buildpack:
$ heroku config:add BUILDPACK_URL=git://github.com/kr/heroku-buildpack-go.git
Adding config vars:
BUILDPACK_URL => git://github.com...dpack-go.git
Restarting app... done, v1.
Deploy your code:
$ git push heroku master
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (6/6), 687 bytes, done.
Total 6 (delta 0), reused 0 (delta 0)
-----> Heroku receiving push
-----> Fetching custom buildpack... done
-----> Go app detected
-----> Using Go go1
-----> Running go get and go install
-----> Discovering process types
Procfile declares types -> web
-----> Compiled slug size is 1.0MB
-----> Launching... done, v1
http://pure-sunrise-3607.herokuapp.com deployed to Heroku
To git@heroku.com:pure-sunrise-3607.git
* [new branch] master -> master
Now, let's check the state of the app's processes:
$ heroku ps
UPID Process State Command
-------- ------------ ------------------ ------------------------------
19237303 web.1 up for 11m server
The web process is up. Review the logs for more information:
$ heroku logs
2012-08-03T01:17:15+00:00 heroku[api]: Deploy db538ce by kr@example.com
2012-08-03T01:17:15+00:00 heroku[api]: Release v4 created by kr@example.com
2012-08-03T01:17:16+00:00 heroku[slugc]: Slug compilation finished
2012-08-03T01:17:19+00:00 heroku[web.1]: Starting process with command `server`
2012-08-03T01:17:20+00:00 heroku[web.1]: State changed from starting to up
Looks good. We can now visit the app with heroku open
.
The Procfile
format lets you run any number of different process types. For example, let's say you wanted a worker process to complement your web process. Just add another directory containing the source code for your worker command, work/work.go
, and build as usual with the go
tool:
$ go get ./work
web: server
worker: work
(Running more than one dyno for an extended period may incur charges to your account. Read more about dyno-hour costs.)
Push this change to Heroku, then launch a worker:
$ heroku scale worker=1
Scaling worker processes... done, now running 1
Check heroku ps
to see that your worker comes up, and heroku logs
to see your worker doing its work.