Application Hub Deployment Guide⚓︎
OIDC is currently a requirement for the Application Hub. This is a work in progress and will be updated in the future.
The Application Hub provides a suite of web-based tools—like JupyterLab and Code Server—for interactive analysis and application development on Earth Observation (EO) data. It can also host custom dashboards and interactive web apps
Introduction⚓︎
The Application Hub Building Block provides JupyterLab notebooks, Code Server and custom web applications for EO data analysis and processing.
The building block offers:
- JupyterLab for interactive data analysis and notebook execution
- Code Server for browser-based development environments
- Multi-user support with profile-based resource allocation
- Group-based access control for different user categories
- Integration with OIDC for authentication
- Persistent storage for user workspaces
- Customisable container images per profile
Prerequisites⚓︎
Before deploying the Application Hub, ensure you have the following:
| Component | Requirement | Documentation Link |
|---|---|---|
| Kubernetes | Cluster (tested on v1.32) | Installation Guide |
| Helm | Version 3.8 or newer | Installation Guide |
| kubectl | Configured for cluster access | Installation Guide |
| Ingress Controller | Properly installed (NGINX or APISIX) | Installation Guide |
| TLS Certificates | Managed via cert-manager or manually |
TLS Certificate Management Guide |
| OIDC Provider | Keycloak or compatible | IAM Deployment Guide |
| Storage Class | For persistent volumes | Default or custom storage class |
Clone the Deployment Guide Repository:
Validate your environment:
Run the validation script to ensure all prerequisites are met:
Deployment Steps⚓︎
1. Run the Configuration Script⚓︎
Core Configuration Parameters
During the script execution, you will be prompted to provide:
INGRESS_HOST: Base domain for ingress hosts.- Example:
example.com
- Example:
PERSISTENT_STORAGECLASS: Storage class for persistent volumes.- Example:
standard
- Example:
CLUSTER_ISSUER(if usingcert-manager): Name of the ClusterIssuer.- Example:
letsencrypt-http01-apisix
- Example:
NODE_SELECTOR_KEY: Determine which nodes will run the Application Hub pods.- Example:
kubernetes.io/os - Read more: Node Selector Documentation
- Example:
NODE_SELECTOR_VALUE: Value for the node selector key.- Example:
linux
- Example:
OIDC Configuration (We will set this up in the next step):
KEYCLOAK_HOST: OIDC provider base domain will be asked if this hasn’t been set. JupyterHub requires an OIDC provider for authentication.- Example:
auth.example.com
- Example:
APPHUB_CLIENT_ID: Client ID for the OIDC provider.- Example:
application-hub
- Example:
2. Create a Keycloak Client:⚓︎
To enable Jupyter notebooks and other interactive services to authenticate users, you must integrate the Application Hub with an OIDC identity provider. This requires creation of a Client in Keycloak (part of IAM BB).
The client can be created using the Crossplane Keycloak provider via the Client CRD.
source ~/.eoepca/state
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: ${APPHUB_CLIENT_ID}-keycloak-client
namespace: iam-management
stringData:
client_secret: ${APPHUB_CLIENT_SECRET}
---
apiVersion: openidclient.keycloak.m.crossplane.io/v1alpha1
kind: Client
metadata:
name: ${APPHUB_CLIENT_ID}
namespace: iam-management
spec:
forProvider:
realmId: ${REALM}
clientId: ${APPHUB_CLIENT_ID}
name: Application Hub
description: Application Hub OIDC
enabled: true
accessType: CONFIDENTIAL
rootUrl: ${HTTP_SCHEME}://app-hub.${INGRESS_HOST}
baseUrl: ${HTTP_SCHEME}://app-hub.${INGRESS_HOST}
adminUrl: ${HTTP_SCHEME}://app-hub.${INGRESS_HOST}
serviceAccountsEnabled: true
directAccessGrantsEnabled: true
standardFlowEnabled: true
oauth2DeviceAuthorizationGrantEnabled: true
useRefreshTokens: true
authorization:
- allowRemoteResourceManagement: false
decisionStrategy: UNANIMOUS
keepDefaults: true
policyEnforcementMode: ENFORCING
validRedirectUris:
- "/*"
webOrigins:
- "/*"
clientSecretSecretRef:
name: ${APPHUB_CLIENT_ID}-keycloak-client
key: client_secret
providerConfigRef:
name: provider-keycloak
kind: ProviderConfig
EOF
The Client should be created successfully.
3. Deploy the Application Hub Using Helm⚓︎
helm repo add eoepca https://eoepca.github.io/helm-charts
helm repo update eoepca
helm upgrade -i application-hub eoepca/application-hub \
--version 2.1.0 \
--values generated-values.yaml \
--namespace application-hub \
--create-namespace
3.1. Configure Ingress⚓︎
4. Create an admin user⚓︎
By default, the Application Hub has a demo admin user named eric. You will need to create this user in Keycloak (or your OIDC provider) to access the Application Hub admin.
The user can be created declaratively using the CRD defined by the Crossplane Keycloak provider. A Secret is used to inject the password securely.
source ~/.eoepca/state
username="eric"
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: ${username}-user-password
namespace: iam-management
stringData:
password: ${KEYCLOAK_TEST_PASSWORD}
---
apiVersion: user.keycloak.m.crossplane.io/v1alpha1
kind: User
metadata:
name: ${username}
namespace: iam-management
spec:
forProvider:
realmId: eoepca
username: ${username}
email: ${username}@eoepca.org
emailVerified: true
firstName: ${username}
lastName: Testuser
initialPassword:
- temporary: false
valueSecretRef:
name: ${username}-user-password
key: password
providerConfigRef:
name: provider-keycloak
kind: ProviderConfig
EOF
Alternatively you can create this user through the Keycloak admin interface.
- Create Groups in AppHub
Once eric has been created, navigate to the Application Hub admin panel:
-
Log in with the
ericuser. -
Select > Manage Groups and create the following groups with this exact naming:
group-1group-2group-3

- Assign Users to Groups
Individually assign the eric user to each group and hit Apply.

- Select a Profile
Return to the primary Application Hub interface (https://app-hub.${INGRESS_HOST}/) and log in as eric.
You should now see a list of the preconfigured profiles. Select one to spawn an application profile.

- Launch a Profile
Select one of the profiles to launch a profile. You will then be redirected to the relevant tooling environment.

***⚓︎
5. Validation⚓︎
5.1 Automated Validation⚓︎
Run validation:
5.2 Manual Validation⚓︎
- Check Kubernetes Resources:
Ensure the JupyterHub pod(s) and other components are in the Running state.
- Access the Hub:
- Go to
https://app-hub.${INGRESS_HOST}/. - You should be redirected to Keycloak (or your chosen OIDC provider) for login if OIDC is set up.
- Upon successful login, you’ll land in the JupyterHub interface (the “spawn” page).
- Spawn a Notebook:
While this Building Block is still in development, the following steps may not work as expected. This section will be updated in the future.
- If you have multiple Profiles, pick one.
- Wait for the container to start. You should end up in a JupyterLab interface.
If something fails (e.g. a 401 from Keycloak or a “profile list is empty” error), review the logs:
6. Advanced Configuration⚓︎
Check the JupyterHub Configuration Reference for more advanced settings and options.
Uninstallation⚓︎
To uninstall the Application Hub and clean up associated resources:
Further Reading⚓︎
- Application Hub Design Document
- EOEPCA+ Helm Charts Repository
- EOEPCA+ Deployment Guide Repository
- JupyterLab Documentation
Feedback⚓︎
If you encounter any issues or have suggestions for improvement, please open an issue on the EOEPCA+Deployment Guide GitHub Repository.