TIL: Deploying Go apps on Heroku
2022-01-11 00:00:00 +0000 UTCI recently deployed my projects recipe randomizer and mdbssg to Heroku. I had never deployed anything to Heroku before (having only used cloud offerings like EC2 and Digital Ocean droplets in the past), so I learned a few things.
- Heroku’s Go buildpack supports a lot of different Go projects.
- Heroku also supports Docker builds on even free-tier projects now.
Since I was already familiar with building Go apps in Docker, I decided to take that route. That means writing a Dockerfile like this:
##
## BUILD
##
FROM golang:1.17-bullseye AS build
WORKDIR /app
COPY go.mod ./
COPY go.sum ./
RUN go mod download
COPY *.go ./
COPY models/*.go ./models/
COPY handlers/*.go ./handlers/
COPY templates/*.html ./templates/
RUN go build -o /reciperandomizer
##
## Deploy
##
FROM gcr.io/distroless/base-debian10 AS deploy
WORKDIR /app
COPY /reciperandomizer ./reciperandomizer
COPY templates/*.html ./templates/
USER nonroot:nonroot
ENTRYPOINT [ "/app/reciperandomizer" ]
Using a multi-stage build as advised by the Docker docs for Go.
This also requires a heroku.yml
file that tells Heroku how to deploy any container(s) your app needs:
build:
docker:
web: Dockerfile
run:
web: ./app/reciperandomizer
Now you can create a Heroku app for your project and set the heroku build stack to container.
$ heroku app:create
$ heroku stack:set container
$ git push heroku master
And Heroku will build your Docker container and run your app as instructed in the heroku.yml
file. Note there is no EXPOSE
directive in the Dockerfile. This is because Heroku will assign a port to your app just like when deploying a non-dockerized app on heroku.