Serverless Computing is an interesting concept. You can execute a script or programm without setting up the infrastructure behind it (servers, storage, networks, etc.). You just write your code and it gets executed. But Serverless doesn’t mean “without any servers” - you just don’t need to worry about them. That’s not that much of a difference to renting classic webspace from any webhosting service and putting your PHP scripts there. Nowadays Serverless usually means some kind of modern architecture that allows you to run your application code. The difference is scaling. The cloud provider handles the logic to run your serverless functions as it’s needed. When your application is not used, the execution is stopped and no computing resources are consumed.
My serverless use case
Sometimes I simply need to find out my public IP-Address, without worrying about any specific system caveats. The easiest way to find out that information, is to browse any of the roughly 1.5 billion websites that display the visitor’s IP-Address.
Thing is - these websites are really annoying, full of ads, tracking and tons of unnecessary informations. I can never be sure if any of these particular sites is actually safe to use. Even if at one point in time a site is usable, I can’t be sure if it will stay like that. I decided to make my own website to show the IP-Address.
Going Serverless with Vercel
My first attempt was to use Vercel. I’m already hosting this blog there as a static site using Jekyll with Github integration. I knew that Vercel also supports Serverless functions. I somehow got the idea to create a static Jamstack site and then fetch the IP-Address using a JavaScript AJAX request to a self-written JSON API which runs as a Serverless function.
That was actually pretty easy.
- Create a new Github repository and connect it with Vercel
- Create a “.js”-script file in the “api” subfolder.
I used this code to return the visitor’s IP-Adress as a simple JSON response:
|
|
Neat! Vercel returns the client IP-Address for every request in req.headers['x-forwarded-for']
.
I then started out to write a simple clientside JavaScript that calls the API URL to retrieve the IP-Address. Wow! That’s on-point thinking in microservices 😅.
I quickly got to a working frontend site, until I realized: Vercel doesn’t support IPv6. Woops. Nevermind I can still use my frontend, I’ll just switch my backend provider.
Switching to Serverless with Cloudflare Workers
So I switched over to Cloudflare Workers. Mainly because they do support IPv6 and IPv4. Since Cloudflare Workers is providing the visitor’s IP-Address in a different way, I had to rewrite my complete backend 🤭. I came up with this code:
|
|
Eventhough I wanted to keep it simple, I found the location info too cool to leave it out 😅. So I’m also returning an estimated location with city and country. The city-info is often not really accurate, but the country usually works.
Cool.
The static site on Cloudflare Pages
I’ve then put my static site on Cloudflare Pages. Because I didn’t want to use any overblown framework, I decided to style the site with W3.CSS and write my own simple code for the AJAX request. Also not really the best-practice JS code, but it worked for me. I even included a method to make it work in Internet Explorer 5 and 6 - eventhough I didn’t test if that actually works.
|
|
I then started out to write a function to copy the IP-Address to the user’s clipboard. There is a legacy way to do it, using document.execCommand("copy");
and a modern way via the Clipboard API navigator.clipboard.writeText();
. I decided to implement both, with the modern approach first and the old method as a fallback.
|
|
Now I’m basically done, so let’s change the architecture again 🙄.
NoScript first - Cloudflare Workers Sites
I then realized, that I didn’t like my current approach for two reasons:
- The website requires clientside JavaScript to work. I’m using NoScript (or ScriptSafe) myself and I don’t really like websites that require JS to work properly.
- To display the IP-Address on the site, the user would initiate another unnecessary GET-request. I can deliver a quicker result when serving all information in one request.
So I dug deeper and found Cloudflare Workers Sites. Essentially it combines the capabilities of Cloudflare Pages - to deliver static sites through a global CDN - and Cloudflare Workers. The static portions like .html and .css files are saved in Cloudflare KV and get distributed globally. I’m then using HTMLRewriter to just inject the IP-Address and location info into my static HTML page before delivering it to the user.
The rewriting only happens for index.html and sets the value of the HTML-elements with the ids “ipaddress” and “location” accordingly.
|
|
Conclusion
Well, the site is up and running. The source code is available on Github, feel free to check the whole thing out. I’m 100% sure: It would’ve been way easier to just use a classic shared webspace and some PHP code. But this whole process was not just about the result. It was also really interesting to check out Serverless applications and different providers. I do prefer the Cloudflare approach, because the Serverless Workers are executed globally, not only in the US like with Vercel.