Introduction
Hey, hey! 👋 Are you ready to continue learning how to work with GitHub Actions and get to know it better? Perfect! Today, we will create your own link shortener to simplify interaction on the Internet.
So where's GitHub Actions? Almost everywhere, because that's main part! We'll use it at its full power to add new links, reboot a web server and deploy a friendly index page of your shortener website.
📝 Table of contents
- What will we build?
- Register domain name
- Configure remote virtual server
- Configure GitHub Actions for deploys
- Questions for better understanding
- Exercises for independent execution
🤔 What will we build?
We will build the URL shortener for only important links, that you always use and which you won't change often.
👀 For example, for a slide in your presentation with contact information or for downloading a useful snippet from your repository (for easily
wget
manipulations) or for a shorter version of link to YouTube video... and so on.
All right, here's our plan:
- Register domain name
- Configure remote virtual server
- Configure a separate branches of the same GitHub repository
- Configure GitHub Actions for deploys
- Push-to-Deploy
Repository structure
As I said earlier, we will split our repository into two branches:
-
master
branch will contain the main scenario (a list of shortened URLs) -
website
branch will contain the index page of your website (a "hello" message for curious users)
☝️ Please note: in this case, the unfolding of two branches will go independently of each other. Thank you, GitHub Actions!
Structure of master
branch:
.
├── .github
│ └── workflows
│ └── urls_deploy.yml # <-- GitHub Action
└── short_urls_list.conf # <-- List of shorted URLs (NGINX config)
Structure of website
branch:
.
├── .github
│ └── workflows
│ └── website_deploy.yml # <-- GitHub Action
└── index.html # <-- Index page of website
🌐 Register domain name
At the very beginning of our exciting journey, let's define the domain name for your project. I was lucky enough to register the domain name shrts.website
or similar, which fully matches to our idea: make shorten links to websites.
😉 Fun fact: I've been using this domain name registrar for over 14 years (to be exact, since October 2006) and I'm still fully satisfied with its prices and support.
You can play with different combinations and abbreviations, but the main purpose of the domain for a such project → simplicity and ease of remembering!
⚙️ Configure remote virtual server
To avoid repeating myself, I'm not going to describe in detail the process of configuring the virtual server and just give you links to my articles, where I already described it:
- Create a new droplet on DigitalOcean
- Setup virtual server via
snippets-deploy
- Create a private SSH key for GitHub Actions deploys
🤖 Configure GitHub Actions for deploys
Let's start with the most interesting part: setting up GitHub Actions.
GitHub secrets
Here's a list of all the secrets we need:
-
REMOTE_HOST
– IP address of your virtual server -
REMOTE_USER
– user on your virtual server (notroot
, please) -
REMOTE_NGINX_DIR
– full path to your NGINX folder for place snippets (by default, it should be/etc/nginx/snippets
) -
REMOTE_WEBSITE_DIR
– full path to your website root folder (if you setup your virtual server viasnippets-deploy
, it should be/var/www/<domain>/html
) -
SSH_KEY
— the contents of a PRIVATE part (~/.ssh/gha_rsa
) of the SSH key, that we generated in Private key for SSH section of my previous article -
SSH_KEY_PASSPHRASE
— the passphrase of the SSH key, that we entered, when generating the SSH key
☝️ Please read part of my previous article entitled "Understanding the GitHub secrets", if you want to know more about it.
List of shorted URLs
Let's get started with NGINX config for your <domain>
on remote virtual server.
Connect to server and open config in nano
editor. Go to main server {...}
section and add include snippets/short_urls_list.conf;
line after index index.html;
, like this:
# /etc/nginx/sites-available/<domain>.conf
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name <domain>;
root /var/www/<domain>/html;
index index.html;
include snippets/short_urls_list.conf; # <-- include file with URLs redirects
ssl_certificate /etc/letsencrypt/live/<domain>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<domain>/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/<domain>/chain.pem;
# ...
❗️ Attention: do not forget to change
<domain>
to yours.
Good! 👍 Now, create snippet with shorten URLs in your GitHub repository:
# short_urls_list.conf
rewrite /link-1 https://huge-example-1.com/very-long/link/1 permanent;
As you can see, these are common 301 Moved Permanently
redirect from https://<domain>/link-1
to another link (https://huge-example-1.com/very-long/link/1
in this example).
Now, we've to create GitHub Action config for master
branch:
# .github/workflows/urls_deploy.yml
name: Deploy new short URLs via SSH
on:
push:
branches: [master] # triggered only if pushed to master branch
jobs:
build:
runs-on: ubuntu-latest
steps:
# Checks-out repository under $GITHUB_WORKSPACE
- uses: actions/checkout@master
# Copying files to server via SSH
- name: Copying files to server
uses: appleboy/scp-action@master
with:
host: ${{ secrets.REMOTE_HOST }}
username: ${{ secrets.REMOTE_USER }}
key: ${{ secrets.SSH_KEY }}
passphrase: ${{ secrets.SSH_KEY_PASSPHRASE }}
source: "short_urls_list.conf"
target: "${{ secrets.REMOTE_NGINX_DIR }}"
# Restart NGINX after deploy
- name: Restart NGINX
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.REMOTE_HOST }}
username: ${{ secrets.REMOTE_USER }}
key: ${{ secrets.SSH_KEY }}
passphrase: ${{ secrets.SSH_KEY_PASSPHRASE }}
script: sudo nginx -t && sudo systemctl restart nginx
Website index page
Switch to website
branch and create an index page (simple index.html
file) for the website of your taste.
👌 It could be some kind of welcome text describing your shortener or whatever you want. Fantasize about it!
And, finally, we're ready to create GitHub Action for website
branch:
# .github/workflows/website_deploy.yml
name: Deploy website via SSH
on:
push:
branches: [website] # triggered only if pushed to website branch
jobs:
build:
runs-on: ubuntu-latest
steps:
# Checks-out repository under $GITHUB_WORKSPACE
- uses: actions/checkout@master
# Copying files to server via SSH
- name: Copying files to server
uses: appleboy/scp-action@master
with:
host: ${{ secrets.REMOTE_HOST }}
username: ${{ secrets.REMOTE_USER }}
key: ${{ secrets.SSH_KEY }}
passphrase: ${{ secrets.SSH_KEY_PASSPHRASE }}
source: "index.html"
target: "${{ secrets.REMOTE_WEBSITE_DIR }}"
Let's deploy it!
Commit & push changes to your repository (for both branches) and visit https://<domain>
to see website index page, like this:
Now, hit your shortened link to make sure everything works as intended.
Yep, it just works! 🎉
Add new link
To add a new link, all you need to do is add it to the short_urls_list.conf
file (in the master
branch) and make push.
That's all! Cool, isn't it? 😎
💬 Questions for better understanding
- What should be the domain name for the link shortener?
- Due to what redirect from a short link to the original occurs?
- Which parameter in the GitHub Actions config is responsible for triggering job by branch name?
✏️ Exercises for independent execution
- Repeat everything you have seen in the article, but with your own domain and virtual server. Please, write about your result & link to your shorter website in the comments below!
- Try to deploy
index.html
to GitHub Pages (at your repository) instead of the virtual server, using the right action. Seegh-pages
docs here.
Photos/Images by
- GitHub repository settings (link)
P.S.
If you want more articles (like this) on this blog, then post a comment below and subscribe to me. Thanks! 😻
❗️ You can support me on Boosty, both on a permanent and on a one-time basis. All proceeds from this way will go to support my OSS projects and will energize me to create new products and articles for the community.
And of course, you can help me make developers' lives even better! Just connect to one of my projects as a contributor. It's easy!
My main projects that need your help (and stars) 👇
- 🔥 gowebly: A next-generation CLI tool that makes it easy to create amazing web applications with Go on the backend, using htmx, hyperscript or Alpine.js and the most popular CSS frameworks on the frontend.
- ✨ create-go-app: Create a new production-ready project with Go backend, frontend and deploy automation by running one CLI command.
Top comments (8)
This is really slick
Yes, it is 😅
Great article! And this series in general
Can't wait to read the forth part :)
Thx! You're welcome 👍
Nice article!
Thanks! 😊
sharts.website
Hmmm
Nope, it's shrts.website, without
a
letter betweenh
andr
😉