Host your own documentation

Github pages are an easy way to host the documentation of your project. But what can you do when you move away from Github?

When your hosting provider allows to use SSH and git, then you can host it yourself. Zumuta! is hosted on Alwaysdata and meets these requirements.

This is the story on how you can keep the documentation site in sync with the documentation that is available in your documentation branch.

Pages branch

On Github you need a gh-pages branch. here we use a pages branch. The repository is not empty so an orphan branch must be created.

git switch --orphan pages
git commit --allow-empty -m "Initial commit for pages"
git push -u origin pages
git switch master

Now you should have an empty pages branch on your remote repository.

Worktree

Switching between the master and pages branch is cumbersome. Therefore we are going to use a worktree. This allows us to have a branch of the repository checked out in a subdirectory. When you use mkdocs for example, the documentation site is generated in the _site directory.

git worktree add _site pages

Add _site to the .gitignore file.

Update documentation

When the documentation is generated, you can update the pages branch.

cd _site
git add .
git commit -m "Update documentation"
git push origin pages

The branch pages on the remote repository should now contain the updated documentation.

The hosting side

When you are still using gh-pages on GitHub, the documentation will be deployed for you. On Codeberg, you can use grebedoc and a webhook on your repository. But you can also host it on your own provider.

Use ssh to access your host and create a directory (that is not reachable from the internet). Create a bare git repository in this new directory.

cd /your_bare_repository_directory
git init --bare project.git

Now there should be a directory project.git created. Go to the hooks directory and create a post-receive hook with the following content:

#!/bin/bash
TARGET="/your_htdocs_directory"
GIT_DIR="/your_bare_repository_directory/project.git"
BRANCH="pages"

while read oldrev newrev ref
do
	# only checking out the master (or whatever branch you would like to deploy)
	if [ "$ref" = "refs/heads/$BRANCH" ];
	then
		echo "Ref $ref received. Deploying ${BRANCH} branch to production..."
		git --work-tree=$TARGET --git-dir=$GIT_DIR checkout -f $BRANCH
	else
		echo "Ref $ref received. Doing nothing: only the ${BRANCH} branch may be deployed on this server."
	fi
done

Credit where credit is due. This code comes from here.

Don't forget to make the hook executable:

chmod +x post-receive

Deploy

Is the documentation ready? You need to push the documentation to the bare git repository. Add this repository as a remote repository.

cd _site
git remote add documentation ssh://<your_ssh_user>@<your_ssh_host>/<your_bare_repository_directory>/project.git

From now on it's easy, push the changes to this remote and the site will be up-to-date.

git push documentation pages

Now the post-receive hook should have copied the latest documentation files to your htdocs directory.

When you are using pre-commit, put PRE_COMMIT_ALLOW_NO_CONFIG=1 before a git commit command to run it without a config file.

Previous Article
Zola
Back to the blog