Skip to main content

Project Overview

What You Will Learn

  • Who the Radical Faeries are and what they need from Junovy
  • What you will build: two live apps with databases, secrets, and TLS
  • How this project differs from Chapter 9 (more apps, more moving parts)
  • The four phases of client onboarding

The Mission

You are going to onboard a real client: the Radical Faeries. They are a queer spiritual and social community that organises gatherings, rituals, and shared projects. They need two tools hosted on the Junovy platform:

  • BookStack -- an internal wiki for sharing knowledge, meeting notes, and community documentation
  • Rallly -- a meeting scheduler for coordinating gatherings and events

When this project is complete, both apps will be live:

https://bookstack.radical-faeries.junovy.com
https://rallly.radical-faeries.junovy.com

Both will be served over HTTPS with automatic TLS certificates, running in containers managed by Kubernetes, deployed through GitOps.

Training Note: In the real Junovy platform, BookStack and Rallly run as shared services (support.junovy.com and gather.junovy.com), not as per-tenant deployments. This project deliberately deploys them inside a tenant namespace as a learning exercise -- it teaches the HelmRelease, ExternalSecret, and Ingress patterns you will use for any app. In production, you would follow this same pattern but with different applications.


How This Differs from Chapter 9

In Chapter 9, you deployed a single static web app. This project is closer to what real client onboarding looks like. Here is the comparison:

Aspect Chapter 9 (Godot Game) Chapter 10 (Radical Faeries)
Number of apps 1 2 (BookStack + Rallly)
Databases None MySQL (BookStack) + PostgreSQL (Rallly)
Secrets in Vault None Database credentials, app keys, mail config
ExternalSecrets None 2 ExternalSecret resources
HelmReleases None (raw Deployment) 2 HelmRelease resources
Ingress resources 1 2 (one per app)
Complexity Starter Realistic production workload

Think of Chapter 9 as a tutorial level. This chapter is the first real mission.


The Four Phases

Here is what you will do, broken into one page per phase:

Phase Page What Happens
1 Plan the Tenant Decide namespace name, list required apps, databases, secrets, and domains
2 Create the Tenant from Scratch Build the directory, namespace, Vault secrets, and ExternalSecrets
3 Deploy Apps for the Faeries Write HelmRelease manifests for BookStack and Rallly, plus Ingress resources
4 Verify and Handoff Push to Git, reconcile with Flux, verify everything works, hand off to the client

Each phase builds on the previous one. By the end, you will have onboarded a multi-app client from scratch.


Prerequisites

Before you start, make sure you have the following ready:

Prerequisite How to Check
Completed Chapter 9 You have a working tenant deployment under your belt
Understand secrets (Chapter 7) You know what Vault and ExternalSecrets do
VPN access (WireGuard) ping robin.spynl.net responds
Vault access vault status shows "Initialized: true, Sealed: false"
dds-k8s-cluster repo cloned ls ~/workspace/junovy/dds-k8s-cluster/clients/ shows existing tenants
kubectl configured for the cluster kubectl cluster-info --context admin@dds-prod-de-fsn1 shows the API server
flux CLI installed flux version shows output
Helm CLI installed helm version shows output

If any of these are not set up yet, refer back to Chapter 6 (Your Toolbox) and Chapter 7 (Secrets and Security).


What You Are Building

Here is a quick sketch of the final architecture inside the hst-radical-faeries namespace:

hst-radical-faeries namespace
├── BookStack (PHP app)
│   ├── HelmRelease → runs BookStack container + MySQL sidecar
│   ├── ExternalSecret → pulls DB creds + app key from Vault
│   ├── Ingress → bookstack.radical-faeries.junovy.com (TLS)
│   └── PersistentVolume → stores uploads and attachments
│
└── Rallly (Node.js app)
    ├── HelmRelease → runs Rallly container
    ├── ExternalSecret → pulls DB URL + secret key from Vault
    └── Ingress → rallly.radical-faeries.junovy.com (TLS)

Everything is defined in YAML, committed to Git, and deployed automatically by Flux.


Key Takeaways

  • The Radical Faeries need BookStack (wiki) and Rallly (scheduler) hosted on Junovy
  • This project involves two apps, two databases, secrets in Vault, and two Ingress resources
  • There are four phases: Plan, Create Tenant, Deploy Apps, Verify and Handoff
  • The final URLs are bookstack.radical-faeries.junovy.com and rallly.radical-faeries.junovy.com

What Is Next

Next up: Plan the Tenant where you will map out every resource, secret, and file before writing a single line of YAML.