Versioning with mkdocs when not using GitHub
Mike is the go-to tool for versioning MkDocs sites.
It allows you to easily manage multiple versions of your site and provides a simple way to deploy them to a static hosting service.
However, mike
is heavily focused on GitHub Pages, which may not be suitable for all use cases.
For example, if you want to host your site on a different platform or use a different versioning strategy, it can get a bit complicated.
Since I am a heavy user of Forgejo/Gitea-based instances, where GitHub Pages is not available (and Codeberg’s pages server can be unreliable at times), I usually prefer pushing to S3 and putting a CDN in front of it.
Yet, mike
requires the ability to push to a branch named gh-pages
in the first place.
It doesn’t work locally in the sense that it builds/appends the versioning structure, and one could sync to a different destination from there. After figuring this all out, I thought sharing this in a brief post might help others out there.
This post assumes you have a working mkdocs
site and have installed mike
.
mike list
at any time to see the current version structure mike
knows about.
Local Deployment
-
Run
mike deploy <version>
with the oldest version of your docs you want to deploy. It is usually best to start from the oldest version and move forward, even though you can also deploy older versions retrospectively. Ensure you go to the respective commit back in time (git checkout <tag/commit-hash>
) and then runmike deploy <version>
. Do this for all versions you want to deploy. It is also common to deploy a rolling “dev” version at the end, which will be updated with each new commit.TipYou usually only want to use
major.minor
versioning and leave out versions for patch versions. Instead, patch versions will update the existing minor version. -
Tell
mike
which version is currently the “latest” one by runningmike set-default <version> --push
. The--push
will issue agit push
command and push the changes to the remote repository, i.e., thegh-pages
branch. -
From here, you can now either:
- Push everything to the
pages
branch to be picked up by Codeberg pages. - Sync the contents to an S3 bucket.
- Push everything to the
CI Deployment
When running in CI, you must set up the build in a way that it has proper git
authentication and is able to push to the gh-pages
branch.
How this is done depends on your respective CI and is out of scope for this post.
However, if you’re running in a containerized way, you can use the following commands in a plain Alpine container:
- apk add --no-cache -q git py3-pip cairo go pngquant
- python3 -m venv venv
- git config --global user.email "<email>"
- git config --global user.name "<username>"
- git remote set-url origin https://<username>:${TOKEN}@<your git domain>/<user>/<repo>.git
# build & deploy
- ./venv/bin/activate && mike deploy <version> --push
When you deploy a new release version, you want to use mike deploy <tag> latest --push
to update the “latest” version reference.
After all of the above, you need to run the following steps:
- Clone the
gh-pages
branch of your repo to a sub-directory:git clone --branch gh-pages --depth 1 <your repo> <some dir>
- Perform S3 sync to the destination bucket