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:
- What is the namespace called?
- What apps go in it and what do they need?
- What secrets are required and where do they live?
- 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-faerieswith 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.