<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Khaled Monsoor</title>
    <description>The latest articles on DEV Community by Khaled Monsoor (@kmonsoor).</description>
    <link>https://dev.to/kmonsoor</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F48773%2Fcb1a23c9-6400-4a9f-8e1c-73523a812c3a.jpg</url>
      <title>DEV Community: Khaled Monsoor</title>
      <link>https://dev.to/kmonsoor</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kmonsoor"/>
    <language>en</language>
    <item>
      <title>Personal short-link server using only Caddy webserver</title>
      <dc:creator>Khaled Monsoor</dc:creator>
      <pubDate>Thu, 22 Apr 2021 01:58:22 +0000</pubDate>
      <link>https://dev.to/kmonsoor/personal-short-link-server-using-only-caddy-webserver-pjh</link>
      <guid>https://dev.to/kmonsoor/personal-short-link-server-using-only-caddy-webserver-pjh</guid>
      <description>&lt;p&gt;Post originally published on &lt;a href="https://blog.kmonsoor.com/personal-shortlink-server-using-Caddy/" rel="noopener noreferrer"&gt;my blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Before I go into any details, please note that I've used the term "shortlink-server" instead of "url-shortener" because the difference is significant for this post.&lt;br&gt;&lt;br&gt;
A "url-shortener" takes a long url, and gives a short url, then redirects any requests for the shortened link to its long counterpart. On the contrary, shortlink-server takes both the long and short url, then only does the redirect-ion part.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F4nZbnUE.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F4nZbnUE.png" alt="Simple, on-prem short-link server using Caddy webserver"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Backstory
&lt;/h2&gt;

&lt;p&gt;If I wanted an amazing, personal url-shortener or "go link" server, there are many amazing solutions out there, which are not only free or open-source but full-fledged as well for personal or public usage. Rather, I wanted some "service" that will "resolve" my personal, short links. I have been using bit.ly for a long time for its customizable "short-half" part, but the problem with bit.ly is -- for some God-forsaken reason -- blocked by the Bangladeshi govt. So, I needed a replacement to be properly "glocal".&lt;br&gt;
There are many free (unbranded) and commercial (branded) options as well, but I wanted something that will be resolved via my hosted service (and personal domain) and as cheap as possible. So, basically solution for a poor nerd :D&lt;/p&gt;

&lt;p&gt;Before jumped into this solution, I tried (deployed &amp;amp; tested) few others myself, mainly &lt;a href="https://github.com/kellegous/go" rel="noopener noreferrer"&gt;kellegous/go&lt;/a&gt;, &lt;a href="//kutt.it"&gt;kutt.it&lt;/a&gt; and &lt;a href="https://github.com/adamyi/golinks" rel="noopener noreferrer"&gt;adamyi/golinks&lt;/a&gt;. But, all of them "too featureful" for my needs. &lt;/p&gt;

&lt;p&gt;What I wanted is to be able to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;resolve only my custom short-links (hence, no need for url-shortener)&lt;/li&gt;
&lt;li&gt;not a public, internet-facing service (hence, any frontend, authentication, email verification etc. would be overkill )&lt;/li&gt;
&lt;li&gt;minimal setup (if possible, no webapp at all)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Given my previous experience with &lt;code&gt;Caddy&lt;/code&gt; webserver, which is an amazing one(&lt;a href="https://caddyserver.com/docs/" rel="noopener noreferrer"&gt;why?&lt;/a&gt;), I had a gut feeling that Caddy has something for me -- under the sleeve -- to meet my minimal set of requirements. Thankfully, I managed to find it.&lt;/p&gt;

&lt;p&gt;I believe NGINX, currently the most popular webserver, has some kind of similar mechanism as well. But, I'm not an expert, and once I was genuinely intimidated by its config file syntax. YMMV.&lt;/p&gt;
&lt;h2&gt;
  
  
  What you gonna need?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;your own domain which will be the root of the short-links. While "sub-domained" URL like &lt;code&gt;go.yourname.com/*&lt;/code&gt; is quite common, if you have some short domain, like you.co/*, only for this purpose, that's fine as well.&lt;/li&gt;
&lt;li&gt;A webhost server or public-facing instance with its own, &lt;strong&gt;public&lt;/strong&gt; IPv4 address.&lt;/li&gt;
&lt;li&gt;working knowledge of Linux&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Step-1: Point your subdomain to the right place
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Find out what's the &lt;strong&gt;public IPv4 address&lt;/strong&gt; of your instance that'll act as the webserver. It's usually on the cloud management dashboard.

&lt;ul&gt;
&lt;li&gt;make sure that, regardless of your cloud architecture (e.g. VPC, subnet, firewall etc.), the SSL port (&lt;code&gt;:443&lt;/code&gt;) of the instance is reachable from the public internet.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;now go to your domain name registrar (or, DNS management provider which in my case is Cloudflare). There, you need to point the short-link subdomain (&lt;code&gt;go.&lt;/code&gt;)to the webserver's IP address.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Actually, you can do this step at the last. But for some reason, I prefer to do it first. Because sometimes, &lt;a href="https://blog.cloudflare.com/never-deal-with-dns-propagation-again/" rel="noopener noreferrer"&gt;DNS propagation delay&lt;/a&gt; takes some time. But, once my webservice is up and running, I like to see the result instantaneously. ;)&lt;/p&gt;
&lt;h2&gt;
  
  
  Step-2: Install Caddy, the mighty webserver
&lt;/h2&gt;

&lt;p&gt;Depending on your host OS (mine is Ubuntu 20.04 LTS), you need to install the &lt;code&gt;Caddy&lt;/code&gt; webserver. While there are some hacky solutions to run, I think running Caddy as a background server is the simplest to manage.&lt;br&gt;
In fact, the documentation of Caddy is excellent, I'd better leave that part to you. &lt;/p&gt;

&lt;p&gt;After running with the default config(&lt;code&gt;Caddyfile&lt;/code&gt;) which is in Ubuntu's case located as &lt;code&gt;/etc/caddy/Caddyfile&lt;/code&gt;, it should have a status somewhat like the below image. Please note that, in many cases, if running without &lt;code&gt;sudo&lt;/code&gt; Caddy cannot attach itself with the SSL port (&lt;code&gt;:443&lt;/code&gt;) which is necessary for serving &lt;code&gt;https://&lt;/code&gt;.  So, check for that error message in the "status" log.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FcfS5nvZ.png%3F1" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FcfS5nvZ.png%3F1" alt="Caddy service on Ubuntu"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;**P.S.&lt;/em&gt;* By the way, want your console and command prompt to look 🚀 like mine? Here's the guide: &lt;a href="https://blog.kmonsoor.com/pimp-up-my-terminal/" rel="noopener noreferrer"&gt;How do I pimp up my terminal on Linux&lt;/a&gt;*&lt;/p&gt;
&lt;h2&gt;
  
  
  Step-3: Tell Caddy your short-links to redirect
&lt;/h2&gt;

&lt;p&gt;Now, it's time to configure Caddy to actually do the job.&lt;/p&gt;

&lt;p&gt;Caddy has its native &lt;code&gt;redir&lt;/code&gt; "directive" to redirect incoming web-request from one to another. While the &lt;code&gt;map&lt;/code&gt; directive is relatively new, it makes the config file i.e. Caddyfile look elegant in case you have (or, will have in the long run) a long list of short-links.&lt;/p&gt;

&lt;p&gt;Here's mine which is working ...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# /etc/caddy/Caddyfile

go.kmonsoor.com {   # replace it your web-url root

    map {path} {redirect-uri} {
        /blog    https://blog.kmonsoor.com
        /photos  https://photos.kmonsoor.com

        /resume     https://drive.google.com/file/d/1nMS3i1ai6nsI70zZ7NFnNQ_XmvAa4GOl
        /resume-doc https://docs.google.com/document/d/1ECx1Yr8Jzz9I3S5VcoKnZQz56oIht2XaM5gSNetcWag

        /rickrolled    https://www.youtube.com/watch?v=dQw4w9WgXcQ

        # will add new ones here like the above
        # ...
    }

    # this below code is required to actually make the above `map` work

    @hasRedir expression `{redirect-uri} != ""`
    redir @hasRedir {redirect-uri}

    # code below is to set the default response if the requested shortlink isn't here
    respond "Thas's an unknown short URL ... :("  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: Don't forget to restart the &lt;code&gt;caddy&lt;/code&gt; service to let the new config to take effect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step-4: Profit !
&lt;/h2&gt;

&lt;p&gt;Yeah, that's it. Now, add some own personal stuff with some cool short-links, and proudly share with the world.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next ?
&lt;/h2&gt;

&lt;p&gt;I'm thinking that given the very low workload my shortlink resolver needs — unless I'm becoming an overnight internet sensation — using a server instance only for this purpose is overkill. My next goal is to have the same service using some "serverless" function or using the "&lt;a href="https://developers.cloudflare.com/workers/examples/redirect" rel="noopener noreferrer"&gt;worker on the edge&lt;/a&gt;" thing from Cloudflare. Let's see ;)&lt;/p&gt;

</description>
      <category>caddyserver</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
