Running Serverless Functions in Containers
What are Cloud Run and Knative?
Google Cloud Run was recently announced at Google Cloud Next after a private alpha period and we are finally able to talk about it. Cloud run basically allows us to deploy stateless HTTP(S) endpoints via containers without managing servers or Kubernetes clusters. Now we have a serverless platform for our Docker containers with pricing and deployment as easy as most serverless platforms. Everything is managed like scaling the container, routing traffic, custom domains and HTTPS certificates.
Cloud Run is built on Knative an open-source Kubernetes based project which gives confidence that our code/containers are still highly portable.
Check out Googles Documentation for concepts behind Cloud Run and Knative.
Building the Docker Container for Go
Cloud Run needs Docker images in our projects registry to deploy services and their revisions.
Like part 1 we are using the project Gistdirect for trying Google Cloud Run. This function serves a simple redirect service.
Go Serverless: Part 1 Google Cloud Functions
Niklas Merz ・ Apr 12 '19
NiklasMerz / gistdirect
Redirect to urls from a gist with a hostfile. Ready for serverless and Containers
gistdirect
Gistdirect is a simple URL redirection service / URL shortener.
Imagine bitly.com or goo.gl and your hosts file combined
Create a Github Gist or just any plain file hosted somewhere. Gistdirect will grap that file and redirect the alias to the full url.
Sample "host" file:
gh https://github.com
The URL to the file is provided as an environment variable: GIST_URL
. Make sure to provide an URL that is a raw textfile. If you use a GitHub Gist click on the raw button before grabbing the URL like https://gist.githubusercontent.com/NiklasMerz/a9b5905f742b5863197a0af0465a39f6/raw/
.
It is a simple Go function which is easy to run on any serverless platform. You can also run the binary somewhere and it will listen on port 8080. Executables are avaible from releases.
I got it running with Google Cloud Functions and Firebase hosting. You can deploy the function from "function.go" via the web…
We need a Docker container to run our Go function. Gistdirect has a Dockerfile similar to this Dockerfile with modifications to use Go modules, because Gistdirect is structured to use modules:
FROM golang:alpine as builder
ENV PATH /go/bin:/usr/local/go/bin:$PATH
ENV GOPATH /go
RUN apk --no-cache add gcc g++ make ca-certificates
COPY . /home/gistdirect
RUN set -x \
&& cd /home/gistdirect/main \
&& go build \
&& mv main /usr/bin/gistdirect \
&& rm -rf /go \
&& echo "Build complete."
FROM alpine:latest
RUN apk add --no-cache \
ca-certificates
COPY --from=builder /usr/bin/gistdirect /usr/bin/gistdirect
EXPOSE 8080
ENTRYPOINT ["gistdirect"]
CMD [""]
This Dockerfile builds the main.go
file which uses the redirect handler in the main()
function and makes it executable to the final Docker image we will run.
To prepare the Dockerfile for Cloud Run we need to have the gcloud
CLI tool and must be signed in to a project with billing enabled (see part 1). If you followed through part 1 use the same project to reuse your domain. We can submit our project to Google Cloud Build which builds the image and puts it into the registry of our project.
gcloud builds submit --tag gcr.io/[PROJECTID]/gistdirect
Deploying to Cloud Run
Creating the service is really easy with the Google Cloud Console. Just go to Cloud Run, “Create new Service”, Select the image, set the environment variable and we are good to go.
When the service is ready we get a URL like this: gistdirect-khsgfjhsg-uc.a.run.app
and that’s our function.
Get a nicer domain
If you followed through part 1 you probably already set up and verified a domain to this project. You can go to the Cloud Run main page and select “Manage custom domain”. There you can use your previously added domain, set another custom domain and map it to your service. Once HTTPS is ready and you did the CNAME change in your DNS, you are ready to call your container.
Top comments (1)
Hi Niklas, thank you for your article. One question: what about docker-compose. Nowadays it's very uncommon to have a single image, usually you have more than one and run them with docker-compose