How to use Codeberg Pages for MkDocs
Codeberg1 is a Website providing Git Hosting and services for free and open source software, content and projects.
It's managed by a non-profit (Codeberg e.V.) and offers a lot of things, including their own static page hosting Codeberg Pages.
Since I moved my blog to Codeberg Pages a while ago and since I find its set of features quite good did I now decide to make this little tutorial on how you can automate the publishing and updating of your MkDocs Site for Codeberg Pages.
Comparison to GitHub Pages¶
Codeberg Pages has some similarities to GitHub Pages, while also offering additional features and having some smaller issues too.
This section will only cover a comparison to GitHub Pages. Other Page services (i.e. GitLab Pages) may offer similar features as Codeberg Pages.
Similarities to GitHub Pages¶
There are a few similarities to GitHub Pages.
The first similarity is the usage of a dedicated branch and repository for repo-sites and user/org sites respectively.
On GitHub this would be the gh-pages
branch for a repository (<username>.github.io/repository
) and <username>.github.io
as repository name for a user/org site.
On Codeberg Pages, the equivalent to these are a branch named pages
and a repository named pages
.
Another feature available in both is defining a domain. In GitHub is this done using a CNAME
file (Assuming you use their "deploy from branch" method) and in Codeberg page would this be a .domains
file.
The .domains
file has some benefits, but also drawbacks, which are explained in the next sections.
Beneficial features¶
Codeberg Pages has some features not available in GitHub Pages, which can be very useful to have.
The first feature is the .domains
file, which allows to define more than one domain. The first domain would then be used as the primary and any other would redirect to it.
Additionally can you define a branch in the URL to see the content of a non-pages
branch.
As an example knut.codeberg.page/@some-branch
would display the content of the some-branch
branch on the knut/pages
repository.
This can be really useful for things such as deploy-previews of Pull requests, allowing you to see the changes before merging, or to host old versions of your documentation.
Additionally can you also configure your DNS to have a (sub)domain point to a specific branch of your repository.
drawbacks¶
There are some drawbacks/issues with Codeberg Pages not present in GitHub Pages itself.
One issue is, that once you create a custom domain for your user/org (Define a domain used for a pages
repository), will sub-pages made from repositories no longer display content of a repository's pages
branch, even if there is one.
This means while knut.codeberg.page/repository
did display content of knut/repository
's pages
branch before would now example.com/repository
return a 404 error. In addition will your codeberg.page
sub-domain be automatically redirected to your custom domain (knut.codeberg.page/repository
-> example.com/repository
).
Another issue is the .domains
file. By default does MkDocs ignore and not include files starting with a dot in its page build, meaning it would ignore and not include the .domains
file. This is not an issue in GitHub Pages as the file used there is named CNAME
which MkDocs just includes unchanged in its build page.
A workaround for this issue is explained later in this post.
As a final drawback can you not define a specific folder to be used for the page content. Only the root of a repository is used.
Preparations¶
Before your site can actually be published will you need to make sure, that you've prepared some stuff first, to ensure it will work.
First of all, you need to make sure you have a CI/CD system ready to use on your repository. I use Woodpecker-CI2, an open source CI software, in this guide, but any CI that can work with Forgejo3, a fork of Gitea4 used to manage the Git Hosting of Codeberg, should be fine to use here.
It's worth noting that Codeberg offers their own Woodpecker-CI Instance5 to use for free. Only requirement is that you have to apply for access.6
Next should you create an API token for Codeberg. This is required as otherwise, your CI won't be able to commit and push the docs to the repository.
Finally should you have prepared your repository. This means that you either set up a pages
branch (Preferably orphaned) to push towards, or have created a repository named pages
.
I will use the second option in this guide, but this also means that I'll need a second repository hosting the source (config files, markdown files, etc), as everything on the default branch of the pages
repository would be served on your user.codeberg.page
domain.
I suggest to have the following file structure prepared for your source repository:
.woodpecker/
└── publish_docs.yml
docs/
└── index.md
domains # Used for custom domains
mkdocs.yml
requirements.txt
The usage of a .woodpecker
folder instead of a .woodpecker.yml
file is recommended, as it would allow you to later add additional CI workflows for different things.
Preparing the woodpecker file¶
Info
The below example file will show some placeholder/example values which you should change to your own stuff. Namely...
knut
will be used as user, which is Codeberg's example account and should be replaced with your username on Codeberg.docs-source
will be used as the source repository containing the raw MkDocs content and should be replaced with your source repo name.
The first thing you should do is add the source repository as a new repo in the Woodpecker-CI Dashboard. Next should you add the necessary secrets to it, to ensure that they will be present when using the file.
In my example below do I include two secrets:
cbemail
which contains the e-mail to use for the Git user. This can be replaced with your e-mail in the file if you're not afraid of others knowing it.cbtoken
which contains a valid PAT (Personal Access Token) for your Codeberg account. This ensures that we can push the final docs to the target repository without requiring login data to be included in whatever way.
DO NOT DIRECTLY INCLUDE YOUR PAT IN THE WOODPECKER FILE! This can result in your account being hijacked and abused. Always treat a PAT like a super important password nobody should know about.
In my example do I have .woodpecker/publish_docs.yml
which does the publishing for us. Let's see how the file looks like and then go over all the necessary stuff:
when:
- event: push
branch: master
path:
include: ["docs/**", "mkdocs.yml", "requirements.txt"]
variables:
setup_git: &setup_git
- apk add git
- git config --global user.email "$CBEMAIL"
- git config --global user.name "CI Docs Builder"
steps:
cloneTargetRepo:
image: alpine:3.18.4
secrets: [cbemail]
commands:
- chmod -R a+w .
- <<: *setup_git
- git config --global --add safe.directory /woodpecker/src/codeberg.org/knut/docs-source
- git config --global init.defaultBranch pages
- git clone -b pages https://codeberg.org/knut/pages.git
- chmod -R a+w pages
buildDocs:
image: woodpeckerci/plugin-mkdocs:1.2.0
settings:
site_dir: pages
commitAndPush:
image: alpine:3.18.4
secrets: [cbtoken, cbemail]
commands:
- <<: *setup_git
- cd pages
- git remote set-url origin https://$CBTOKEN@codeberg.org/knut/pages.git
- git add --all
- git commit -m "Update Docs ($( env TZ=Europe/Berlin date +"%d.%m.%Y %Z" )) [SKIP CI]"
- git push
Lets get over the different parts to look at...
when:
- event: push
branch: master
path:
include: ["docs/**", "mkdocs.yml", "requirements.txt"]
master
branch and only files defined in include
are modified.Make sure to update
master
to whatever branch you use for your docs source and also update include
to have the file paths necessary. The option supports glob patterns.
variables:
setup_git: &setup_git
- apk add git
- git config --global user.email "$CBEMAIL"
- git config --global user.name "CI Docs Builder"
$CBEMAIL
would be an enviroment variable that would be defined in a step using the secrets
option.
steps:
cloneTargetRepo:
image: alpine:3.18.4
secrets: [cbemail]
commands:
- chmod -R a+w .
- <<: *setup_git
- git config --global --add safe.directory /woodpecker/src/codeberg.org/knut/docs-source
- git config --global init.defaultBranch pages
- git clone -b pages https://codeberg.org/knut/pages.git
- chmod -R a+w pages
- It applies proper permissions using
chmod
to avoid access issues - It adds and setups git using the previously mentioned YAML anchor that has been created.
<<:
is another YAML feature that tells it to inject the provided anchor at this position. - It configures a safe directory in git to avoid security issues
- It sets a default branch
- It clones the target repository to where the built docs would be pushed. Make sure to update the URL here to whatever target repo yours would be.
The-b pages
defines thepages
branch to be cloned from. Change the name to whatever branch name yours is. - It applies proper permission to the cloned repo folder.
Also, note that I use alpine here as image. You can use any docker image you like. Just make sure that essential commands such as chmod
and mv
are available, or else the workflow may not work for you.
steps:
# ...
buildDocs:
image: woodpeckerci/plugin-mkdocs:1.2.0
settings:
site_dir: pages
We use the
site_dir:
setting to change the target directory for the built docs to our target repository (pages
).
steps:
# ...
commitAndPush:
image: alpine:3.18.4
secrets: [cbtoken, cbemail]
commands:
- <<: *setup_git
- cd pages
- git remote set-url origin https://$CBTOKEN@codeberg.org/knut/pages.git
- git add --all
- git commit -m "Update Docs ($( env TZ=Europe/Berlin date +"%d.%m.%Y %Z" )) [SKIP CI]"
- git push
pages
folder and sets the target URL to the target repository, while including the $CBTOKEN
. This should be a valid Codeberg PAT to allow pushing the changes.It then adds all the changed files, commits them (Note the
[SKIP CI]
which tells Woodpecker-CI to ignore this commit) and finally pushes it to the target repository to publish.
And that's all. Your site should now be available under your codeberg.page
subdomain.
Adding custom domains¶
Similar to GitHub Pages does Codeberg pages allow you to define custom domains to use. The difference here is, that not only can you define multiple custom domains for one repository, but they also use a different file.
The file in question is called .domains
which is already a smaller issue. With GitHub Pages you can have a CNAME
file in the docs folder and MkDocs would carry it over into the build site. With the file from Codeberg Pages however can this not be done.
The main reason is MkDocs ignoring files starting with a dot by default.
You could now alter the configuration of MkDocs to change what files to ignore, or you can do the solution I'll show you below.
To make things work, all you have to do is make a domains
file, fill it with the custom domain(s) you want to use and then add the following line to your workflow file:
when:
- event: push
branch: master
path:
include: ["docs/**", "mkdocs.yml", "requirements.txt"]
variables:
setup_git: &setup_git
- apk add git
- git config --global user.email "$CBEMAIL"
- git config --global user.name "CI Docs Builder"
steps:
cloneTargetRepo:
image: alpine:3.18.4
secrets: [cbemail]
commands:
- chmod -R a+w .
- <<: *setup_git
- git config --global --add safe.directory /woodpecker/src/codeberg.org/knut/docs-source
- git config --global init.defaultBranch pages
- git clone -b pages https://codeberg.org/knut/pages.git
- chmod -R a+w pages
buildDocs:
image: woodpeckerci/plugin-mkdocs:1.2.0
settings:
site_dir: pages
commitAndPush:
image: alpine:3.18.4
secrets: [cbtoken, cbemail]
commands:
- <<: *setup_git
- mv domains pages/.domains
- cd pages
- git remote set-url origin https://$CBTOKEN@codeberg.org/knut/pages.git
- git add --all
- git commit -m "Update Docs ($( env TZ=Europe/Berlin date +"%d.%m.%Y %Z" )) [SKIP CI]"
- git push
domains
file into the pages
folder and also rename it to .domains
in order for Codeberg Pages to recognize it.
And that's already it. Your domain should now be available under your custom domain.
DNS settings
Remember to also configure your domain's DNS properly to have the domains work.
You can visit the Codeberg Pages documentation for how to setup and configure custom domains.
Footnotes
Comments
Comment system powered by Mastodon.
Leave a comment using Mastodon or another Fediverse-compatible account.