Deploying mdbook to codeberg pages using woodpecker CI

4 min read

I have been working on transitioning more of my sites to Codeberg after becoming a member, and today was the day that I took the plunge into using their hosted Woodpecker CI instance. You have to apply for access by submitting an issue to the requests repository, however the process was very quick and painless. Within a few days I had been approved and had access.

To start, I wanted to configure my notes because it was the simpliest and almost certainly receives the least traffic. I laid out the following steps to facilitate the transition:

  1. Turn off mirroring of the codeberg repository to the github repository previously used for vercel deployment.
  2. Configure the woodpecker-ci via .woodpecker.yml and ensure that it was working.
  3. Add the .domain file so that would redirect to the codeberg pages server.

Setting up woodpecker-ci

Fortunately, there was already an example configuration for mdbook available in the ci examples repository. I just had to copy the woodpecker.yml file listed in the mdbook directory.

    image: woodpeckerci/plugin-git

  branch: master
  event: [push, cron]

    image: peaceiris/mdbook:latest
      - mdbook build

    image: bitnami/git
    secrets: [mail, codeberg_token]
      - MDBOOK_OUTPUT=book
      - git config --global $MAIL
      - git config --global "Woodpecker CI"
      - git clone -b pages https://[email protected]/$CI_REPO.git $CI_REPO_NAME
      - cp -ar $MDBOOK_OUTPUT/. $CI_REPO_NAME/
      - cp .domains $CI_REPO_NAME || true
      - cd $CI_REPO_NAME
      - git add .
      - git commit -m "Woodpecker CI ${CI_BUILD_CREATED}"
      - git push

Note that this file uses two secrets: mail, and codeberg_token. The mail token should be set to whichever email is used for your git commits, and the codeberg_token can be obtained by going into your codeberg Account Settings > Applications and then generating a new token. You should only need to give the token read/write access to repositories. Copy the token into woodpecker-ci under the repositories secrets. Make sure to call the secret codeberg_token exactly. Never expose this token publicly, including in any commits. It should only be managed through the woodpecker secrets manager. More documentation on woodpecker secrets can be found in the woodpecker documentation

Next, I had to change branch master to main to match the setup for my repository.

  branch: main
  event: [push, cron]


Deploying was simple. As soon as I committed the woodpecker.yml file and pushed to main, the ci pipeline triggered and was observable from the woodpecker GUI. After fixing the master -> main issue, it worked without any further troubleshooting. Before running, I checked that the peaceiris/mdbook and bitnami/git images were still active. If you are reading this many years in the future, you may need to switch these images if they are no longer maintained.

Setting up the custom domain

To use the domain with the codeberg page, I had to add a .domains file at the root of the repository. It is a very simple text file, that in this case, just includes a single line.

This .domains file should automatically be copied over into the pages branch when you commit and push for the first time.

I then pointed the domain to the site via a CNAME record to Documentation on using custom domains with codeberg pages can be found in the codeberg documentation.

The finalized setup can be found in the codeberg repository for my notes

Next steps

The big task is migrating my main site (this site) next. I may try to configure woodpecker to send the deployment to vercel instead of using codeberg pages. Prettier should hopefully be quite easy as there is a woodpecker prettier plugin