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.
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.
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 — : — : — — : — : — — : — : — 31271Downloading Caddy for linux/amd64 (personal license)…
Download verification OK
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)
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.
Caddyfile that should do the trick.
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
- Redirect HTTP to HTTPS with an
- And just for fun let’s use the Caddy
headerdirective 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:
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.comServing HTTP on port 80
INVOKE YOUR Fn FUNCTION
After starting Caddy let’s test out a function.
Dans-Machine:~ dan$ curl — request GET — url https://fnmedium.example.com/t/myapp/hello
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
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.