Skip to content

Commit 12ec629

Browse files
committed
Merge branch 'sunman' of https://github.com/elastic/elasticsearch-labs into sunman
2 parents 1b2974f + 87988ce commit 12ec629

File tree

275 files changed

+135043
-5828
lines changed

Some content is hidden

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

275 files changed

+135043
-5828
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
name: build chatbot-rag-app image
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- example-apps/chatbot-rag-app/**
9+
- .github/workflows/docker-chatbot-rag-app.yml
10+
- '!**/*.md'
11+
pull_request:
12+
branches:
13+
- main
14+
paths:
15+
# Verify changes to the Dockerfile on PRs
16+
- example-apps/chatbot-rag-app/Dockerfile
17+
- .github/workflows/docker-chatbot-rag-app.yml
18+
- '!**/*.md'
19+
workflow_dispatch:
20+
21+
permissions:
22+
contents: read
23+
packages: write
24+
25+
env:
26+
IMAGE: ghcr.io/${{ github.repository }}/chatbot-rag-app
27+
28+
jobs:
29+
build-image:
30+
strategy:
31+
matrix:
32+
runner:
33+
- ubuntu-24.04
34+
- ubuntu-24.04-arm
35+
runs-on: ${{ matrix.runner }}
36+
steps:
37+
- uses: actions/checkout@v4
38+
- uses: docker/setup-buildx-action@v3
39+
- uses: docker/login-action@v3
40+
if: github.event_name == 'push'
41+
with:
42+
registry: ghcr.io
43+
username: ${{ github.actor }}
44+
password: ${{ secrets.GITHUB_TOKEN }}
45+
- uses: docker/build-push-action@v6
46+
id: build
47+
with:
48+
context: example-apps/chatbot-rag-app
49+
outputs: type=image,name=${{ env.IMAGE }},push-by-digest=true,name-canonical=true,push=${{ github.event_name == 'push' && 'true' || 'false' }}
50+
cache-from: type=gha
51+
cache-to: type=gha,mode=max
52+
- name: export digest
53+
if: github.event_name == 'push'
54+
run: |
55+
mkdir -p /tmp/digests
56+
digest="${{ steps.build.outputs.digest }}"
57+
touch "/tmp/digests/${digest#sha256:}"
58+
- name: upload digest
59+
if: github.event_name == 'push'
60+
uses: actions/upload-artifact@v4
61+
with:
62+
name: digests-${{ matrix.runner }}
63+
path: /tmp/digests/*
64+
if-no-files-found: error
65+
retention-days: 1
66+
67+
push-manifest:
68+
runs-on: ubuntu-24.04
69+
needs: build-image
70+
if: github.event_name == 'push'
71+
steps:
72+
- uses: actions/checkout@v4
73+
- uses: docker/setup-buildx-action@v3
74+
- uses: docker/login-action@v3
75+
with:
76+
registry: ghcr.io
77+
username: ${{ github.actor }}
78+
password: ${{ secrets.GITHUB_TOKEN }}
79+
- name: Docker meta
80+
id: meta
81+
uses: docker/metadata-action@v5
82+
with:
83+
images: ${{ env.IMAGE }}
84+
tags: |
85+
type=raw,latest
86+
type=sha,format=long
87+
- name: Download digests
88+
uses: actions/download-artifact@v4
89+
with:
90+
path: /tmp/digests
91+
pattern: digests-*
92+
merge-multiple: true
93+
- run: ls /tmp/digests
94+
- name: Create manifest list and push
95+
working-directory: /tmp/digests
96+
run: |
97+
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
98+
$(printf '${{ env.IMAGE }}@sha256:%s ' *)
99+
- name: Inspect image to verify
100+
run: |
101+
docker buildx imagetools inspect ${{ env.IMAGE }}:${{ steps.meta.outputs.version }}

.github/workflows/tests.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@ on:
1414
jobs:
1515
notebook-tests:
1616
strategy:
17+
fail-fast: false
1718
matrix:
1819
es_stack:
19-
- 8.13.4
20-
- 8.14.0
21-
- 8.15.0-SNAPSHOT
20+
- 8.16.1
21+
- 8.17.0
22+
- 8.18.0-SNAPSHOT
2223
runs-on: ubuntu-latest
2324
services:
2425
elasticsearch:

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ The [`notebooks`](notebooks/README.md) folder contains a range of executable Pyt
2929
- [`question-answering.ipynb`](./notebooks/generative-ai/question-answering.ipynb)
3030
- [`chatbot.ipynb`](./notebooks/generative-ai/chatbot.ipynb)
3131

32+
### Playground RAG Notebooks
33+
34+
Try out Playground in Kibana with the following notebooks:
35+
36+
- [`OpenAI Example`](./notebooks/playground-examples/openai-elasticsearch-client.ipynb)
37+
- [`Anthropic Claude 3 Example`](./notebooks/playground-examples/bedrock-anthropic-elasticsearch-client.ipynb)
38+
3239
### LangChain
3340

3441
- [`question-answering.ipynb`](./notebooks/generative-ai/question-answering.ipynb)
@@ -55,6 +62,14 @@ The [`notebooks`](notebooks/README.md) folder contains a range of executable Pyt
5562
- [`04-multilingual.ipynb`](./notebooks/search/04-multilingual.ipynb)
5663
- [`05-query-rules.ipynb`](./notebooks/search/05-query-rules.ipynb)
5764
- [`06-synonyms-api.ipynb`](./notebooks/search/06-synonyms-api.ipynb)
65+
- [`07-inference.ipynb`](./notebooks/search/07-inference.ipynb)
66+
- [`08-learning-to-rank.ipynb`](./notebooks/search/08-learning-to-rank.ipynb)
67+
- [`09-semantic-text.ipynb`](./notebooks/search/09-semantic-text.ipynb)
68+
69+
#### Semantic reranking
70+
71+
- [`10-semantic-reranking-retriever-cohere.ipynb`](./notebooks/search/10-semantic-reranking-retriever-cohere.ipynb)
72+
- [`11-semantic-reranking-hugging-face.ipynb`](./notebooks/search/11-semantic-reranking-hugging-face.ipynb)
5873

5974
### Integrations
6075

bin/find-notebooks-to-test.sh

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ EXEMPT_NOTEBOOKS=(
55
"notebooks/esql/esql-getting-started.ipynb"
66
"notebooks/search/07-inference.ipynb"
77
"notebooks/search/08-learning-to-rank.ipynb"
8+
"notebooks/search/10-semantic-reranking-retriever-cohere.ipynb"
9+
"notebooks/search/11-semantic-reranking-hugging-face.ipynb"
10+
"notebooks/search/12-semantic-reranking-elastic-rerank.ipynb"
811
"notebooks/images/image-similarity.ipynb"
912
"notebooks/langchain/langchain-vector-store.ipynb"
1013
"notebooks/langchain/self-query-retriever-examples/chatbot-example.ipynb"
@@ -26,15 +29,21 @@ EXEMPT_NOTEBOOKS=(
2629
"notebooks/integrations/llama3/rag-elastic-llama3-elser.ipynb"
2730
"notebooks/integrations/llama3/rag-elastic-llama3.ipynb"
2831
"notebooks/integrations/azure-openai/vector-search-azure-openai-elastic.ipynb"
29-
"notebooks/enterprise-search/app-search-engine-exporter.ipynb"
32+
"notebooks/enterprise-search/app-search-engine-exporter.ipynb",
33+
"notebooks/playground-examples/bedrock-anthropic-elasticsearch-client.ipynb",
34+
"notebooks/playground-examples/openai-elasticsearch-client.ipynb",
35+
"notebooks/integrations/hugging-face/huggingface-integration-millions-of-documents-with-cohere-reranking.ipynb",
36+
"notebooks/integrations/cohere/updated-cohere-elasticsearch-inference-api.ipynb",
37+
"notebooks/integrations/alibabacloud-ai-search/inference-alibabacloud-ai-search.ipynb",
38+
"notebooks/integrations/jinaai/inference-jinaai.ipynb"
3039
)
3140

3241
# Per-version testing exceptions
3342
# use variables named EXEMPT_NOTEBOOKS__{major}_[minor} to list notebooks that
3443
# cannot run on that stack version or older
3544
# Examples:
3645
# EXEMPT_NOTEBOOKS__8 for notebooks that must be skipped on all versions 8.x and older
37-
# EXEMPT_NOTEBOOKS__8_12 for notebooks that must skipped on versions 8.12 and older
46+
# EXEMPT_NOTEBOOKS__8_12 for notebooks that must be skipped on versions 8.12 and older
3847

3948
EXEMPT_NOTEBOOKS__8_12=(
4049
# Add any notebooks that must be skipped on versions 8.12 or older here
@@ -44,6 +53,14 @@ EXEMPT_NOTEBOOKS__8_12=(
4453
"notebooks/langchain/langchain-using-own-model.ipynb"
4554
)
4655

56+
EXEMPT_NOTEBOOKS__8_14=(
57+
# Add any notebooks that must be skipped on versions 8.14 or older here
58+
"notebooks/search/09-semantic-text.ipynb",
59+
# This notebook has the text_expansion deprecation notice for 8.15.
60+
# Only running on 8.15 so includes the deprecation notice and newer so the local output is the same as CI
61+
"notebooks/langchain/langchain-vector-store-using-elser.ipynb",
62+
)
63+
4764
# this function parses a version given as M[.N[.P]] or M[_N[_P]] into a numeric form
4865
function parse_version { echo "$@" | awk -F'[._]' '{ printf("%02d%02d\n", $1, $2); }'; }
4966

docker/README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Running your own Elastic Stack with Docker
2+
3+
If you'd like to start Elastic locally, you can use the provided
4+
[docker-compose-elastic.yml](docker-compose-elastic.yml) file. This starts
5+
Elasticsearch, Kibana, and APM Server and only requires Docker installed.
6+
7+
Note: If you haven't checked out this repository, all you need is one file:
8+
```bash
9+
wget https://raw.githubusercontent.com/elastic/elasticsearch-labs/refs/heads/main/docker/docker-compose-elastic.yml
10+
```
11+
12+
Use docker compose to run Elastic stack in the background:
13+
14+
```bash
15+
docker compose -f docker-compose-elastic.yml up --force-recreate -d
16+
```
17+
18+
Then, you can view Kibana at http://localhost:5601/app/home#/
19+
20+
If asked for a username and password, use username: elastic and password: elastic.
21+
22+
Clean up when finished, like this:
23+
24+
```bash
25+
docker compose -f docker-compose-elastic.yml down
26+
```

docker/docker-compose-elastic.yml

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
name: elastic-stack
2+
3+
services:
4+
elasticsearch:
5+
image: docker.elastic.co/elasticsearch/elasticsearch:8.17.0
6+
container_name: elasticsearch
7+
ports:
8+
- 9200:9200
9+
environment:
10+
- node.name=elasticsearch
11+
- cluster.name=docker-cluster
12+
- discovery.type=single-node
13+
- ELASTIC_PASSWORD=elastic
14+
- bootstrap.memory_lock=true
15+
- xpack.security.enabled=true
16+
- xpack.security.http.ssl.enabled=false
17+
- xpack.security.transport.ssl.enabled=false
18+
- xpack.license.self_generated.type=trial
19+
- ES_JAVA_OPTS=-Xmx8g
20+
ulimits:
21+
memlock:
22+
soft: -1
23+
hard: -1
24+
healthcheck:
25+
test: ["CMD-SHELL", "curl -s http://localhost:9200/_cluster/health?wait_for_status=yellow&timeout=500ms"]
26+
retries: 300
27+
interval: 1s
28+
29+
elasticsearch_settings:
30+
depends_on:
31+
elasticsearch:
32+
condition: service_healthy
33+
image: docker.elastic.co/elasticsearch/elasticsearch:8.17.0
34+
container_name: elasticsearch_settings
35+
restart: 'no'
36+
command: >
37+
bash -c '
38+
# gen-ai assistants in kibana save state in a way that requires security to be enabled, so we need to create
39+
# a kibana system user before starting it.
40+
echo "Setup the kibana_system password";
41+
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;
42+
'
43+
44+
kibana:
45+
image: docker.elastic.co/kibana/kibana:8.17.0
46+
container_name: kibana
47+
depends_on:
48+
elasticsearch_settings:
49+
condition: service_completed_successfully
50+
ports:
51+
- 5601:5601
52+
environment:
53+
- SERVERNAME=kibana
54+
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
55+
- ELASTICSEARCH_USERNAME=kibana_system
56+
- ELASTICSEARCH_PASSWORD=elastic
57+
# Non-default settings from here:
58+
# https://github.com/elastic/apm-server/blob/main/testing/docker/kibana/kibana.yml
59+
- MONITORING_UI_CONTAINER_ELASTICSEARCH_ENABLED=true
60+
- XPACK_SECURITY_ENCRYPTIONKEY=fhjskloppd678ehkdfdlliverpoolfcr
61+
- XPACK_ENCRYPTEDSAVEDOBJECTS_ENCRYPTIONKEY=fhjskloppd678ehkdfdlliverpoolfcr
62+
- SERVER_PUBLICBASEURL=http://127.0.0.1:5601
63+
healthcheck:
64+
test: ["CMD-SHELL", "curl -s http://localhost:5601/api/status | grep -q 'All services are available'"]
65+
retries: 300
66+
interval: 1s
67+
68+
apm-server:
69+
image: docker.elastic.co/apm/apm-server:8.17.0
70+
container_name: apm-server
71+
depends_on:
72+
elasticsearch:
73+
condition: service_healthy
74+
command: >
75+
apm-server
76+
-E apm-server.kibana.enabled=true
77+
-E apm-server.kibana.host=http://kibana:5601
78+
-E apm-server.kibana.username=elastic
79+
-E apm-server.kibana.password=elastic
80+
-E output.elasticsearch.hosts=["http://elasticsearch:9200"]
81+
-E output.elasticsearch.username=elastic
82+
-E output.elasticsearch.password=elastic
83+
cap_add: ["CHOWN", "DAC_OVERRIDE", "SETGID", "SETUID"]
84+
cap_drop: ["ALL"]
85+
ports:
86+
- 8200:8200
87+
healthcheck:
88+
test: ["CMD-SHELL", "bash -c 'echo -n > /dev/tcp/127.0.0.1/8200'"]
89+
retries: 300
90+
interval: 1s
91+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.venv
2+
*/node_modules

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

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
frontend/build
22
frontend/node_modules
33
api/__pycache__
4-
api/.env
54
.venv
65
venv
7-
.DS_Store
6+
.DS_Store
7+
.env
Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
1-
# app/Dockerfile
2-
3-
FROM node:16-alpine as build-step
1+
FROM node:22-alpine AS build-step
42
WORKDIR /app
5-
ENV PATH /node_modules/.bin:$PATH
3+
ENV PATH=/node_modules/.bin:$PATH
64
COPY frontend ./frontend
7-
RUN rm -rf /app/frontend/node_modules
85
RUN cd frontend && yarn install
96
RUN cd frontend && REACT_APP_API_HOST=/api yarn build
107

11-
FROM python:3.9-slim
8+
FROM python:3.12-slim
129

1310
WORKDIR /app
1411
RUN mkdir -p ./frontend/build
15-
COPY --from=build-step ./app/frontend/build ./frontend/build
12+
COPY --from=build-step ./app/frontend/build ./frontend/build
1613
RUN mkdir ./api
1714
RUN mkdir ./data
1815

@@ -24,12 +21,26 @@ RUN apt-get update && apt-get install -y \
2421
&& rm -rf /var/lib/apt/lists/*
2522

2623

27-
COPY api ./api
28-
COPY data ./data
2924
COPY requirements.txt ./requirements.txt
3025
RUN pip3 install -r ./requirements.txt
31-
ENV FLASK_ENV production
26+
COPY api ./api
27+
COPY data ./data
3228

3329
EXPOSE 4000
34-
WORKDIR /app/api
35-
CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0", "--port=4000" ]
30+
31+
# Default to disabling instrumentation, can be overridden to false in
32+
# docker invocations to reenable.
33+
ENV OTEL_SDK_DISABLED=true
34+
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"]

0 commit comments

Comments
 (0)