Skip to content

Commit b81319b

Browse files
authored
Merge branch 'elastic:main' into main
2 parents fc9cdba + f20a2d2 commit b81319b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+6225
-55
lines changed

bin/find-notebooks-to-test.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ EXEMPT_NOTEBOOKS=(
3030
"notebooks/integrations/llama3/rag-elastic-llama3.ipynb"
3131
"notebooks/integrations/azure-openai/vector-search-azure-openai-elastic.ipynb"
3232
"notebooks/enterprise-search/app-search-engine-exporter.ipynb",
33+
"notebooks/enterprise-search/elastic-crawler-to-open-crawler-migration.ipynb",
34+
"notebooks/enterprise-search/app-search-crawler-to-open-crawler-migration.ipynb",
3335
"notebooks/playground-examples/bedrock-anthropic-elasticsearch-client.ipynb",
3436
"notebooks/playground-examples/openai-elasticsearch-client.ipynb",
3537
"notebooks/integrations/hugging-face/huggingface-integration-millions-of-documents-with-cohere-reranking.ipynb",

docker/README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@ Note: If you haven't checked out this repository, all you need is one file:
99
wget https://raw.githubusercontent.com/elastic/elasticsearch-labs/refs/heads/main/docker/docker-compose-elastic.yml
1010
```
1111

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

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

2225
Clean up when finished, like this:
23-
2426
```bash
2527
docker compose -f docker-compose-elastic.yml down
2628
```

docker/docker-compose-elastic.yml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ services:
2727
test: # readiness probe taken from kbn-health-gateway-server script
2828
[
2929
"CMD-SHELL",
30-
"curl -s http://localhost:9200 | grep -q 'missing authentication credentials'",
30+
"curl --max-time 1 -s http://localhost:9200 | grep -q 'missing authentication credentials'",
3131
]
3232
start_period: 10s
3333
interval: 1s
@@ -41,12 +41,15 @@ services:
4141
image: docker.elastic.co/elasticsearch/elasticsearch:8.17.2
4242
container_name: elasticsearch_settings
4343
restart: 'no'
44+
# gen-ai assistants in kibana save state in a way that requires system
45+
# access, so set kibana_system's password to a known value.
4446
command: >
45-
bash -c '
46-
# gen-ai assistants in kibana save state in a way that requires security to be enabled, so we need to create
47-
# a kibana system user before starting it.
47+
bash -c '
4848
echo "Setup the kibana_system password";
49-
until curl -s -u "elastic:elastic" -X POST http://elasticsearch:9200/_security/user/kibana_system/_password -d "{\"password\":\"elastic\"}" -H "Content-Type: application/json" | grep -q "^{}"; do sleep 5; done;
49+
until curl --max-time 1 -s -u "elastic:elastic" \
50+
-X POST http://elasticsearch:9200/_security/user/kibana_system/_password \
51+
-d "{\"password\":\"elastic\"}" \
52+
-H "Content-Type: application/json" | grep -q "^{}"; do sleep 5; done;
5053
'
5154
5255
kibana:
@@ -69,7 +72,7 @@ services:
6972
- XPACK_ENCRYPTEDSAVEDOBJECTS_ENCRYPTIONKEY=fhjskloppd678ehkdfdlliverpoolfcr
7073
- SERVER_PUBLICBASEURL=http://127.0.0.1:5601
7174
healthcheck:
72-
test: ["CMD-SHELL", "curl -s http://localhost:5601/api/status | grep -q 'All services are available'"]
75+
test: ["CMD-SHELL", "curl --max-time 1 -s http://localhost:5601/api/status | grep -q 'available'"]
7376
retries: 300
7477
interval: 1s
7578

example-apps/chatbot-rag-app/Dockerfile

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,17 @@ COPY frontend ./frontend
55
RUN cd frontend && yarn install
66
RUN cd frontend && REACT_APP_API_HOST=/api yarn build
77

8+
# Use glibc-based image to get pre-compiled wheels for grpcio and tiktoken
89
FROM python:3.12-slim
910

1011
WORKDIR /app
1112
RUN mkdir -p ./frontend/build
1213
COPY --from=build-step ./app/frontend/build ./frontend/build
13-
RUN mkdir ./api
14-
RUN mkdir ./data
15-
16-
RUN apt-get update && apt-get install -y \
17-
build-essential \
18-
curl \
19-
software-properties-common \
20-
git \
21-
&& rm -rf /var/lib/apt/lists/*
22-
2314

2415
COPY requirements.txt ./requirements.txt
2516
RUN pip3 install -r ./requirements.txt
17+
18+
RUN mkdir -p ./api ./data
2619
COPY api ./api
2720
COPY data ./data
2821

@@ -31,16 +24,6 @@ EXPOSE 4000
3124
# Default to disabling instrumentation, can be overridden to false in
3225
# docker invocations to reenable.
3326
ENV OTEL_SDK_DISABLED=true
27+
ENTRYPOINT [ "opentelemetry-instrument" ]
3428

35-
# https://github.com/elastic/genai-instrumentation/issues/255
36-
# Currently Python SDK has a bug that spams logs when opentelemetry-instrument is used
37-
# with SDK being disabled. Until it is fixed, we handle it in our own entrypoint by
38-
# avoiding opentelemetry-instrument when SDK is disabled.
39-
RUN echo 'if [ "${OTEL_SDK_DISABLED:-true}" == "false" ]; \
40-
then \
41-
opentelemetry-instrument $@; \
42-
else \
43-
exec $@; \
44-
fi' > entrypoint.sh
45-
ENTRYPOINT [ "bash", "-eu", "./entrypoint.sh" ]
46-
CMD [ "python", "api/app.py"]
29+
CMD [ "python", "api/app.py" ]

example-apps/chatbot-rag-app/README.md

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ Copy [env.example](env.example) to `.env` and fill in values noted inside.
2222
## Installing and connecting to Elasticsearch
2323

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

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

@@ -71,6 +71,69 @@ Clean up when finished, like this:
7171
docker compose down
7272
```
7373

74+
### Run with Kubernetes
75+
76+
Kubernetes is more complicated than Docker, but closer to the production
77+
experience for many users. [k8s-manifest.yml](k8s-manifest.yml) creates the
78+
same services, but needs additional configuration first.
79+
80+
First step is to setup your environment. [env.example](env.example) must be
81+
copied to a file name `.env` and updated with `ELASTICSEARCH_URL` and
82+
`OTEL_EXPORTER_OTLP_ENDPOINT` values visible to you Kubernetes deployment.
83+
84+
For example, if you started your Elastic Stack with [k8s-manifest-elastic.yml][k8s-manifest-elastic],
85+
you would update these values:
86+
```
87+
ELASTICSEARCH_URL=http://elasticsearch:9200
88+
OTEL_EXPORTER_OTLP_ENDPOINT=http://apm-server:8200
89+
```
90+
91+
Then, import your `.env` file as a configmap like this:
92+
```bash
93+
kubectl create configmap chatbot-rag-app-env --from-env-file=.env
94+
```
95+
96+
<details>
97+
<summary>To use Vertex AI, set `LLM_TYPE=vertex` in your `.env` and follow these steps</summary>
98+
99+
The `api-frontend container` needs access to your Google Cloud credentials.
100+
Share your `application_default_credentials.json` as a Kubernetes secret:
101+
```bash
102+
# Logs you into Google Cloud and creates application_default_credentials.json
103+
gcloud auth application-default login
104+
# Adds your credentials to a Kubernetes secret named gcloud-credentials
105+
kubectl create secret generic gcloud-credentials \
106+
--from-file=application_default_credentials.json=$HOME/.config/gcloud/application_default_credentials.json
107+
```
108+
</details>
109+
110+
Now that your configuration is applied, create the `chatbot-rag-app` deployment
111+
and service by applying this manifest:
112+
```bash
113+
kubectl apply -f k8s-manifest.yml
114+
```
115+
116+
Next, block until `chatbot-rag-app` is available.
117+
```bash
118+
kubectl wait --for=condition=available --timeout=20m deployment/chatbot-rag-app
119+
```
120+
121+
*Note*: The first run may take several minutes to become available. Here's how
122+
to follow logs on this stage:
123+
```bash
124+
kubectl logs deployment.apps/chatbot-rag-app -c create-index -f
125+
```
126+
127+
Next, forward the web UI port:
128+
```bash
129+
kubectl port-forward deployment.apps/chatbot-rag-app 4000:4000 &
130+
```
131+
132+
Clean up when finished, like this:
133+
```bash
134+
kubectl delete -f k8s-manifest.yml
135+
```
136+
74137
### Run with Python
75138

76139
If you want to run this example with Python, you need to do a few things listed
@@ -165,8 +228,6 @@ pip-compile
165228
pip install -r requirements.txt
166229
# Add opentelemetry instrumentation for these dependencies
167230
edot-bootstrap >> requirements.txt
168-
# Missing dependency for langtrace vertexai instrumentation
169-
echo "setuptools" >> requirements.txt
170231
# Install opentelemetry dependencies
171232
pip install -r requirements.txt
172233
```
@@ -198,3 +259,5 @@ docker compose up --build --force-recreate
198259
---
199260
[loader-docs]: https://python.langchain.com/docs/how_to/#document-loaders
200261
[install-es]: https://www.elastic.co/search-labs/tutorials/install-elasticsearch
262+
[docker-compose-elastic]: ../../docker/docker-compose-elastic.yml
263+
[k8s-manifest-elastic]: ../../k8s/k8s-manifest-elastic.yml

example-apps/chatbot-rag-app/env.example

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ FLASK_APP=api/app.py
66
PYTHONUNBUFFERED=1
77

88
# How you connect to Elasticsearch: change details to your instance
9+
# This defaults to a Elastic Stack accessible via localhost.
10+
#
11+
# When running inside Kubernetes, set to http://elasticsearch.default.svc:9200
12+
# or similar.
913
ELASTICSEARCH_URL=http://localhost:9200
1014
ELASTICSEARCH_USER=elastic
1115
ELASTICSEARCH_PASSWORD=elastic
@@ -68,7 +72,11 @@ OTEL_SDK_DISABLED=true
6872
# Assign the service name that shows up in Kibana
6973
OTEL_SERVICE_NAME=chatbot-rag-app
7074

71-
# Default to send traces to the Elastic APM server
75+
# Default to send logs, traces and metrics to an Elastic APM server accessible
76+
# via localhost.
77+
#
78+
# When running inside Kubernetes, set to http://elasticsearch.default.svc:9200
79+
# or similar.
7280
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:8200
7381
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
7482

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
# chatbot-rag-app deploys "create-index" to install ELSER and load values.
3+
# Then, it starts "api-frontend" to serve the application.
4+
apiVersion: apps/v1
5+
kind: Deployment
6+
metadata:
7+
name: chatbot-rag-app
8+
spec:
9+
replicas: 1
10+
selector:
11+
matchLabels:
12+
app: chatbot-rag-app
13+
template:
14+
metadata:
15+
labels:
16+
app: chatbot-rag-app
17+
spec:
18+
# For `LLM_TYPE=vertex`: create a volume for application_default_credentials.json
19+
volumes:
20+
- name: gcloud-credentials
21+
secret:
22+
secretName: gcloud-credentials
23+
optional: true # only read when `LLM_TYPE=vertex`
24+
initContainers:
25+
- name: create-index
26+
image: &image ghcr.io/elastic/elasticsearch-labs/chatbot-rag-app:latest
27+
command: &command [ "opentelemetry-instrument" ] # match image
28+
args: [ "flask", "create-index" ]
29+
# This recreates your configmap based on your .env file:
30+
# kubectl create configmap chatbot-rag-app-env --from-env-file=.env
31+
envFrom: &envFrom
32+
- configMapRef:
33+
name: chatbot-rag-app-env
34+
containers:
35+
- name: api-frontend
36+
image: *image
37+
command: *command
38+
args: [ "python", "api/app.py" ]
39+
ports:
40+
- containerPort: 4000
41+
envFrom: *envFrom
42+
# For `LLM_TYPE=vertex`: mount credentials to the path read by the google-cloud-sdk
43+
volumeMounts:
44+
- name: gcloud-credentials
45+
mountPath: /root/.config/gcloud
46+
readOnly: true
47+
---
48+
apiVersion: v1
49+
kind: Service
50+
metadata:
51+
name: api
52+
spec:
53+
selector:
54+
app: chatbot-rag-app
55+
ports:
56+
- protocol: TCP
57+
port: 4000
58+
targetPort: 4000

example-apps/chatbot-rag-app/requirements.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ langchain-mistralai
1616

1717
# EDOT dependencies
1818
elastic-opentelemetry
19-
# Additional LLM support not in EDOT
19+
# Additional LLM support not yet in EDOT
2020
langtrace-python-sdk

0 commit comments

Comments
 (0)