Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions deployments/Cloud_HelloWorld/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Dynamo Deployment of Hello World Example with Dynamo Cloud
1. Prepare for Dynamo Cloud Setup
# Set your container registry
```sh
export ORG="NGC_ORG"
export TEAM="NGC_TEAM"
export DOCKER_SERVER=nvcr.io/${ORG}/${TEAM}
# Set the image tag (e.g., latest, 0.0.1, etc.)
export IMAGE_TAG=v0.1.0

earthly --push +all-docker --DOCKER_SERVER=$DOCKER_SERVER --IMAGE_TAG=$IMAGE_TAG
```
This step will build two images:
- nvcr.io/${ORG}/${TEAM}/dynamo-operator:${IMAGE_TAG}
- nvcr.io/${ORG}/${TEAM}/dynamo-api-store:${IMAGE_TAG}
Push them into docker registry
```sh
docker push nvcr.io/${ORG}/${TEAM}/dynamo-operator:${IMAGE_TAG}
docker nvcr.io/${ORG}/${TEAM}/dynamo-api-store:${IMAGE_TAG}
```
2. Deploy Dynamo Cloud
Get your docker authentication token
```sh
export DOCKER_USERNAME='$oauthtoken'
export DOCKER_PASSWORD='AUTHENTICATION_TOKEN'
export DOCKER_SERVER='nvcr.io/${ORG}/${TEAM}'
export NAMESPACE='dynamo-cloud'

cd dynamo/deploy/cloud/helm
kubectl create namespace $NAMESPACE
kubectl config set-context --current --namespace=$NAMESPACE
./deploy.sh
```
You should see the dynamo cloud related pods running in your k8s cluster.

3. Connect to Dynamo Cloud and Test
```sh
# In a separate terminal, run port-forward to expose the dynamo-store service locally
kubectl port-forward svc/dynamo-store 8000:80 -n $NAMESPACE

# Set DYNAMO_CLOUD to use the local port-forward endpoint
export DYNAMO_CLOUD=http://localhost:8000
dynamo deployment list
```

## 2. Dynamo Application Deployment
1. Build the Dynamo Base Image. For the hello world example, we can just build the leaner image without CUDA and vLLM making it suitable for CPU only deployments.
```bash
export CI_REGISTRY_IMAGE=nvcr.io/${ORG}/${TEAM}
export CI_COMMIT_SHA=hello-world

earthly +dynamo-base-docker --CI_REGISTRY_IMAGE=$CI_REGISTRY_IMAGE --CI_COMMIT_SHA=$CI_COMMIT_SHA
# Image should succesfully be built and tagged as nvcr.io/ORG/TEAM/dynamo-base-docker:hello-world
```
2. Push the built image to your docker registry and set environment variable
```bash
docker push nvcr.io/${ORG}/${TEAM}/dynamo-base-docker:hello-world
export DYNAMO_IMAGE=nvcr.io/${ORG}/${TEAM}/dynamo-base-docker:hello-world
```
3. Build the Dynamo application bundle.
```sh
###### Build Dynamo application bundle
cd dynamo/examples/hello_world
DYNAMO_TAG=$(dynamo build hello_world:Frontend | grep "Successfully built" | awk '{ print $3 }' | sed 's/\.$//')
# Create the deployment
export DEPLOYMENT_NAME=hello-world
dynamo deployment create $DYNAMO_TAG --no-wait -n $DEPLOYMENT_NAME
```

## 3. Dynamo Cloud Deployment and test
Test the deployed example
```sh
kubectl port-forward svc/dynamo-helloworld-frontend 8000:80
curl -X 'POST' 'http://localhost:8000/generate' \
-H 'accept: text/event-stream' \
-H 'Content-Type: application/json' \
-d '{"text": "dynamo_k8s_test"}'
```
and you should see the output `Frontend: Middle: Backend: dynamo_k8s_test-mid-back`
53 changes: 53 additions & 0 deletions deployments/Helm_HelloWorld/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Dynamo Deployment of Hello World Example with Helm Chart

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving a comment that applies to the rest of the helm deployments as well.

We are deprecating and removing the dynamo get commands in a future release (The SDK in general is going away). What this will mean is that the pipeline-values.yaml that gets auto-generated from the example will instead have to be authored by the user. This hopefully should not complicate the workflow too much.

## 1. Dynamo Application Image
1. Build the Dynamo Base Image. For the hello world example, we can just build the leaner image without CUDA and vLLM making it suitable for CPU only deployments.
```bash
export CI_REGISTRY_IMAGE=nvcr.io/ORG/TEAM
export CI_COMMIT_SHA=hello-world

earthly +dynamo-base-docker --CI_REGISTRY_IMAGE=$CI_REGISTRY_IMAGE --CI_COMMIT_SHA=$CI_COMMIT_SHA
# Image should succesfully be built and tagged as nvcr.io/ORG/TEAM/dynamo-base-docker:hello-world
```
2. Push the built image to your docker registry and set environment variable
```bash
docker push nvcr.io/ORG/TEAM/dynamo-base-docker:hello-world
export DYNAMO_IMAGE=nvcr.io/ORG/TEAM/dynamo-base-docker:hello-world
```
3. Build the Dynamo Application Image
```
cd dynamo/examples/hello_world
DOCKER_BUILDKIT=0 dynamo build hello_world:Frontend --containerize
```
You should get an image named `frontend:DYNAMO_TAG`, where `DYANMO_TAG` is a 16 character long string.

4. Get pipeline values from the application image.
```
dynamo get frontend:DYNAMO_TAG > pipeline-values.yaml
```

5. Push the application image to your docker registry
```
docker tag frontend:DYNAMO_TAG nvcr.io/ORG/TEAM/dynamo-application:hello-world
docker push nvcr.io/ORG/TEAM/dynamo-application:hello-world
```
## 2. Helm Chart update
1. The `pipeline-values.yaml` can be used as a reference for your `values.yaml` files.
2. In this example, 3 pods, `frontend`,`middle` and `backend` will be deployed together with `nats` and `etcd` services.
3. Update the `image:"nvcr.io/ORG/TEAM/dynamo-application:hello-world"` in the `values.yaml` with the Dynamo Application Image you built.
4. Update the `AUTHENTICATION_TOKEN` with your docker registry token
5. Update the version `DYNAMO_TAG` with real tag (Optional)

## 3. Helm Deployment and test
1. Now deploy the helm chart in local k8s environment.
```sh
helm install dynamo-hello-world chart/
```
2. Test the deployed example
```sh
kubectl port-forward svc/dynamo-helloworld-frontend 8000:80
curl -X 'POST' 'http://localhost:8000/generate' \
-H 'accept: text/event-stream' \
-H 'Content-Type: application/json' \
-d '{"text": "dynamo_k8s_test"}'
```
and you should see the output `Frontend: Middle: Backend: dynamo_k8s_test-mid-back`
21 changes: 21 additions & 0 deletions deployments/Helm_HelloWorld/chart/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: v2
name: dynamo-pipeline
description: A Helm chart to deploy a Dynamo pipeline on Kubernetes
type: application
version: 0.1.0
appVersion: 1.0.0
93 changes: 93 additions & 0 deletions deployments/Helm_HelloWorld/chart/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
{{- range .Values.services }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: dynamo-helloworld-{{ .name | lower }}
labels:
app: dynamo-helloworld-{{ .name | lower }}
spec:
replicas: {{ .config.workers | default 1 }}
selector:
matchLabels:
app: dynamo-helloworld-{{ .name | lower }}
template:
metadata:
labels:
app: dynamo-helloworld-{{ .name | lower }}
spec:
imagePullSecrets:
- name: {{ $.Values.dockerPullSecret.name }}
securityContext:
runAsUser: 0
containers:
- name: {{ $.Release.Name }}-{{ .name | lower }}
image: {{ $.Values.image }}
args:
{{ if $.Values.configFilePath }}
- cd src && uv run dynamo serve --service-name {{ .name }} {{ $.Values.dynamoIdentifier }} -f {{ $.Values.configFilePath }}
{{ else }}
- cd src && uv run dynamo serve --service-name {{ .name }} {{ $.Values.dynamoIdentifier }}
{{ end }}
command:
- sh
- -c
{{ if .config.resources }}
resources:
requests:
{{ if .config.resources.cpu }}
cpu: "{{ .config.resources.cpu }}"
{{ end }}
{{ if .config.resources.memory }}
memory: "{{ .config.resources.memory }}"
{{ end }}
{{ if .config.resources.gpu }}
nvidia.com/gpu: "{{ .config.resources.gpu }}"
{{ end }}
limits:
{{ if .config.resources.cpu }}
cpu: "{{ .config.resources.cpu }}"
{{ end }}
{{ if .config.resources.memory }}
memory: "{{ .config.resources.memory }}"
{{ end }}
{{ if .config.resources.gpu }}
nvidia.com/gpu: "{{ .config.resources.gpu }}"
{{ end }}
{{ end }}
env:
{{- if and .config.traffic .config.traffic.timeout }}
- name: TRAFFIC_TIMEOUT
value: "{{ .config.traffic.timeout }}"
{{- end }}
{{- if and .config.dynamo .config.dynamo.enabled }}
- name: DYNAMO_NAMESPACE
value: "{{ .config.dynamo.namespace }}"
- name: DYNAMO_NAME
value: "{{ .config.dynamo.name }}"
{{- end }}
{{- if .config.workers }}
- name: WORKERS
value: "{{ .config.workers }}"
{{- end }}
- name: PORT
value: "3000"
- name: NATS_SERVER
value: nats://{{ $.Release.Name }}-nats:4222
- name: ETCD_ENDPOINTS
value: {{ $.Release.Name }}-etcd:2379
---
{{- end }}
25 changes: 25 additions & 0 deletions deployments/Helm_HelloWorld/chart/templates/etcd-deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ $.Release.Name }}-etcd
spec:
replicas: 1
selector:
matchLabels:
app: {{ $.Release.Name }}-etcd
template:
metadata:
labels:
app: {{ $.Release.Name }}-etcd
spec:
imagePullSecrets:
- name: {{ $.Values.dockerPullSecret.name }}
containers:
- name: etcd
image: {{ .Values.etcd.image }}
env:
- name: ALLOW_NONE_AUTHENTICATION
value: "yes"
ports:
- containerPort: 2379
- containerPort: 2380
14 changes: 14 additions & 0 deletions deployments/Helm_HelloWorld/chart/templates/etcd-service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: {{ $.Release.Name }}-etcd
spec:
selector:
app: {{ $.Release.Name }}-etcd
ports:
- name: client
port: 2379
targetPort: 2379
- name: peer
port: 2380
targetPort: 2380
24 changes: 24 additions & 0 deletions deployments/Helm_HelloWorld/chart/templates/nats-deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ $.Release.Name }}-nats
spec:
replicas: 1
selector:
matchLabels:
app: {{ $.Release.Name }}-nats
template:
metadata:
labels:
app: {{ $.Release.Name }}-nats
spec:
imagePullSecrets:
- name: {{ $.Values.dockerPullSecret.name }}
containers:
- name: nats
image: {{ .Values.nats.image }}
args: ["-js", "--trace"]
ports:
- containerPort: 4222
- containerPort: 6222
- containerPort: 8222
17 changes: 17 additions & 0 deletions deployments/Helm_HelloWorld/chart/templates/nats-service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: v1
kind: Service
metadata:
name: {{ $.Release.Name }}-nats
spec:
selector:
app: {{ $.Release.Name }}-nats
ports:
- name: client
port: 4222
targetPort: 4222
- name: cluster
port: 6222
targetPort: 6222
- name: monitor
port: 8222
targetPort: 8222
7 changes: 7 additions & 0 deletions deployments/Helm_HelloWorld/chart/templates/secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: v1
kind: Secret
metadata:
name: {{ .Values.dockerPullSecret.name }}
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: {{ .Values.dockerPullSecret.auth | b64enc | quote }}
28 changes: 28 additions & 0 deletions deployments/Helm_HelloWorld/chart/templates/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
{{- range .Values.services }}
apiVersion: v1
kind: Service
metadata:
name: dynamo-helloworld-{{ .name | lower }}
spec:
selector:
app: dynamo-helloworld-{{ .name | lower }}
ports:
- protocol: TCP
port: 80
targetPort: 8000
---
{{- end }}
Loading