Skip to content

Commit

Permalink
chatbot-rag-app: adds Kubernetes manifest and instructions
Browse files Browse the repository at this point in the history
Signed-off-by: Adrian Cole <[email protected]>
  • Loading branch information
codefromthecrypt committed Feb 26, 2025
1 parent d0605d2 commit 5145b72
Show file tree
Hide file tree
Showing 7 changed files with 365 additions and 8 deletions.
6 changes: 4 additions & 2 deletions docker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ Note: If you haven't checked out this repository, all you need is one file:
wget https://raw.githubusercontent.com/elastic/elasticsearch-labs/refs/heads/main/docker/docker-compose-elastic.yml
```

Use docker compose to run Elastic stack in the background:
Before you begin, ensure you have free CPU and memory on your Docker host. If
you plan to use ELSER, assume a minimum of 8 cpus and 6GB memory for the
containers in this compose file.

First, start this Elastic Stack in the background:
```bash
docker compose -f docker-compose-elastic.yml up --force-recreate --wait -d
```
Expand All @@ -20,7 +23,6 @@ Then, you can view Kibana at http://localhost:5601/app/home#/
If asked for a username and password, use username: elastic and password: elastic.

Clean up when finished, like this:

```bash
docker compose -f docker-compose-elastic.yml down
```
4 changes: 1 addition & 3 deletions example-apps/chatbot-rag-app/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ COPY frontend ./frontend
RUN cd frontend && yarn install
RUN cd frontend && REACT_APP_API_HOST=/api yarn build

# langchain and vertexai depend on a large number of system packages including
# linux-headers, g++, geos, geos-dev, rust and cargo. These are already present
# on -slim and adding them to -alpine results in a larger image than -slim.
# Use glibc-based image to get pre-compiled wheels for grpcio and tiktoken
FROM python:3.12-slim

WORKDIR /app
Expand Down
62 changes: 60 additions & 2 deletions example-apps/chatbot-rag-app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ Copy [env.example](env.example) to `.env` and fill in values noted inside.
## Installing and connecting to Elasticsearch

There are a number of ways to install Elasticsearch. Cloud is best for most
use-cases. We also have [docker-compose-elastic.yml](../../docker), that starts
Elasticsearch, Kibana, and APM Server on your laptop with one command.
use-cases. We also have [docker-compose-elastic.yml][docker-compose-elastic],
that starts Elasticsearch, Kibana, and APM Server on your laptop in one step.

Once you decided your approach, edit your `.env` file accordingly.

Expand Down Expand Up @@ -71,6 +71,62 @@ Clean up when finished, like this:
docker compose down
```

### Run with Kubernetes

Kubernetes is more complicated than Docker, but closer to the production
experience for many users. [k8s-manifest.yml](k8s-manifest.yml) creates the
same services, but needs additional configuration first.

First step is to setup your environment. [env.example](env.example) must be
copied to a file name `.env` and updated with `ELASTICSEARCH_URL` and
`OTEL_EXPORTER_OTLP_ENDPOINT` values visible to you Kubernetes deployment.

For example, if you started your Elastic Stack with [k8s-manifest-elastic.yml][k8s-manifest-elastic],
you would update these values:
```
ELASTICSEARCH_URL=http://elasticsearch:9200
OTEL_EXPORTER_OTLP_ENDPOINT=http://apm-server:8200
```

Then, import your `.env` file as a configmap like this:
```bash
kubectl create configmap chatbot-rag-app-env --from-env-file=.env
```

If you are using Vertex AI, make a secret for authentication:
```bash
kubectl create secret generic gcloud-credentials \
--from-file=application_default_credentials.json=$HOME/.config/gcloud/application_default_credentials.json
```

Now that your configuration is applied, create the chatbot-rag-app deployment
and service by applying this manifest:
```bash
kubectl apply -f k8s-manifest.yml
```

Next, block until chatbot-rag-app is available.
```bash
kubectl wait --for=condition=available --timeout=20m deployment/chatbot-rag-app
```

*Note*: The first run may take several minutes to become available. Here's how
to follow logs on this stage:
```bash
kubectl logs deployment.apps/chatbot-rag-app -c create-index -f
```

Next, forward the kibana port:
```bash
kubectl port-forward service/kibana 5601:5601 &
```

Clean up when finished, like this:

```bash
kubectl delete -f k8s-manifest.yml
```

### Run with Python

If you want to run this example with Python, you need to do a few things listed
Expand Down Expand Up @@ -196,3 +252,5 @@ docker compose up --build --force-recreate
---
[loader-docs]: https://python.langchain.com/docs/how_to/#document-loaders
[install-es]: https://www.elastic.co/search-labs/tutorials/install-elasticsearch
[docker-compose-elastic]: ../../docker/docker-compose-elastic.yml
[k8s-manifest-elastic]: ../../k8s/k8s-manifest-elastic.yml
6 changes: 5 additions & 1 deletion example-apps/chatbot-rag-app/env.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ FLASK_APP=api/app.py
PYTHONUNBUFFERED=1

# How you connect to Elasticsearch: change details to your instance
# This defaults to a Elastic Stack accessible via localhost. When this is
# running inside Kubernetes, update to http://elasticsearch:9200 or similar.
ELASTICSEARCH_URL=http://localhost:9200
ELASTICSEARCH_USER=elastic
ELASTICSEARCH_PASSWORD=elastic
Expand Down Expand Up @@ -68,7 +70,9 @@ OTEL_SDK_DISABLED=true
# Assign the service name that shows up in Kibana
OTEL_SERVICE_NAME=chatbot-rag-app

# Default to send traces to the Elastic APM server
# Default to send logs, traces and metrics to an Elastic APM server accessible
# via localhost. If using running inside k8s, update to http://apm-server:8200
# or similar.
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:8200
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf

Expand Down
57 changes: 57 additions & 0 deletions example-apps/chatbot-rag-app/k8s-manifest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: chatbot-rag-app
spec:
replicas: 1
selector:
matchLabels:
app: chatbot-rag-app
template:
metadata:
labels:
app: chatbot-rag-app
spec:
# The below will recreate your secret based on the gcloud credentials file
# kubectl create secret generic gcloud-credentials \
# --from-file=application_default_credentials.json=$HOME/.config/gcloud/application_default_credentials.json
volumes:
- name: gcloud-credentials
secret:
secretName: gcloud-credentials
initContainers:
- name: create-index
image: &image ghcr.io/elastic/elasticsearch-labs/chatbot-rag-app:latest
args: ["flask", "create-index"]
env:
- name: FLASK_APP
value: api/app.py
# This recreates your configmap based on your .env file:
# kubectl create configmap chatbot-rag-app-env --from-env-file=.env
envFrom: &envFrom
- configMapRef:
name: chatbot-rag-app-env
volumeMounts: &volumeMounts
- name: gcloud-credentials
mountPath: /root/.config/application_default_credentials.json
readOnly: true
containers:
- name: api-frontend
image: *image
ports:
- containerPort: 4000
envFrom: *envFrom
volumeMounts: *volumeMounts
---
apiVersion: v1
kind: Service
metadata:
name: api
spec:
selector:
app: chatbot-rag-app
ports:
- protocol: TCP
port: 4000
targetPort: 4000
47 changes: 47 additions & 0 deletions k8s/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Running your own Elastic Stack with Kubernetes

If you'd like to start Elastic with Kubernetes, you can use the provided
[manifest-elastic.yml](manifest-elastic.yml) file. This starts
Elasticsearch, Kibana, and APM Server in an existing Kubernetes cluster.

Note: If you haven't checked out this repository, all you need is one file:
```bash
wget https://raw.githubusercontent.com/elastic/elasticsearch-labs/refs/heads/main/docker/docker-compose-elastic.yml
```

Before you begin, ensure you have free CPU and memory in your cluster. If you
plan to use ELSER, assume a minimum of 8 cpus and 6GB memory for the containers
in this manifest.

First, start this Elastic Stack in the background:
```bash
kubectl apply -f k8s-manifest-elastic.yml
```

**Note**: For simplicity, this adds an Elastic Stack to the default namespace.
Commands after here are simpler due to this. If you want to choose a different
one, use `kubectl`'s `--namespace` flag!

Next, block until the whole stack is available. First install or changing the
Elastic Stack version can take a long time due to image pulling.
```bash
kubectl wait --for=condition=available --timeout=10m \
deployment/elasticsearch \
deployment/kibana \
deployment/apm-server
```

Next, forward the kibana port:
```bash
kubectl port-forward service/kibana 5601:5601 &
```

Finally, you can view Kibana at http://localhost:5601/app/home#/

If asked for a username and password, use username: elastic and password: elastic.

Clean up when finished, like this:

```bash
kubectl delete -f k8s-manifest-elastic.yml
```
Loading

0 comments on commit 5145b72

Please sign in to comment.