Molecular Dynamics simulation dashboard with JupyterHub integration.
-
Add GitHub secrets (Settings → Secrets):
REGISTRY_USERNAME- Container registry userREGISTRY_PASSWORD- Container registry passwordKUBECONFIG- Your kubeconfig base64 encoded:cat ~/.kube/config | base64 -w 0OAUTH_CLIENT_ID- OAuth client ID for authenticationOAUTH_CLIENT_SECRET- OAuth client secretS3_ACCESS_KEY- S3 access keyS3_SECRET_KEY- S3 secret keyMDREPO_CLIENT_ID- MDRepo OAuth client ID for publishing experimentsMDREPO_CLIENT_SECRET- MDRepo OAuth client secretTUNER_USER- Username for Gromacs TunerTUNER_PASSWORD- Password for Gromacs Tuner
-
Push to deploy:
- Push to
dev→ deploys to dev environment (tag:dev) - Push to
master→ deploys to production (tag:YYYYMMDD-<commit-sha>)
- Push to
All secrets are automatically created in the namespace during deployment.
| Environment | Branch | Tag Format | Pull Policy |
|---|---|---|---|
| Dev | dev |
Static dev |
Always |
| Prod | master |
YYYYMMDD-<sha> + latest |
IfNotPresent |
Configure in Harbor UI (Project → Policy → Tag Retention):
- Dev tags: Repository
**, tagdev→ Retain always - Prod latest: Repository
**, taglatest→ Retain always - Prod dated: Repository
**, tag*-*→ Keep last 10 pushed
config.yaml- Production environment configurationconfig.dev.yaml- Development environment configuration
Install the Dev Containers extension in VSCode, then F1 → "Reopen in Container". Includes Docker-in-Docker, kubectl, and all dev tools.
make build ENV=dev # Build images
make all ENV=dev # Build, push, deploy
make status ENV=dev # Check status
make history ENV=prod # Show deployment history
make rollback ENV=prod REVISION=3 # Rollback to specific revision
make help # Show all commandsIf you need to deploy manually (bypassing CI/CD), follow these steps.
Ensure you have the following tools installed:
dockerkubectlhelmyqgomplatemake
Choose your target environment (dev or prod):
export ENV=dev # or prodYou must manually create the required Kubernetes secrets in your target namespace.
First, get the namespace and package name from your config:
if [ "${ENV}" = "dev" ]; then
CONFIG=config.dev.yaml
else
CONFIG=config.yaml
fi
NAMESPACE=$(yq '.namespace' "${CONFIG}")
PACKAGE=$(yq '.helm.package' "${CONFIG}")
kubectl create namespace "${NAMESPACE}" --dry-run=client -o yaml | kubectl apply -f -Then create the secrets (replace placeholders with actual values):
# OAuth Credentials
kubectl create secret generic oidc-credentials \
--from-literal=client_id="YOUR_CLIENT_ID" \
--from-literal=client_secret="YOUR_CLIENT_SECRET" \
-n ${NAMESPACE}
# Kubeconfig for the cluster (used by the app to spawn resources)
kubectl create secret generic ${PACKAGE}-kubeconfig-secret \
--from-file=config=$HOME/.kube/config \
-n ${NAMESPACE}
# S3 Credentials
kubectl create secret generic ${PACKAGE}-s3-creds \
--from-literal=S3_ACCESS_KEY="YOUR_S3_ACCESS_KEY" \
--from-literal=S3_SECRET_KEY="YOUR_S3_SECRET_KEY" \
-n ${NAMESPACE}
# MDRepo OAuth Credentials (for publishing experiments to MDRepo)
kubectl create secret generic ${PACKAGE}-mdrepo-credentials \
--from-literal=client_id="YOUR_MDREPO_CLIENT_ID" \
--from-literal=client_secret="YOUR_MDREPO_CLIENT_SECRET" \
-n ${NAMESPACE}
# Gromacs Tuner Credentials
kubectl create secret generic tuner-auth \
--from-literal=user="YOUR_TUNER_USER" \
--from-literal=password="YOUR_TUNER_PASSWORD" \
-n ${NAMESPACE}Once secrets are in place, you can run the full deployment pipeline:
# 1. Build and push all docker images
make push ENV=${ENV}
# 2. Package and push the mdrun-api Helm chart (sub-chart for mddash)
make push-mdrun-api-chart ENV=${ENV}
# 3. Deploy to Kubernetes
# For first-time installation:
make -C helm install ENV=${ENV}
# For updates:
make deploy ENV=${ENV}Shared infrastructure components that manage the platform and compute resources.
- JupyterHub
- Location: Configured in
helm/charts/mddash/values.yaml.tmpl - Purpose: Orchestrates the platform by managing user logins and spawning isolated environments for each user on demand.
- Location: Configured in
- MDRun API
- Location:
mdrun-api/,helm/charts/mdrun-api(Configured inhelm/charts/mddash/values.yaml.tmpl) - Purpose: Decouples simulation execution from user sessions, ensuring long-running GROMACS jobs continue even if the user logs out.
- Location:
- Gromacs Tuner
- Location: source code (Configured in
helm/charts/mddash/values.yaml.tmpl) - Purpose: Automatically benchmarks and selects the most efficient simulation parameters to optimize performance and resource usage.
- Location: source code (Configured in
Isolated environments created for each logged-in user.
- Proxy (Caddy)
- Location:
dashboard/proxy/ - Port:
8888,2019(proxy admin) - Purpose: Acts as the single entry point for the user pod, routing traffic to the appropriate internal service (UI, API, or Jupyter) and serving the frontend application.
- Location:
- JupyterHub Singleuser
- Location: Configured in
helm/charts/mddash/values.yaml.tmpl - Port:
8080 - Purpose: Provides the standard interface required by JupyterHub to manage the pod's lifecycle and connectivity.
- Location: Configured in
- Forward Auth
- Location:
dashboard/auth/ - Port:
5001 - Purpose: Secures the application by intercepting requests and validating JupyterHub authentication tokens before they reach the API or UI.
- Location:
- UI
- Location:
dashboard/ui/ - Purpose: Simplifies the complex workflow of molecular dynamics by providing a graphical interface for experiment setup and monitoring.
- Location:
- API
- Location:
dashboard/api/ - Port:
5000 - Purpose: Centralizes business logic to manage experiment state and coordinate actions between the user interface and backend simulation services.
- Location:
- S3 Sync Daemon
- Location:
dashboard/s3-sync/ - Purpose: Bridges the gap between local file access and cloud storage by automatically syncing user data to S3 for persistence and sharing.
- Location:
- Jupyter Notebooks
- Location:
notebook/ - Purpose: Offers an interactive environment for specific setup tasks (like protein preparation) that require manual visualization or intervention.
- Location:
- User PVC
- Location: Configured in
helm/charts/mddash/pre_spawn_hook.py - Purpose: Mounts the
/mddashdirectory to a persistent volume, ensuring user data and configurations persist across sessions.
- Location: Configured in
Services outside the Kubernetes cluster that the application depends on.
- S3
- Location: Endpoint configured in
config.yamlandconfig.dev.yaml(secrets stored in${PACKAGE}-s3-creds) - Purpose: Provides a central, scalable storage layer accessible by all services to persist large simulation datasets and trajectories.
- Location: Endpoint configured in
