Fn Project & Caddy for Fun & Learning

Dan Anderson
Fn Project
Published in
5 min readMar 25, 2019

As a Product Manager who does some weekend hacking, I love finding open source projects and technologies that help demonstrate important concepts in the web services world. As I crawl up the technology learning curve it’s great to take seemingly abstract concepts such as containers and serverless and employ them in simple but illustrative ways.

I was an early user of Iron.io for hosted workers and enthusiastically followed co-founders Chad Arimura (@chadarimura) and Travis Reeder (@treeder) as Iron.io gained traction in the marketplace.

When I heard that Chad and Travis’ focus moved to the Fn Project, I jumped at the chance to try it to build a deeper understanding of serverless and FaaS. I deployed the Fn server to a Digital Ocean “droplet” and never looked back. I used the Fn Project to support prototypes and personal projects so my requirements were rudimentary such as functions for messaging (text, email) and basic file processing.

One need that surfaced was invoking functions in a more secure manner. Since my deployment was exposed to the web rather than behind an enterprise or cloud firewall, that meant at least making https requests. What was not on my short list of concepts to learn was complex web server configuration and obtaining SSL certificates.

Enter Caddy, one of my other favorite open source projects from Matt Holt (@mholt6) and a team of fellow contributors. Caddy (https://caddyserver.com/) is an open source web server and an early player in automatic provisioning of free SSL certificates (Let’s Encrypt certs).

Caddy is awesome. A simple download for personal use and a few lines in a config file (the “Caddyfile”) and I can set up a simple proxy, automatically provision & install SSL certificates, serve static sites, and route traffic to other web services running on non-public ports. I had found my answer!

Use Caddy as a Proxy to the Fn Server

Here’s how to get started.

Get yourself over to https://caddyserver.com and download Caddy. I downloaded the version applicable to my Digital Ocean Linux server. Caddy has a rich ecosystem of plugins to enable things like integrating with DNS providers and standing up a simple file browser. But for our purposes (use https, proxy to the Fn Server) we can just use Caddy right out of the box.

Caddy download page

DOWNLOAD AND INSTALL CADDY

On the server running the Fn server, I opted to use the handy shell script suggested on the Caddy site.

CADDY_TELEMETRY=on curl https://getcaddy.com | bash -s personal

and you’ll get something like this:

% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 7380 100 7380 0 0 31271 0 — : — : — — : — : — — : — : — 31271
Downloading Caddy for linux/amd64 (personal license)…
Download verification OK
Extracting…
Backing up /usr/local/bin/caddy to /usr/local/bin/caddy_old
(Password may be required.)
Putting caddy in /usr/local/bin (may require password)
Caddy 0.11.5 (non-commercial use only)
Successfully installed

After installation, we’ll configure Caddy.

CREATE A ‘Caddyfile’ CONFIG FILE

Caddy reads a configuration file called a Caddyfile. I have a personal domain for small projects so I added a subdomain to point to my Digital Ocean instance. Caddy will use this domain to automatically provision a Let’s Encrypt SSL certificate.

Here’s a Caddyfile that should do the trick.

fnmedium.example.com {
proxy / localhost:8080
header / X-Custom-Header “Courtesy of Caddy”
}

A few lines of text will actually accomplish my objectives:

  • Provision and install an SSL certificate for my subdomain: fnmedium.example.com
  • Listen for requests to http://fnmedium.example.com (port 80) and https://fnmedium.example.com (443)
  • Proxy those requests to the Fn Server listening on the default Fn port localhost:8080
  • Redirect HTTP to HTTPS with an HTTP 301 redirect
  • And just for fun let’s use the Caddy header directive to insert a custom header to ensure Caddy is in the mix

FIRE UP CADDY

The install script put Caddy in my path. You can start Caddy in the same folder as the Caddyfile or elsewhere specifying the file’s location.

caddy -conf ~/app/caddy/Caddyfile

Caddy will start the certificate provisioning and the output will look similar to:

Activating privacy features…Your sites will be served over HTTPS automatically using Let’s Encrypt.
By continuing, you agree to the Let’s Encrypt Subscriber Agreement at:
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf
Please enter your email address to signify agreement and to be notified
in case of issues. You can leave it blank, but we don’t recommend it.
Email address:
...[INFO] [fnmedium.example.com] acme: Obtaining bundled SAN certificate
INFO] [fnmedium.example.com] AuthURL: https://acme-v02.api.letsencrypt.org/acme/authz/ks3...
[INFO] [fnmedium.example.com] acme: use tls-alpn-01 solver
[INFO] [fnmedium.example.com] acme: Trying to solve TLS-ALPN-01
[INFO] [fnmedium.example.com] The server validated our request
[INFO] [fnmedium.example.com] acme: Validations succeeded; requesting certificates
[INFO] [fnmedium.example.com] Server responded with a certificate.
done.
Serving HTTPS on port 443
https://fnmedium.example.com
Serving HTTP on port 80
https://fnmedium.example.com

INVOKE YOUR Fn FUNCTION

After starting Caddy let’s test out a function.

I stepped through the Fn Project Go tutorial and set up a “Hello World” function. With an external function trigger configured, we can now invoke the function via an HTTP call.

Dans-Machine:~ dan$ curl — request GET — url https://fnmedium.example.com/t/myapp/hello
{“message”:”Hello World”}

Here’s output describing what’s going on under the hood:

> GET /t/myapp/hello HTTP/1.1
> Host: fnmedium.example.com
> User-Agent: xxxx
> Accept: */*
< HTTP/1.1 200 OK
< Content-Length: 26
< Content-Type: text/plain; charset=utf-8
< Date: Wed, 20 Mar 2019 18:12:51 GMT
< Fn-Call-Id: 01D6E4WJVYNG8G00GZJ000000A
< Server: Caddy
< X-Custom-Header: Courtesy of Caddy

Mission Accomplished

And we’re done.

What I love about both the Fn Project and Caddy is that I can deploy, run, and forget. I’ve been executing a core set of functions for years without any hassle or disruption. I’m able to satisfy my core requirements without complex configuration.

I definitely recommend Fn for serverless function type calls and Caddy for pain-free web server capabilities.

Dan Anderson is a Product Manager at JDK Technologies.

--

--

Dan Anderson
Fn Project

Product development mensch. I dig Go, Angular, MongoDB, and Lean Startup. Studying Data Science at Lambda School (DSPT4)