Self-Hosted Docker Compose Templates: The Complete, Powerful Starter Guide

self-hosted-docker-compose-templates.md
title Self-Hosted Docker Compose Templates: The Complete, Powerful Starter Guide
date
author VahaC
read 6 min read
category Self-Hosting
tags #container #Docker #Homelab #Stashboard
self-hosted docker compose templates

Stashboard V7.5 ships self-hosted docker compose templates — a built-in catalogue of starter recipes that turns “I want to try this app” into a running stack in under a minute. Instead of hunting a README, copying a docker-compose.yml, and fixing indentation over SSH, you pick a card, fill a few fields, and click create. 🧩

This guide is the deep dive on self-hosted docker compose templates: where the From template tab lives, every per-deployment field you fill, how ${KEY} placeholders resolve, how each write is validated, and how to add your own recipes. It builds directly on the visual Docker Compose editor pillar and the create Docker Compose stack from scratch guide — templates are the fastest of the create paths described there. New to Compose itself? Start with Docker for beginners.

What ships in the catalogue

Stashboard bundles over 125 self-hosted docker compose templates (126 and counting) spread across 10 categories:

  • Databases & caches — Postgres, MariaDB, MySQL, Redis, Valkey, MongoDB, InfluxDB, and more.
  • Networking & proxies — Nginx, Caddy, Traefik, HAProxy, Nginx Proxy Manager, Cloudflared, WireGuard.
  • Monitoring & dashboards — Grafana, Prometheus, Uptime Kuma, and friends.
  • Media servers — Jellyfin, Plex, Emby, Navidrome.
  • Media automation — the *arr suite (Sonarr, Radarr, Prowlarr), qBittorrent, SABnzbd.
  • Files & productivity — Nextcloud, WordPress, Vaultwarden, and office tools.
  • Security & identity — Authelia, Authentik, Keycloak, and similar.
  • Smart home & IoT — Home Assistant, Mosquitto, Zigbee2MQTT, Node-RED.
  • Developer & Git — Gitea, code servers, registries, CI helpers.
  • Communication — messaging, mail, and chat servers.

Crucially, recipes are not limited to single containers. Many are full multi-service stacks — app + database + cache wired together. The WordPress + MariaDB template, for example, starts two services in one project with the app already pointed at its database.

Where self-hosted docker compose templates live

Open any host header on the Docker page and click New project — the same button covered in the create-from-scratch guide. The dialog has two tabs: From scratch and From template. The second tab is the home of self-hosted docker compose templates. It renders the catalogue as cards grouped by category, each with an icon, name, and one-line description. Pick one and the deployment form appears.

The per-deployment fields

Self-hosted docker compose templates keep the form short: each template declares its own variables — the handful of values that differ between your deployment and everyone else’s — and Stashboard renders one input per variable, nothing more. The four field flavours are:

  • path — a volume host path, e.g. ./wordpress/db. This is the host side of a bind mount.
  • port — an exposed port, e.g. 8080.
  • text — a plain value (a username, a domain).
  • password — a masked input with a one-click generate button that fills a strong random secret.

⚠️ Generate the secret before you create. Many recipes mark the password required, and a database that boots with a blank or weak root password is a real risk — especially for a multi-service stack you may expose later.

Above the variables you also edit the project name (defaults to the recipe’s, validated to Compose’s lowercase rule) and the target directory — a free-text path as the connection sees it: inside the Stashboard container for a Local socket, on the remote host for SSH.

How ${KEY} placeholders resolve

This is the mechanism that makes self-hosted docker compose templates both simple and safe. Each variable has a key (say DB_PASSWORD). Inside the recipe’s service definitions, that key appears as a ${DB_PASSWORD} placeholder wherever the value belongs — an env value, a volume’s host path, or a port mapping.

When you click create, the frontend substitutes every ${KEY} with the value you entered (or its default) and posts the fully-resolved services to the very same create-project endpoint the from-scratch flow uses. The backend never sees a placeholder — it just receives ordinary service definitions. In the WordPress recipe, the one ${DB_PASSWORD} you type once lands in both the database’s MARIADB_PASSWORD and WordPress’s WORDPRESS_DB_PASSWORD, so the two services agree by construction.

Validation: nothing invalid hits disk

Because self-hosted docker compose templates ride the same create path as everything else, they inherit the same guarantee: every write is validated with docker compose config -q before it is committed. If the resolved file is not valid Compose, the save is refused — a template bug can never persist a file Compose itself rejects. The file is written atomically (candidate → validate → rename), so a half-written stack never lands on disk. ✅

How to verify it worked

After deploying one of the self-hosted docker compose templates, confirm it like this:

  1. The card appears. The new project shows up as its own group on the Docker page (a re-scan runs automatically on success).
  2. Containers run. For a Create-and-run, open the project’s Logs tab and confirm every service started — for a multi-service recipe like WordPress, check both the app and the database.
  3. Finish in the browser. Many recipes carry a post-create note (e.g. “finish setup on the exposed port”). Open the port you chose.
  4. Check the YAML. The Raw YAML tab shows the resolved file — confirm the top-level name: and your substituted values are present.

Extend the catalogue with your own recipes

The catalogue is just JSON, so you can add your own self-hosted docker compose templates without rebuilding the image. Drop one or more *.json files into the override directory — /app/Data/templates inside the container (bind-mount it so your recipes survive upgrades). Stashboard loads them once at startup, alongside the built-ins. Three rules are worth knowing:

  • Same id overrides. A user template whose id matches a built-in replaces it — handy for pinning an image tag or tweaking defaults without forking.
  • ⚠️ Malformed files are skipped, not fatal. Each file is structurally validated (a valid id, a project name, at least one service, every service has an image). A bad file is logged and skipped, so one typo never breaks the whole catalogue.
  • Structure mirrors the editor. Each service’s shape matches the create request, so the simplest way to author a recipe is to build the stack once in the editor, then copy the field values into JSON.

A minimal recipe looks like this:

{
  "id": "my-app",
  "name": "My App",
  "category": "Developer & Git",
  "projectName": "my-app",
  "variables": [
    { "key": "PORT", "label": "Exposed port", "type": "port", "default": "9000" }
  ],
  "services": [
    { "name": "app", "image": "ghcr.io/me/my-app:latest", "ports": ["${PORT}:80"] }
  ]
}

Bottom line

Self-hosted docker compose templates turn Stashboard’s create flow into a one-click app store for your homelab: over 125 recipes across 10 categories, full multi-service stacks included, with declared variables, one-click secret generation, ${KEY} substitution on the client, and docker compose config -q validation on every write. Every one of the self-hosted docker compose templates runs through that same atomic, validated writer, so the worst case is a refused save — never a corrupted stack. Drop your own JSON in /app/Data/templates and the catalogue is yours to extend. Click New project → From template and try it. 🚀

Stashboard is open source — you can find the full source code on GitHub and pull the ready-to-run image directly from Docker Hub. Issues, PRs, and stars are always welcome. 🙌

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.