I recently intoduced my newest project, the Vulnerability Garden 🪴. Unlike this site (shellsharks.com), which has always been hosted on GitHub Pages, Vulnerability.Garden is brought to you by Codeberg pages! This post will walk through how (and a bit of why) I got this new static site goin’ with Codeberg.
I’ve been thinking of migrating my main site off of GitHub for a while. For all the reasons you probably already know of—but let’s just say that Microsoftslop has given me a lot of reasons to want to move away. It’s a big undertaking, and for many-a-reason, I just haven’t done it yet. But, I had a new project in mind, and decided to start fresh. So I am trying out Codeberg’s “pages” offering.
Setting up the static site on Codeberg
To get started, sign up for an account at Codeberg.org. Easy! Then, spin up a new project for your static site—I personally am familiar with Jekyll, having used it for this site for years, so decided to go with that for this new project as well. Create a Codeberg repository, either on the remote side or locally and clone-down or commit that repo to get it synced up with Codeberg.
Next, you’ll want to make sure you’ve added an ssh key to your account.
For setting up the static page on Codeberg, I’ve opted for the “legacy method”, which is currently the only option that supports custom domains on Codeberg. To get the site up, you need to set up the repo with a separate pages branch, push the generated static content (i.e. HTML, style sheets, images, etc…), configure DNS, and create a .domains file in the project repo. Let me walk through these steps below as I found this the most confusing part of the whole thing, despite Codeberg’s claim that “it’s quick and easy”. 🙄
SPECIAL THANKS: I want to pause here and give all the credit for the rest of this setting-up-a-static-site-on-Codeberg walkthrough to @mttaggart@infosec.exchange. He was kind enough to hold my hand through this process and even taught me a cool thing or two about git in the process. Thank you, thank you! 🙏
So, at a high level, we’re going to create the new pages branch (the branch has to be named ‘pages’ according to the Codeberg instructions), which will at first have everything that the main branch has. We’re going to switch to, and then delete everything from it (SCARY!). Then we switch back to the main repo and add that new branch as a submodule. From there we can build the site, copy the files from that build folder (this would be _site in Jekyll terms) into the new pages folder (which remember is where the submodule/branch will be), move into the pages branch (by simply cd-ing into the folder), commit+push the updated files there, and then finally move back to the project root directory and commit+push any files there. Phew!
Let’s walk through those steps again at a more granular level below…
Starting in your main branch and in your project root on the command line, run
git switch -c pagesto create and switch to the newpagesbranch.Run
git -rm -r ./*to delete everything from the pages branch. It will look scary at first, but when you switch back to your main branch, everything will still be there I promise!Then push everything up to the remote repo to lock in that new clean branch. So while in the pages branch run
git add -A, thengit commit -m "WHATEVER COMMIT MESSAGE",git push -u origin pages, and thengit switch -to go back to your main branch.Next, you add the submodule and associate it with the pages branch by running
git submodule add -b pages git@codeberg.org:USERNAME/SITE-REPO.git pages. REMEMBER! Use YOUR username and the name of your Codeberg repository here. You’ll also need to be sure you’ve set up your SSH keys at this point.Next, move your built site static content to the newly created pages directory,
cp -R YOUBUILDFOLDER/* pages/— be sure to include the/*after your build folder directory to ensure only the files in your build directory are moved over and not the build directory folder itself.Create a .domains file and move it into the pages directory. The .domains file will simply list, line-by-line, the custom domains you want your site to be reachable on. So for example, my .domains file for Vulnerability.Garden simply has one line:
vulnerability.garden.Move into the pages directory
cd pagesand addgit add -A, commitgit commit -m "COMMIT MESSAGE"and pushgit pushthe static files up to the remote repo. One beauty of submodules here is that by simply navigating into this directory on the command line and committing+pushing your files, it also pushes these files into the pages branch of the project. So you don’t have to do any branch switching here. Neat!Finally, move back to the project root directory
cd .., commit changes at that levelgit commit -am "COMMIT MESSAGE"and push those changes up as wellgit push.
To recap, here’s all those instructions in one go…
git switch -c pages
git rm -r ./*
git add -A
git commit -m "Remove everything for new branch"
git push -u origin pages
git switch -
git submodule add -b pages git@codeberg.org:username/site-repo.git pages
cp -R build_folder/* pages/
cp .domains pages/
cd pages
git add -A
git commit -m "Rebuild: $(date -Iseconds)"
git push
cd ..
git commit -am "Update build"
git push
Hopefully everything worked for you! Now the last step is to get DNS all set up through your DNS provider. I use GoDaddy, but the instructions should be pretty straight-forward for other providers as well. Codeberg’s instructions I feel are pretty straight forward…
- Add a DNS record for that domain:
CNAME [[branch.]repo.]user.codeberg.page.— which I didn't do as my provider wouldn’t let me. - So alternatively you can, for an apex domain where CNAME doesn’t work, add the ALIAS record
ALIAS codeberg.page.(which I also didn’t do because it also wasn’t supported), andTXT [[branch.]repo.]user.codeberg.pageTXT record, which I did do. - So in the end, I only added the TXT record. Mine looked like:
pages.vulnerability-garden.shellsharks.codeberg.page. - Finally, set up the A and AAAA records using
A 217.197.84.141andAAAA 2a0a:4580:103f:c0de::2respectively.
Give DNS time to propagate, and Codeberg time to do their magic on the back end, and before long you should be able to see your site at your custom domain. Hurray! 🎉
Updating content on your static site
Now that your site is all set up, you’ll want to know how to update said site right? Well the good news here is that you’ve already done the steps at least once. The bad news is it’s a little clunky, but there are ways to streamline it.
Basically, you just need to redo steps 5-8 from the previous section. But before you do, make sure you delete any existing build folder (i.e. _site in the Jekyll world), and I also like to delete everything out of the pages directory (except the .domains file). I do this because I was seeing some issues recursively adding ‘pages’ folder content into my _site and pages directories. From there, it’s the same steps as before. To recap again, here’s what I do…
# DELETE BUILDFOLDER
# DELETE EVERYTHING IN PAGES FOLDER *EXCEPT* .domains FILE
# cd TO MAIN REPO DIR
cp -R _site/* ./pages # SUB '_site' with the path to your build directory
cd pages
git add -A
git commit -m “COMMIT MSG”
git push
cd ..
rm -rf _site/ # SUB '_site' with the path to your build directory
git add -A
git commit -am “COMMIT MSG”
git push
Give Codeberg another minute or two and huzzah! The days is yours. 🥳
just file
Updating your static site on Codeberg pages can be a bit clunky if done manually via the approach described here. But you can use a just file to streamline the process. I haven’t set this up quite yet, but Taggart was kind enough to share his (thanks again!) — to give you an idea of what one might look like. With a bit of tweaking, this can be used for your site to do all the moving about, deleting things, committing+pushing, etc…
Jekyll on Codeberg
I want to highlight a few li’l oddities and differences I encountered while setting up a Jekyll site this way on Codeberg, versus GitHub Pages.
You’ll want to really make sure you’re building your site with
jekyll build, and notjekyll servewhen you are pushing content into production. This way you can avoid having localhost URLs in your site’s production code. This one got me a few times.On GitHub, you commit your un-built files and their backend does the build for you and then publishes your static content. Here, you’re running the build locally and moving files into the pages branch. This should be evident at this point in the post, but I felt it worth mentioning again.
Interesting things I’ve done with Vulnerability.Garden
In this final section, I want to cover a few noteworthy things that I’ve done with Vulnerability.Garden.
- The base theme is Beautiful Jekyll, which I heavily modified.
- The main vulnerability table is powered by DataTables. It’s a tool I hadn’t used before, but it is awesome! Below you can see some of the DataTables-specific configuration I did to get it to work the way I wanted…
$(document).ready( function () {
$('#myTable').DataTable( {
paging: false,
order: [[3, '']],
layout: {topStart: 'search', topEnd: null}
} );
} );
One issue I encountered with DataTables was the way it was trying to sort my date fields. It was doing so alphabetically instead of, well… date-wise. This li’l stackoverflow thread helped me sort this issue out (get it!?) rather quickly. To be clear, I used the “HTML Solution” by adding
<td data-sort='YYYYMMDD'>parameters to my<td>tags. Elegant.For vulnerability logos, I used this site to help remove background and improve transparency for the images.