Getting started
π Documentation home
Everything you need to do from a fresh clone, in order. There are two paths:
- A. Local walkthrough β bring up the control plane and console with Docker Compose, no Kubernetes and no GPU.
- B. Real deployment β an all-in-one install on a GPU Kubernetes cluster, running actual sessions.
Related:
README.mdfor the overall shape,cluster-setup.mdfor building the cluster itself, andcluster-connect.mdfor registering clusters and attaching operators.
0. Clone and prerequisitesβ
git clone https://github.com/boanlab/gShare.git && cd gShare
| Path | Requirements |
|---|---|
| A. Local walkthrough | Docker and Docker Compose |
| B. Real deployment | kubectl pointed at the target cluster, helm v3, and a Kubernetes cluster. For GPU sessions: the NVIDIA runtime, HAMi, a default StorageClass, and ingress-nginx |
You do not need to build images. The components are published publicly as
boanlab/gshare-{backend,operator,frontend}:latest. Build only when you have changed the
code β see the appendix.
A. Local walkthrough (no Kubernetes, no GPU)β
This runs the control plane and console so you can explore the API and the UI. It does not include the operator or GPU scheduling, so by default no real session pod can start β that is path B.
To run real sessions from a Compose-hosted control plane, build a GPU cluster with
hack/cluster-bootstrap.sh up, register it from the console, then bring up the data plane
with make deploy-dataplane CLUSTER_ID=β¦ CONTROL_PLANE_URL=http://<compose-host>:8080.
The full procedure is in cluster-connect.md Β§C.
make compose-up # build and start api, worker, frontend, postgres, redis
- Console: http://localhost:8000
- API: http://localhost:8080 (
/healthz,/api/v1/...) - Login: admin@example.com / 12345678 β the Compose defaults. You are forced to change the password at first login.
Changing the defaults is optional; the stack runs without a
.envfile. To override, setGSHARE_BOOTSTRAP_ADMIN_EMAIL,GSHARE_BOOTSTRAP_ADMIN_PASSWORD, orGSHARE_SESSION_DOMAINin a repository-root.env(Compose loads it automatically) or in your shell environment beforemake compose-up. If you want strong secrets such as a real RS256 key, generate a.envwithhack/gen-secrets.shβ also optional for Compose.
make smoke # wait until the API reports healthy
make compose-down # stop and drop volumes
B. Real deployment (GPU Kubernetes cluster)β
The cluster only ever receives plain HTTP. A reverse proxy you own terminates TLS and
forwards to the ingress-nginx NodePort on :30080.
You edit exactly one file. Copy the template
domain.example.yamltodeploy/values/domain.yaml(not committed), fill in the domain and the administrator identity, and runmake deploy-incluster. Secrets, CRDs, namespaces, the database, Redis, and the admin password are all created by the chart. Skip step 0 if your cluster is already up;hack/cluster-infois only needed when building a new one.
Step 0 β prepare the clusterβ
If you already have ingress-nginx, a default StorageClass, and β for GPU work β HAMi and
the NVIDIA runtime, go to step 1. Otherwise see cluster-setup.md,
or take the automated path:
cp hack/cluster-info.example hack/cluster-info # fill in MASTER_NODE, WORKER_NODES(:mode), CPU_WORKERS
./hack/cluster-bootstrap.sh up # kubeadm + flannel + HAMi + ingress-nginx(:30080) + local-path
up labels the nodes according to the modes in cluster-info; manual labeling is only
needed on the step-by-step path.
Step 1 β decide the domain and TLSβ
-
Pick a console domain, for example
gshare.example.com. -
Point its DNS at your reverse proxy, and have the proxy terminate TLS and
proxy_passtohttp://<any-node>:30080, preserving theHostheader. -
Write the domain and administrator identity into the deployment-local overlay. This is the only configuration you touch on path B. It differs per deployment and must not be committed, so it lives in its own file (ignored by git; only the example is tracked):
cp deploy/values/domain.example.yaml deploy/values/domain.yaml# deploy/values/domain.yamlglobal:domains:console: gshare.example.com # the real domain β one host for the console and path-based sessionsbootstrapAdmin:email: admin@example.com # first super_admin login (default: admin@example.com)password: 12345678 # initial password; must be changed at first loginmake deploy-inclusterandmake prod-deployapply this file with-fwhen it exists, and fall back to the chart defaults when it does not. That one domain value drives the console, every session URL (/proxy/{cr}/{lab,terminal,code}), and the ingress host. The administrator account is created on first start with this email and password. Setpassword: ""to have a random one generated instead β read it back in step 3. Display names are edited from the console after login.
Step 2 β deployβ
make deploy-incluster
That is the whole install. The chart configures everything with no manual prerequisites:
in-cluster Postgres and Redis, secrets, CRDs, namespaces, the operator's internal JWT
(issued and rotated by a Job and CronJob), and registration of the local cluster. It uses
the public :latest images.
For the production variant β external CloudNativePG and Redis with external-secrets β use
make prod-deploywithdeploy/values/dockerhub.yaml.
Optional add-ons (each independent; enable via the overlay β every knob is a commented
example in domain.example.yaml):
- Monitoring β
make deploy-monitoringinstalls Prometheus with the dcgm / node / kube-state exporters. It powers the admin monitoring page, the per-session live-usage panels, and (viaoperator.prometheusUrl) the idle reaper's utilization source β on a cluster with more than one GPU node, setprometheusUrl; the HAMi-monitor fallback round-robins per-node pods and idle sessions are then never auto-paused. Prometheus keeps its data on a PVC of the cluster's default StorageClass β it does not need the optional storage node. (If an earlier install left a PVC pinned togshare-data, delete that PVC before re-applying:storageClassNameis immutable.) - Mixed GPU fleet β different card models in one cluster need
operator.perCardMode: true, which pins each session pod to the exact card the ledger reserved. Without it a session priced for one model can land on another. - LAN image registry β
deploy/registry/registry.yamlplus per-node trust; seecluster-setup.mdΒ§Local registry. Setapi.buildRegistryso console-driven image builds push there too. - Real volume quotas β the ZFS storage node
(
cluster-setup.mdΒ§Storage node); thenoperator.volumeStorageClass: gshare-data.
Step 3 β verify and log inβ
kubectl get pods -n gshare-system # api, worker, operator, frontend, pg, redis all Running
# The admin password defaults to 12345678. If you set a different one, or left it
# empty to get a random one, read it from the secret:
kubectl get secret -n gshare-system gshare-bootstrap-admin -o jsonpath='{.data.password}' | base64 -d
Open https://gshare.example.com through your reverse proxy and log in with
bootstrapAdmin.email and that password. You will be asked to change it immediately.
Step 4 β check the catalog (administrator)β
A default catalog is seeded idempotently at startup: GPU offerings (RTX, A100, H100),
base images, compute and GPU presets, a global resource policy, and the system wallet. As
an administrator you only edit and extend it, from the console or through
POST /api/v1/offerings and POST /api/v1/images / /images/import.
- An offering is what a user picks: a GPU model and tier with an hourly credit rate. The seeded rates are suggestions β adjust them in the console.
- An image is the session container image. The GShare session images ship JupyterLab, a web terminal, and code-server.
- Users are not limited to the shared catalog: a member can register images of their own
through the API (
POST /api/v1/images/importfor a public registry reference,POST /api/v1/image-buildsfor a build). Those rows are private to their owner, tagged My image in the wizard, and one member may hold at most 20 of them.
The operator reports GPU inventory automatically, so nodes and devices (for example RTX 4090) appear on the infrastructure screens without further setup.
Step 5 β create and connect to a session (user)β
A user logs in, picks an offering and an image, and creates a session. Once it is
running, the console shows connect links β each carrying a single-use token β all under
the one domain:
https://gshare.example.com/proxy/{cr}/labβ JupyterLabhttps://gshare.example.com/proxy/{cr}/terminalβ web terminal (ttyd)https://gshare.example.com/proxy/{cr}/code/β code-server (VS Code)
The ingress forward-auth redeems the single-use ?gshare_cnx=β¦ token for a short-lived
cookie and then proxies to the app. There is no SSH; the shell is the web terminal or the
code-server terminal.
Sessions can be paused and resumed. Pausing tears down the pod, returns the GPU, and stops billing; resuming re-acquires a GPU and starts it again.
Summaryβ
- Local:
make compose-up, then the console on:8000(control plane only). - All-in-one: prepare the cluster β set the domain and front the cluster with a
TLS-terminating proxy β
make deploy-inclusterβ log in as the administrator, review offerings and images β users create sessions β connect athttps://{domain}/proxy/{cr}/{lab|terminal|code}. - Compose plus an external cluster:
make compose-upfor the control plane βcluster-bootstrap.sh upon the GPU cluster β register it from the console βmake deploy-dataplane CLUSTER_ID=β¦ CONTROL_PLANE_URL=β¦. Seecluster-connect.mdΒ§C.
Appendix β building and pushing your own imagesβ
Only needed when you have changed a component; the default install uses the public images.
make images TAG=<tag> # build backend, operator, frontend
make login # log in with DOCKERHUB_USERNAME / DOCKERHUB_TOKEN
make push TAG=<tag>
make deploy-incluster TAG=<tag> # deploy that tag
- To inject secrets yourself instead of letting the chart generate them:
hack/gen-secrets.sh --k8s. - Tests:
make testfor unit and functional tests,make cifor the full gate.