Custom themes and routes.yaml for a self-hosted Ghost site in Docker
- Where themes live
- Keep the theme in Git
- routes.yaml basics
- Moving posts under /blog/
- Back up both files
- Upgrading Ghost
Uploading a theme zip through Ghost admin works, but in a Docker setup it is easy to lose track of which theme version is live and where it is stored. Treating the theme as code, and knowing how routes.yaml works, makes a self-hosted Ghost site much easier to maintain.
Where themes live
In the official Ghost image, content is under /var/lib/ghost/content. Themes are in content/themes, and uploads in content/images. That directory must be a volume, or uploaded themes and images vanish when the container is recreated:
services:
ghost:
image: ghost:5
volumes:
- ghost_content:/var/lib/ghost/content
Keep the theme in Git
Develop the theme in its own repository. Run npx gscan . before each release; it is Ghost’s official theme validator and catches deprecated helpers that would break on upgrade. Then either upload the zip in admin, or deploy it with the Admin API, which lets CI push a theme on every tagged release.
Avoid bind mounting a theme folder from the host into content/themes in production. Ghost caches templates, and changes to a mounted folder can appear only partially until a restart.
routes.yaml basics
Ghost’s dynamic routing lives in routes.yaml, uploaded under Settings, Labs. It controls three things:
routes:
/start/: start
collections:
/blog/:
permalink: /blog/{slug}/
template: index
taxonomies:
tag: /topic/{slug}/
author: /author/{slug}/
routesmaps a URL to a template, such as a custom landing pagecollectionsdecides which posts appear where and their permalink formattaxonomiessets tag and author URLs
Moving posts under /blog/
Changing the collection permalink changes every post URL. Add redirects for the old URLs in redirects.yaml, or from your reverse proxy, before you upload the new routes. Otherwise search traffic hits 404s.
Back up both files
Download routes.yaml and redirects.yaml from admin and commit them next to the theme. They are stored in the content volume, but having them in Git shows when and why URLs changed.
Upgrading Ghost
Before a major version upgrade, run gscan with the target version flag against your theme and fix errors first. Then back up the database and content volume, change the image tag, and watch the logs while migrations run.
For setup, email and reverse proxy configuration, see this guide to self-hosting a Ghost blog.
Disclosure: I help build Peon.
Write a comment