Skip to main content

Plan the Tenant

What You Will Learn

  • Why you should always plan a tenant before building it
  • The complete resource inventory for the Radical Faeries
  • What secrets each app needs and where they live in Vault
  • The directory structure and file numbering plan

Always Plan Before You Build

Jumping straight into YAML is tempting. Do not do it. A few minutes of planning saves hours of debugging. Before you create any files, you need to answer four questions:

  1. What is the namespace called?
  2. What apps go in it and what do they need?
  3. What secrets are required and where do they live?
  4. What does the file and directory layout look like?

Let us answer each one.


Tenant Identity

Every Junovy tenant gets a namespace with the hst- prefix. Here are the basics:

Property Value
Tenant name radical-faeries
Namespace hst-radical-faeries
Tier hosting
Plan basic
Directory in Flux repo clients/com.junovy.radical-faeries/

The directory name follows the reverse-domain pattern used by other tenants in the repo (like eu.faerues.riverland or com.junovy.open-cloud). Since the Faeries will be on a junovy.com subdomain, the directory is com.junovy.radical-faeries.


App Requirements

Each app has different technology and dependencies. Here is the breakdown:

Property BookStack Rallly
What it does Wiki / knowledge base Meeting scheduler
Language / Runtime PHP Node.js
Database MySQL 8 PostgreSQL 16
Database runs as Sidecar container in the same Pod Connects to shared PostgreSQL cluster
Web port 8080 3000
Needs mail? Yes (SMTP for notifications) Yes (SMTP for invitations)
Needs storage? Yes (uploads / attachments) No
Domain bookstack.radical-faeries.junovy.com rallly.radical-faeries.junovy.com
TLS Automatic via Traefik ACME Automatic via Traefik ACME

BookStack bundles MySQL as a sidecar in its Helm chart, so you do not need to provision a separate database. Rallly connects to the shared PostgreSQL cluster already running in the postgresql namespace.


Secrets Inventory

Each app needs credentials stored in HashiCorp Vault. Here is the full inventory:

BookStack Secrets

Secret Key Purpose Vault Path
app-key Laravel encryption key secret/radical-faeries/bookstack
db-password MySQL root password secret/radical-faeries/bookstack
smtp-host Mail server hostname secret/radical-faeries/bookstack
smtp-port Mail server port secret/radical-faeries/bookstack
smtp-username Mail authentication user secret/radical-faeries/bookstack
smtp-password Mail authentication password secret/radical-faeries/bookstack
smtp-from-email Sender email address secret/radical-faeries/bookstack

All BookStack secrets live under a single Vault path: secret/radical-faeries/bookstack.

Rallly Secrets

Secret Key Purpose Vault Path
database-url Full PostgreSQL connection string secret/radical-faeries/rallly
secret-password Session encryption key secret/radical-faeries/rallly
smtp-host Mail server hostname secret/radical-faeries/rallly
smtp-port Mail server port secret/radical-faeries/rallly
smtp-username Mail authentication user secret/radical-faeries/rallly
smtp-password Mail authentication password secret/radical-faeries/rallly
smtp-from-email Sender email address secret/radical-faeries/rallly

All Rallly secrets live under: secret/radical-faeries/rallly.


Directory Structure

Here is the file tree you will create inside dds-k8s-cluster/clients/:

clients/
└── com.junovy.radical-faeries/
    ├── kustomization.yaml           # Lists all resources for this tenant
    ├── 010-namespace.yaml           # The hst-radical-faeries namespace
    ├── 020-externalsecret-bookstack.yaml  # Pulls BookStack secrets from Vault
    ├── 021-externalsecret-rallly.yaml     # Pulls Rallly secrets from Vault
    ├── 040-helmrelease-bookstack.yaml     # BookStack app + MySQL
    ├── 041-helmrelease-rallly.yaml        # Rallly app
    ├── 050-ingress-bookstack.yaml         # Ingress for BookStack
    └── 051-ingress-rallly.yaml            # Ingress for Rallly

File Numbering Plan

The numeric prefixes follow the Junovy convention. Here is why each file gets its number:

Prefix File Reason
010 010-namespace.yaml Namespace must exist before anything else
020 020-externalsecret-bookstack.yaml Secrets must exist before apps reference them
021 021-externalsecret-rallly.yaml Second secret resource, same tier
040 040-helmrelease-bookstack.yaml Application deployment (depends on secrets)
041 041-helmrelease-rallly.yaml Second application, same tier
050 050-ingress-bookstack.yaml Networking (depends on app services)
051 051-ingress-rallly.yaml Second ingress, same tier

The numbering ensures resources are created in dependency order. Lower numbers are created first.


Key Takeaways

  • Always plan your namespace, apps, secrets, and file layout before writing YAML
  • The Radical Faeries tenant uses namespace hst-radical-faeries with two apps
  • BookStack needs 7 secrets (app key, DB, mail); Rallly needs 7 secrets (DB URL, session key, mail)
  • All secrets are stored in Vault under secret/radical-faeries/<app>
  • Files use numeric prefixes (010, 020, 040, 050) to enforce dependency order

What Is Next

Next up: Create the Tenant from Scratch where you will build the namespace, populate Vault, and create ExternalSecret resources.