From 6c0eac54842f886027447058a160caaa8636acc1 Mon Sep 17 00:00:00 2001 From: Mo Date: Thu, 14 Nov 2024 12:45:05 +0100 Subject: [PATCH 01/21] add build push docker image --- .github/workflows/publish.yml | 67 ++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index e28da570..bbcb3551 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -6,7 +6,7 @@ on: - "v*.*.*" # Triggers when a tag like 'v3.2.0' is pushed jobs: - build-and-publish: + build-and-publish-pypi: name: Build and Publish Packages runs-on: ubuntu-latest @@ -58,3 +58,68 @@ jobs: # Publish to PyPI twine upload dist/* + build-and-push-images: + name: Build and Push Docker Images + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3.3.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata for Elasticsearch image + id: meta-es + uses: docker/metadata-action@v5.5.1 + with: + images: ghcr.io/stac-utils/stac-fastapi-es + tags: | + type=raw,value=latest + type=ref,event=tag + + - name: Build and push Elasticsearch Docker image + uses: docker/build-push-action@v6.9.0 + with: + context: . + file: dockerfiles/Dockerfile.deploy.es + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.meta-es.outputs.tags }} + labels: ${{ steps.meta-es.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Extract metadata for OpenSearch image + id: meta-os + uses: docker/metadata-action@v5.5.1 + with: + images: ghcr.io/stac-utils/stac-fastapi-os + tags: | + type=raw,value=latest + type=ref,event=tag + + - name: Build and push OpenSearch Docker image + uses: docker/build-push-action@v6.9.0 + with: + context: . + file: dockerfiles/Dockerfile.deploy.os + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.meta-os.outputs.tags }} + labels: ${{ steps.meta-os.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max \ No newline at end of file From b19aec9362beb319ba8b5a222f189884d5076fae Mon Sep 17 00:00:00 2001 From: Mo Date: Thu, 14 Nov 2024 13:00:43 +0100 Subject: [PATCH 02/21] bump version --- CHANGELOG.md | 6 ++++++ stac_fastapi/core/stac_fastapi/core/version.py | 2 +- stac_fastapi/elasticsearch/setup.py | 2 +- .../elasticsearch/stac_fastapi/elasticsearch/version.py | 2 +- stac_fastapi/opensearch/setup.py | 2 +- stac_fastapi/opensearch/stac_fastapi/opensearch/version.py | 2 +- 6 files changed, 11 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c3994220..1901a725 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +## [v3.2.1] - 2024-11-14 + +### Added + +- Added Docker image publishing to GitHub Container Registry in publish.yml [#311](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/311) + ## [v3.2.0] - 2024-10-09 ### Added diff --git a/stac_fastapi/core/stac_fastapi/core/version.py b/stac_fastapi/core/stac_fastapi/core/version.py index fad2b4e4..59d4d1a3 100644 --- a/stac_fastapi/core/stac_fastapi/core/version.py +++ b/stac_fastapi/core/stac_fastapi/core/version.py @@ -1,2 +1,2 @@ """library version.""" -__version__ = "3.2.0" +__version__ = "3.2.1" diff --git a/stac_fastapi/elasticsearch/setup.py b/stac_fastapi/elasticsearch/setup.py index a23cbe7c..9239d4fa 100644 --- a/stac_fastapi/elasticsearch/setup.py +++ b/stac_fastapi/elasticsearch/setup.py @@ -6,7 +6,7 @@ desc = f.read() install_requires = [ - "stac-fastapi.core==3.2.0", + "stac-fastapi.core==3.2.1", "elasticsearch[async]==8.11.0", "elasticsearch-dsl==8.11.0", "uvicorn", diff --git a/stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/version.py b/stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/version.py index fad2b4e4..59d4d1a3 100644 --- a/stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/version.py +++ b/stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/version.py @@ -1,2 +1,2 @@ """library version.""" -__version__ = "3.2.0" +__version__ = "3.2.1" diff --git a/stac_fastapi/opensearch/setup.py b/stac_fastapi/opensearch/setup.py index 2cd43da3..3ea0b9ca 100644 --- a/stac_fastapi/opensearch/setup.py +++ b/stac_fastapi/opensearch/setup.py @@ -6,7 +6,7 @@ desc = f.read() install_requires = [ - "stac-fastapi.core==3.2.0", + "stac-fastapi.core==3.2.1", "opensearch-py==2.4.2", "opensearch-py[async]==2.4.2", "uvicorn", diff --git a/stac_fastapi/opensearch/stac_fastapi/opensearch/version.py b/stac_fastapi/opensearch/stac_fastapi/opensearch/version.py index fad2b4e4..59d4d1a3 100644 --- a/stac_fastapi/opensearch/stac_fastapi/opensearch/version.py +++ b/stac_fastapi/opensearch/stac_fastapi/opensearch/version.py @@ -1,2 +1,2 @@ """library version.""" -__version__ = "3.2.0" +__version__ = "3.2.1" From b24192e6b20d8e416031d8f7287f737b2f1af45e Mon Sep 17 00:00:00 2001 From: Mo Date: Thu, 14 Nov 2024 16:35:04 +0100 Subject: [PATCH 03/21] add test health step in publish, refactored the dockerfiles of es and os --- .github/workflows/publish.yml | 115 +++++++++++++++++++++++++++++----- dockerfiles/Dockerfile.ci.es | 75 ++++++++++++++++++++++ dockerfiles/Dockerfile.ci.os | 75 ++++++++++++++++++++++ dockerfiles/entrypoint-es.sh | 23 +++++++ dockerfiles/entrypoint-os.sh | 23 +++++++ 5 files changed, 295 insertions(+), 16 deletions(-) create mode 100644 dockerfiles/Dockerfile.ci.es create mode 100644 dockerfiles/Dockerfile.ci.os create mode 100644 dockerfiles/entrypoint-es.sh create mode 100644 dockerfiles/entrypoint-os.sh diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index bbcb3551..af012dc5 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -58,65 +58,148 @@ jobs: # Publish to PyPI twine upload dist/* + build-and-push-images: name: Build and Push Docker Images runs-on: ubuntu-latest permissions: contents: read packages: write - + steps: - name: Checkout repository uses: actions/checkout@v4 - + - name: Set up QEMU uses: docker/setup-qemu-action@v3 - + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to GitHub Container Registry - uses: docker/login-action@v3.3.0 + uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - + - name: Extract metadata for Elasticsearch image id: meta-es - uses: docker/metadata-action@v5.5.1 + uses: docker/metadata-action@v5 with: - images: ghcr.io/stac-utils/stac-fastapi-es + images: ghcr.io/${{ github.repository_owner }}/stac-fastapi-es tags: | type=raw,value=latest type=ref,event=tag + + - name: Build Elasticsearch image + uses: docker/build-push-action@v6 + with: + context: . + file: dockerfiles/Dockerfile.ci.es + platforms: linux/amd64 + push: false + load: true + tags: stac-fastapi-es:test + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Test Elasticsearch image + run: | + docker run -d --name stac-es \ + -e APP_HOST=0.0.0.0 \ + -e APP_PORT=8080 \ + -e ES_HOST=localhost \ + -e ES_PORT=9200 \ + stac-fastapi-es:test - - name: Build and push Elasticsearch Docker image - uses: docker/build-push-action@v6.9.0 + timeout=120 + while [ $timeout -gt 0 ]; do + if docker inspect stac-es --format='{{.State.Health.Status}}' | grep -q 'healthy'; then + echo "Container is healthy" + break + fi + if [ $timeout -eq 0 ]; then + echo "Health check failed" + docker logs stac-es + docker stop stac-es + docker rm stac-es + exit 1 + fi + sleep 5 + timeout=$((timeout-5)) + done + + docker stop stac-es + docker rm stac-es + + - name: Push Elasticsearch image + uses: docker/build-push-action@v6 with: context: . - file: dockerfiles/Dockerfile.deploy.es + file: dockerfiles/Dockerfile.ci.es platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta-es.outputs.tags }} labels: ${{ steps.meta-es.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max - + - name: Extract metadata for OpenSearch image id: meta-os - uses: docker/metadata-action@v5.5.1 + uses: docker/metadata-action@v5 with: - images: ghcr.io/stac-utils/stac-fastapi-os + images: ghcr.io/${{ github.repository_owner }}/stac-fastapi-os tags: | type=raw,value=latest type=ref,event=tag + + - name: Build OpenSearch image + uses: docker/build-push-action@v6 + with: + context: . + file: dockerfiles/Dockerfile.ci.os + platforms: linux/amd64 + push: false + load: true + tags: stac-fastapi-os:test + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Test OpenSearch image + run: | + docker run -d --name stac-os \ + -e APP_HOST=0.0.0.0 \ + -e APP_PORT=8080 \ + -e OS_HOST=localhost \ + -e OS_PORT=9200 \ + stac-fastapi-os:test + + timeout=120 + while [ $timeout -gt 0 ]; do + if docker inspect stac-os --format='{{.State.Health.Status}}' | grep -q 'healthy'; then + echo "Container is healthy" + break + fi + if [ $timeout -eq 0 ]; then + echo "Health check failed" + docker logs stac-os + docker stop stac-os + docker rm stac-os + exit 1 + fi + sleep 5 + timeout=$((timeout-5)) + done - - name: Build and push OpenSearch Docker image - uses: docker/build-push-action@v6.9.0 + docker stop stac-os + docker rm stac-os + + - name: Push OpenSearch image + uses: docker/build-push-action@v6 with: context: . - file: dockerfiles/Dockerfile.deploy.os + file: dockerfiles/Dockerfile.ci.os platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta-os.outputs.tags }} diff --git a/dockerfiles/Dockerfile.ci.es b/dockerfiles/Dockerfile.ci.es new file mode 100644 index 00000000..244b89a0 --- /dev/null +++ b/dockerfiles/Dockerfile.ci.es @@ -0,0 +1,75 @@ +FROM debian:bookworm-slim AS base + +ARG STAC_FASTAPI_TITLE +ARG STAC_FASTAPI_DESCRIPTION +ARG STAC_FASTAPI_VERSION +ARG APP_HOST +ARG APP_PORT +ARG RELOAD +ARG ENVIRONMENT +ARG WEB_CONCURRENCY +ARG ES_HOST +ARG ES_PORT +ARG ES_USE_SSL +ARG ES_VERIFY_CERTS +ARG BACKEND + +ENV STAC_FASTAPI_TITLE=${STAC_FASTAPI_TITLE} +ENV STAC_FASTAPI_DESCRIPTION=${STAC_FASTAPI_DESCRIPTION} +ENV STAC_FASTAPI_VERSION=${STAC_FASTAPI_VERSION} +ENV APP_HOST=${APP_HOST} +ENV APP_PORT=${APP_PORT} +ENV RELOAD=${RELOAD} +ENV ENVIRONMENT=${ENVIRONMENT} +ENV WEB_CONCURRENCY=${WEB_CONCURRENCY} +ENV ES_HOST=${ES_HOST} +ENV ES_PORT=${ES_PORT} +ENV ES_USE_SSL=${ES_USE_SSL} +ENV ES_VERIFY_CERTS=${ES_VERIFY_CERTS} +ENV BACKEND=${BACKEND} + +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + gcc \ + curl \ + python3 \ + python3-pip \ + python3-venv \ + && apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# set non-root user +RUN groupadd -g 1000 elasticsearch && \ + useradd -u 1000 -g elasticsearch -s /bin/bash -m elasticsearch + +# elasticsearch binaries and libraries +COPY --from=docker.elastic.co/elasticsearch/elasticsearch:8.11.0 /usr/share/elasticsearch /usr/share/elasticsearch + +# ser ownership +RUN chown -R elasticsearch:elasticsearch /usr/share/elasticsearch + +WORKDIR /app +COPY . /app + +# stac-fastapi-es installation +RUN pip3 install --no-cache-dir --break-system-packages -e ./stac_fastapi/core && \ + pip3 install --no-cache-dir --break-system-packages ./stac_fastapi/elasticsearch[server] + +COPY elasticsearch/config/elasticsearch.yml /usr/share/elasticsearch/config/elasticsearch.yml + +COPY dockerfiles/entrypoint-es.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh + + +ENV ES_JAVA_OPTS="-Xms512m -Xmx1g" \ + PATH="/usr/share/elasticsearch/bin:${PATH}" + + +HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 CMD \ + curl --silent --fail http://${ES_HOST}:${ES_PORT}/_cluster/health || exit 1 && \ + curl --silent --fail http://${APP_HOST}:${APP_PORT}/api.html || exit 1 + +EXPOSE $APP_PORT $ES_PORT + +USER elasticsearch +ENTRYPOINT ["/entrypoint.sh"] diff --git a/dockerfiles/Dockerfile.ci.os b/dockerfiles/Dockerfile.ci.os new file mode 100644 index 00000000..4e89c973 --- /dev/null +++ b/dockerfiles/Dockerfile.ci.os @@ -0,0 +1,75 @@ +FROM debian:bookworm-slim AS base + +ARG STAC_FASTAPI_TITLE +ARG STAC_FASTAPI_DESCRIPTION +ARG STAC_FASTAPI_VERSION +ARG APP_HOST +ARG APP_PORT +ARG RELOAD +ARG ENVIRONMENT +ARG WEB_CONCURRENCY +ARG ES_HOST +ARG ES_PORT +ARG ES_USE_SSL +ARG ES_VERIFY_CERTS +ARG BACKEND +ARG STAC_FASTAPI_RATE_LIMIT + +ENV STAC_FASTAPI_TITLE=${STAC_FASTAPI_TITLE} +ENV STAC_FASTAPI_DESCRIPTION=${STAC_FASTAPI_DESCRIPTION} +ENV STAC_FASTAPI_VERSION=${STAC_FASTAPI_VERSION} +ENV APP_HOST=${APP_HOST} +ENV APP_PORT=${APP_PORT} +ENV RELOAD=${RELOAD} +ENV ENVIRONMENT=${ENVIRONMENT} +ENV WEB_CONCURRENCY=${WEB_CONCURRENCY} +ENV ES_HOST=${ES_HOST} +ENV ES_PORT=${ES_PORT} +ENV ES_USE_SSL=${ES_USE_SSL} +ENV ES_VERIFY_CERTS=${ES_VERIFY_CERTS} +ENV BACKEND=${BACKEND} +ENV STAC_FASTAPI_RATE_LIMIT=${STAC_FASTAPI_RATE_LIMIT} + +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + gcc \ + curl \ + python3 \ + python3-pip \ + python3-venv \ + && apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# set non-root user +RUN groupadd -g 1000 opensearch && \ + useradd -u 1000 -g opensearch -s /bin/bash -m opensearch + +# opensearch binaries and libraries +COPY --from=opensearchproject/opensearch:2.11.1 /usr/share/opensearch /usr/share/opensearch + +# ser ownership +RUN chown -R opensearch:opensearch /usr/share/opensearch + +WORKDIR /app +COPY . /app + +# stac-fastapi-os installation +RUN pip3 install --no-cache-dir --break-system-packages -e ./stac_fastapi/core && \ + pip3 install --no-cache-dir --break-system-packages ./stac_fastapi/opensearch[server] + +COPY opensearch/config/opensearch.yml /usr/share/opensearch/config/opensearch.yml + +COPY dockerfiles/entrypoint-os.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh + +ENV OPENSEARCH_JAVA_OPTS="-Xms512m -Xmx1g" \ + PATH="/usr/share/opensearch/bin:${PATH}" + +HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 CMD \ + curl --silent --fail http://${ES_HOST}:${ES_PORT}/_cluster/health || exit 1 && \ + curl --silent --fail http://${APP_HOST}:${APP_PORT}/api.html || exit 1 + +EXPOSE $APP_PORT $ES_PORT + +USER opensearch +ENTRYPOINT ["/entrypoint.sh"] diff --git a/dockerfiles/entrypoint-es.sh b/dockerfiles/entrypoint-es.sh new file mode 100644 index 00000000..17e0df4f --- /dev/null +++ b/dockerfiles/entrypoint-es.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +function validate_elasticsearch { + health=$(curl -s -o /dev/null -w '%{http_code}' "http://${ES_HOST}:${ES_PORT}/_cluster/health") + if [ "$health" -eq 200 ]; then + return 0 + else + return 1 + fi +} + +echo "start es" +/usr/share/elasticsearch/bin/elasticsearch & + +echo "wait for es to be ready" +until validate_elasticsearch; do + echo -n "." + sleep 5 +done +echo "Elasticsearch is up" + +echo "start stac-fastapi-es" +exec uvicorn stac_fastapi.elasticsearch.app:app --host "${APP_HOST}" --port "${APP_PORT}" --reload diff --git a/dockerfiles/entrypoint-os.sh b/dockerfiles/entrypoint-os.sh new file mode 100644 index 00000000..2e7cf294 --- /dev/null +++ b/dockerfiles/entrypoint-os.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +function validate_opensearch { + health=$(curl -s -o /dev/null -w '%{http_code}' "http://${ES_HOST}:${ES_PORT}/_cluster/health") + if [ "$health" -eq 200 ]; then + return 0 + else + return 1 + fi +} + +echo "start opensearch" +/usr/share/opensearch/bin/opensearch & + +echo "wait for opensearch to be ready" +until validate_opensearch; do + echo -n "." + sleep 5 +done +echo "opensearch is up." + +echo "start stac-fastapi-os" +exec uvicorn stac_fastapi.opensearch.app:app --host "${APP_HOST}" --port "${APP_PORT}" --reload From 710b8f4af94d7da3fedb87e4eea7ba510e114c34 Mon Sep 17 00:00:00 2001 From: Mo Date: Thu, 14 Nov 2024 17:23:48 +0100 Subject: [PATCH 04/21] furnished readme and changelog --- CHANGELOG.md | 5 ++- README.md | 96 ++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 82 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1901a725..5990b775 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,8 +10,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [v3.2.1] - 2024-11-14 ### Added +- Added `dockerfiles/Dockerfile.ci.os` and `dockerfiles/Dockerfile.ci.es`, along with their respective entrypoints [#311](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/311) -- Added Docker image publishing to GitHub Container Registry in publish.yml [#311](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/311) +### Changed +- Updated the `publish.yml` workflow to include Docker image publishing to GitHub Container Registry [#311](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/311) +- Improved the README with detailed descriptions of the new Docker images, providing guidance for images. [#311](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/311) ## [v3.2.0] - 2024-10-09 diff --git a/README.md b/README.md index 6ec94b72..74d37e40 100644 --- a/README.md +++ b/README.md @@ -33,38 +33,98 @@ - We are always welcoming contributions. For the development notes: [Contributing](CONTRIBUTING.md) -### To install from PyPI: +### Installing STAC-FastAPI from PyPI -```shell +To install STAC-FastAPI with Elasticsearch or OpenSearch backend support, run the following command: + +For Elasticsearch: +```bash pip install stac_fastapi.elasticsearch ``` -or -``` + +For OpenSearch: +```bash pip install stac_fastapi.opensearch ``` -## Build Elasticsearch API backend +## Running STAC-FastAPI Elasticsearch or OpenSearch API on `localhost:8080` -```shell -docker-compose up elasticsearch -docker-compose build app-elasticsearch +Before starting, [Docker](https://docs.docker.com/get-started/) or [Podman](https://podman.io/docs) has to be installed and running on your machine. + +### Step 1: Configure the `.env` File + +You need to provide a `.env` file to configure the environment variables. Here's a list of variables you can configure: + +- `STAC_FASTAPI_TITLE`: Title of the API shown in the documentation (default: `stac-fastapi-elasticsearch` or `stac-fastapi-opensearch`) +- `STAC_FASTAPI_DESCRIPTION`: Description of the API in the documentation +- `STAC_FASTAPI_VERSION`: API version (default: `2.1`) +- `APP_HOST`: Host to bind the server (default: `0.0.0.0`) +- `APP_PORT`: Port to bind the server (default: `8080`) +- `RELOAD`: Enable auto-reload for development (default: `true`) +- `ENVIRONMENT`: Runtime environment (default: `local`) +- `WEB_CONCURRENCY`: Number of worker processes (default: `10`) +- `ES_HOST`: Elasticsearch or OpenSearch host (default: `localhost`) +- `ES_PORT`: Elasticsearch port (default: `9200` for Elasticsearch, `9202` for OpenSearch) +- `ES_USE_SSL`: Enable SSL for Elasticsearch (default: `false`) +- `ES_VERIFY_CERTS`: Verify SSL certificates (default: `false`) +- `BACKEND`: Backend type (`elasticsearch` or `opensearch`) +- `STAC_FASTAPI_RATE_LIMIT`: API rate limit per client (default: `200/minute`) + +> [!NOTE] +> The variables `ES_HOST`, `ES_PORT`, `ES_USE_SSL`, and `ES_VERIFY_CERTS` apply to both Elasticsearch and OpenSearch, so there is no need to rename the key names to `OS_` even if you're using OpenSearch. + +### Step 2: Running the Backend with Elasticsearch + +To run the backend with Elasticsearch, use the following command: + +```bash +docker run -d \ + --env-file .env \ + -p 9200:9200 \ + -p 8080:8080 \ + ghcr.io/stac-utils/stac-fastapi-es:latest +``` +or +```bash +podman run -d \ + --env-file .env \ + -p 9200:9200 \ + -p 8080:8080 \ + ghcr.io/stac-utils/stac-fastapi-es:latest ``` -## Running Elasticsearch API on localhost:8080 +### Step 3: Running the Backend with OpenSearch -```shell -docker-compose up app-elasticsearch +To run the backend with OpenSearch, use the following command: + +```bash +docker run -d \ + --env-file .env \ + -p 9202:9202 \ + -p 8080:8080 \ + ghcr.io/stac-utils/stac-fastapi-os:latest ``` +or +```bash +podman run -d \ + --env-file .env \ + -p 9202:9202 \ + -p 8080:8080 \ + ghcr.io/stac-utils/stac-fastapi-os:latest +``` +### Step 4: Verifying the Backend is Running -By default, docker-compose uses Elasticsearch 8.x and OpenSearch 2.11.1. -If you wish to use a different version, put the following in a -file named `.env` in the same directory you run docker-compose from: +To check if the container is running, use the following command depending on whether you're using Docker or Podman: -```shell -ELASTICSEARCH_VERSION=7.17.1 -OPENSEARCH_VERSION=2.11.0 +```bash +docker ps ``` -The most recent Elasticsearch 7.x versions should also work. See the [opensearch-py docs](https://github.com/opensearch-project/opensearch-py/blob/main/COMPATIBILITY.md) for compatibility information. +or +```bash +podman ps +``` + +## Interacting with the API To create a new Collection: From 795fa87ce1e088568263ef938959d7b14a2c6370 Mon Sep 17 00:00:00 2001 From: Mo Date: Sat, 16 Nov 2024 21:47:21 +0100 Subject: [PATCH 05/21] added default values and removed the unnecessary env vars from docker files since they already got defualt vals --- .github/workflows/publish.yml | 8 -------- README.md | 25 ++++++++++++------------- dockerfiles/Dockerfile.ci.es | 32 +++++--------------------------- dockerfiles/Dockerfile.ci.os | 34 +++++----------------------------- 4 files changed, 22 insertions(+), 77 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index af012dc5..927bc0f4 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -107,10 +107,6 @@ jobs: - name: Test Elasticsearch image run: | docker run -d --name stac-es \ - -e APP_HOST=0.0.0.0 \ - -e APP_PORT=8080 \ - -e ES_HOST=localhost \ - -e ES_PORT=9200 \ stac-fastapi-es:test timeout=120 @@ -169,10 +165,6 @@ jobs: - name: Test OpenSearch image run: | docker run -d --name stac-os \ - -e APP_HOST=0.0.0.0 \ - -e APP_PORT=8080 \ - -e OS_HOST=localhost \ - -e OS_PORT=9200 \ stac-fastapi-os:test timeout=120 diff --git a/README.md b/README.md index 74d37e40..e1217528 100644 --- a/README.md +++ b/README.md @@ -51,35 +51,33 @@ pip install stac_fastapi.opensearch Before starting, [Docker](https://docs.docker.com/get-started/) or [Podman](https://podman.io/docs) has to be installed and running on your machine. -### Step 1: Configure the `.env` File +### Step 1: Configure the `.env` File (Optional) -You need to provide a `.env` file to configure the environment variables. Here's a list of variables you can configure: +If you need to modify the default configuration, provide a `.env` file with your environment variables. Here's a list of configurable variables. If you're comfortable with the defaults, you can run the Docker container without any environment configuration. - `STAC_FASTAPI_TITLE`: Title of the API shown in the documentation (default: `stac-fastapi-elasticsearch` or `stac-fastapi-opensearch`) - `STAC_FASTAPI_DESCRIPTION`: Description of the API in the documentation - `STAC_FASTAPI_VERSION`: API version (default: `2.1`) - `APP_HOST`: Host to bind the server (default: `0.0.0.0`) - `APP_PORT`: Port to bind the server (default: `8080`) -- `RELOAD`: Enable auto-reload for development (default: `true`) - `ENVIRONMENT`: Runtime environment (default: `local`) -- `WEB_CONCURRENCY`: Number of worker processes (default: `10`) +- `WEB_CONCURRENCY`: Number of worker processes if more workers are needed (default: `10`) +- `RELOAD`: Enable auto-reload for development (default: `true`) - `ES_HOST`: Elasticsearch or OpenSearch host (default: `localhost`) - `ES_PORT`: Elasticsearch port (default: `9200` for Elasticsearch, `9202` for OpenSearch) - `ES_USE_SSL`: Enable SSL for Elasticsearch (default: `false`) - `ES_VERIFY_CERTS`: Verify SSL certificates (default: `false`) -- `BACKEND`: Backend type (`elasticsearch` or `opensearch`) - `STAC_FASTAPI_RATE_LIMIT`: API rate limit per client (default: `200/minute`) > [!NOTE] -> The variables `ES_HOST`, `ES_PORT`, `ES_USE_SSL`, and `ES_VERIFY_CERTS` apply to both Elasticsearch and OpenSearch, so there is no need to rename the key names to `OS_` even if you're using OpenSearch. +> The variables `ES_HOST`, `ES_PORT`, `ES_USE_SSL`, and `ES_VERIFY_CERTS` apply to both Elasticsearch and OpenSearch, so there is no need to rename the key names to `OS_` even if you're using OpenSearch. -### Step 2: Running the Backend with Elasticsearch +### Step 2.1: Running the Backend with Elasticsearch To run the backend with Elasticsearch, use the following command: ```bash docker run -d \ - --env-file .env \ -p 9200:9200 \ -p 8080:8080 \ ghcr.io/stac-utils/stac-fastapi-es:latest @@ -87,19 +85,17 @@ docker run -d \ or ```bash podman run -d \ - --env-file .env \ -p 9200:9200 \ -p 8080:8080 \ ghcr.io/stac-utils/stac-fastapi-es:latest ``` -### Step 3: Running the Backend with OpenSearch +### Step 2.2: Running the Backend with OpenSearch To run the backend with OpenSearch, use the following command: ```bash docker run -d \ - --env-file .env \ -p 9202:9202 \ -p 8080:8080 \ ghcr.io/stac-utils/stac-fastapi-os:latest @@ -107,12 +103,15 @@ docker run -d \ or ```bash podman run -d \ - --env-file .env \ -p 9202:9202 \ -p 8080:8080 \ ghcr.io/stac-utils/stac-fastapi-os:latest ``` -### Step 4: Verifying the Backend is Running + +> [!TIP] +> If you need to mount a volume, use the [`-v`](https://docs.docker.com/engine/storage/volumes/#choose-the--v-or---mount-flag) flag. To specify an environment file, use the [`--env-file`](https://docs.docker.com/reference/cli/docker/container/run/#env) flag. + +### Step 3: Verifying the Backend is Running To check if the container is running, use the following command depending on whether you're using Docker or Podman: diff --git a/dockerfiles/Dockerfile.ci.es b/dockerfiles/Dockerfile.ci.es index 244b89a0..377740e6 100644 --- a/dockerfiles/Dockerfile.ci.es +++ b/dockerfiles/Dockerfile.ci.es @@ -1,32 +1,10 @@ FROM debian:bookworm-slim AS base -ARG STAC_FASTAPI_TITLE -ARG STAC_FASTAPI_DESCRIPTION -ARG STAC_FASTAPI_VERSION -ARG APP_HOST -ARG APP_PORT -ARG RELOAD -ARG ENVIRONMENT -ARG WEB_CONCURRENCY -ARG ES_HOST -ARG ES_PORT -ARG ES_USE_SSL -ARG ES_VERIFY_CERTS -ARG BACKEND - -ENV STAC_FASTAPI_TITLE=${STAC_FASTAPI_TITLE} -ENV STAC_FASTAPI_DESCRIPTION=${STAC_FASTAPI_DESCRIPTION} -ENV STAC_FASTAPI_VERSION=${STAC_FASTAPI_VERSION} -ENV APP_HOST=${APP_HOST} -ENV APP_PORT=${APP_PORT} -ENV RELOAD=${RELOAD} -ENV ENVIRONMENT=${ENVIRONMENT} -ENV WEB_CONCURRENCY=${WEB_CONCURRENCY} -ENV ES_HOST=${ES_HOST} -ENV ES_PORT=${ES_PORT} -ENV ES_USE_SSL=${ES_USE_SSL} -ENV ES_VERIFY_CERTS=${ES_VERIFY_CERTS} -ENV BACKEND=${BACKEND} +ENV ENVIRONMENT="local" +ENV WEB_CONCURRENCY=10 +ENV ES_USE_SSL=false +ENV ES_VERIFY_CERTS=false +ENV STAC_FASTAPI_RATE_LIMIT="200/minute" RUN apt-get update && \ apt-get install -y --no-install-recommends \ diff --git a/dockerfiles/Dockerfile.ci.os b/dockerfiles/Dockerfile.ci.os index 4e89c973..bb1c984c 100644 --- a/dockerfiles/Dockerfile.ci.os +++ b/dockerfiles/Dockerfile.ci.os @@ -1,34 +1,10 @@ FROM debian:bookworm-slim AS base -ARG STAC_FASTAPI_TITLE -ARG STAC_FASTAPI_DESCRIPTION -ARG STAC_FASTAPI_VERSION -ARG APP_HOST -ARG APP_PORT -ARG RELOAD -ARG ENVIRONMENT -ARG WEB_CONCURRENCY -ARG ES_HOST -ARG ES_PORT -ARG ES_USE_SSL -ARG ES_VERIFY_CERTS -ARG BACKEND -ARG STAC_FASTAPI_RATE_LIMIT - -ENV STAC_FASTAPI_TITLE=${STAC_FASTAPI_TITLE} -ENV STAC_FASTAPI_DESCRIPTION=${STAC_FASTAPI_DESCRIPTION} -ENV STAC_FASTAPI_VERSION=${STAC_FASTAPI_VERSION} -ENV APP_HOST=${APP_HOST} -ENV APP_PORT=${APP_PORT} -ENV RELOAD=${RELOAD} -ENV ENVIRONMENT=${ENVIRONMENT} -ENV WEB_CONCURRENCY=${WEB_CONCURRENCY} -ENV ES_HOST=${ES_HOST} -ENV ES_PORT=${ES_PORT} -ENV ES_USE_SSL=${ES_USE_SSL} -ENV ES_VERIFY_CERTS=${ES_VERIFY_CERTS} -ENV BACKEND=${BACKEND} -ENV STAC_FASTAPI_RATE_LIMIT=${STAC_FASTAPI_RATE_LIMIT} +ENV ENVIRONMENT="local" +ENV WEB_CONCURRENCY=10 +ENV ES_USE_SSL=false +ENV ES_VERIFY_CERTS=false +ENV STAC_FASTAPI_RATE_LIMIT="200/minute" RUN apt-get update && \ apt-get install -y --no-install-recommends \ From bd5cddfa2e05de3ee9c78b44874c18a7dd9c3621 Mon Sep 17 00:00:00 2001 From: Mo Date: Sun, 17 Nov 2024 11:06:13 +0100 Subject: [PATCH 06/21] add WEB_CONCURRENCY in entrypoint --- dockerfiles/entrypoint-es.sh | 2 +- dockerfiles/entrypoint-os.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dockerfiles/entrypoint-es.sh b/dockerfiles/entrypoint-es.sh index 17e0df4f..5954c5b9 100644 --- a/dockerfiles/entrypoint-es.sh +++ b/dockerfiles/entrypoint-es.sh @@ -1,5 +1,5 @@ #!/bin/bash - +export WEB_CONCURRENCY="${WEB_CONCURRENCY:-10}" function validate_elasticsearch { health=$(curl -s -o /dev/null -w '%{http_code}' "http://${ES_HOST}:${ES_PORT}/_cluster/health") if [ "$health" -eq 200 ]; then diff --git a/dockerfiles/entrypoint-os.sh b/dockerfiles/entrypoint-os.sh index 2e7cf294..bba562d4 100644 --- a/dockerfiles/entrypoint-os.sh +++ b/dockerfiles/entrypoint-os.sh @@ -1,5 +1,5 @@ #!/bin/bash - +export WEB_CONCURRENCY="${WEB_CONCURRENCY:-10}" function validate_opensearch { health=$(curl -s -o /dev/null -w '%{http_code}' "http://${ES_HOST}:${ES_PORT}/_cluster/health") if [ "$health" -eq 200 ]; then From c97d6f074eab5775c24da3333ca51baba107f060 Mon Sep 17 00:00:00 2001 From: Mo Date: Sun, 17 Nov 2024 12:22:59 +0100 Subject: [PATCH 07/21] add RUN_LOCAL_OS and RUN_LOCAL_ES option to configure backend in container and updated readme --- README.md | 131 ++++++++++++++++++++++------------- dockerfiles/Dockerfile.ci.es | 4 +- dockerfiles/Dockerfile.ci.os | 4 +- dockerfiles/entrypoint-es.sh | 25 ++++--- dockerfiles/entrypoint-os.sh | 24 ++++--- 5 files changed, 117 insertions(+), 71 deletions(-) diff --git a/README.md b/README.md index e1217528..06954756 100644 --- a/README.md +++ b/README.md @@ -47,71 +47,104 @@ For OpenSearch: pip install stac_fastapi.opensearch ``` -## Running STAC-FastAPI Elasticsearch or OpenSearch API on `localhost:8080` +## Running STAC-FastAPI Elasticsearch or OpenSearch API Before starting, [Docker](https://docs.docker.com/get-started/) or [Podman](https://podman.io/docs) has to be installed and running on your machine. -### Step 1: Configure the `.env` File (Optional) +### Step 1: Configure the `.env` File -If you need to modify the default configuration, provide a `.env` file with your environment variables. Here's a list of configurable variables. If you're comfortable with the defaults, you can run the Docker container without any environment configuration. +The `.env` file lets you customize the runtime configuration. If you plan to connect to an external Elasticsearch or OpenSearch instance, set the `ES_HOST` and `ES_PORT` variables to point to your external server. -- `STAC_FASTAPI_TITLE`: Title of the API shown in the documentation (default: `stac-fastapi-elasticsearch` or `stac-fastapi-opensearch`) -- `STAC_FASTAPI_DESCRIPTION`: Description of the API in the documentation -- `STAC_FASTAPI_VERSION`: API version (default: `2.1`) -- `APP_HOST`: Host to bind the server (default: `0.0.0.0`) -- `APP_PORT`: Port to bind the server (default: `8080`) -- `ENVIRONMENT`: Runtime environment (default: `local`) -- `WEB_CONCURRENCY`: Number of worker processes if more workers are needed (default: `10`) -- `RELOAD`: Enable auto-reload for development (default: `true`) -- `ES_HOST`: Elasticsearch or OpenSearch host (default: `localhost`) -- `ES_PORT`: Elasticsearch port (default: `9200` for Elasticsearch, `9202` for OpenSearch) -- `ES_USE_SSL`: Enable SSL for Elasticsearch (default: `false`) -- `ES_VERIFY_CERTS`: Verify SSL certificates (default: `false`) -- `STAC_FASTAPI_RATE_LIMIT`: API rate limit per client (default: `200/minute`) +Alternatively, if you want to run Elasticsearch or OpenSearch **within the same container** as the STAC-FastAPI, enable the respective environment variable in the `.env` file: -> [!NOTE] -> The variables `ES_HOST`, `ES_PORT`, `ES_USE_SSL`, and `ES_VERIFY_CERTS` apply to both Elasticsearch and OpenSearch, so there is no need to rename the key names to `OS_` even if you're using OpenSearch. +- **`RUN_LOCAL_ES`**: Set to `1` to run Elasticsearch locally within the container (default: `0`). Use this with the `stac-fastapi-es` image. +- **`RUN_LOCAL_OS`**: Set to `1` to run OpenSearch locally within the container (default: `0`). Use this with the `stac-fastapi-os` image. -### Step 2.1: Running the Backend with Elasticsearch +> [!IMPORTANT] +> The variables `RUN_LOCAL_ES` and `RUN_LOCAL_OS` correspond to **different Docker images**: +> - Use `RUN_LOCAL_ES` with the `ghcr.io/stac-utils/stac-fastapi-es` image. +> - Use `RUN_LOCAL_OS` with the `ghcr.io/stac-utils/stac-fastapi-os` image. -To run the backend with Elasticsearch, use the following command: -```bash -docker run -d \ - -p 9200:9200 \ - -p 8080:8080 \ - ghcr.io/stac-utils/stac-fastapi-es:latest -``` -or -```bash -podman run -d \ - -p 9200:9200 \ - -p 8080:8080 \ - ghcr.io/stac-utils/stac-fastapi-es:latest -``` +Here are the key variables to configure: -### Step 2.2: Running the Backend with OpenSearch +| Variable | Description | Default | Required | +|------------------------------|--------------------------------------------------------------------------------------|--------------------------|---------------------------------------------------------------------------------------------| +| `RUN_LOCAL_ES` | Enable local Elasticsearch in the container. | `0` | Optional (set to `1` to run local Elasticsearch) | +| `RUN_LOCAL_OS` | Enable local OpenSearch in the container. | `0` | Optional (set to `1` to run local OpenSearch) | +| `ES_HOST` | Hostname for external Elasticsearch/OpenSearch. | `localhost` | **Required if `RUN_LOCAL_ES=0` or `RUN_LOCAL_OS=0`** | +| `ES_PORT` | Port for Elasticsearch/OpenSearch. | `9200` (ES) / `9202` (OS)| **Required if `RUN_LOCAL_ES=0` or `RUN_LOCAL_OS=0`** | +| `ES_USE_SSL` | Use SSL for connecting to Elasticsearch/OpenSearch. | `false` | Optional | +| `ES_VERIFY_CERTS` | Verify SSL certificates when connecting. | `false` | Optional | +| `STAC_FASTAPI_TITLE` | Title of the API in the documentation. | `stac-fastapi-elasticsearch` or `stac-fastapi-opensearch` | Optional | +| `STAC_FASTAPI_DESCRIPTION` | Description of the API in the documentation. | N/A | Optional | +| `STAC_FASTAPI_VERSION` | API version. | `2.1` | Optional | +| `APP_HOST` | Server bind address. | `0.0.0.0` | Optional | +| `APP_PORT` | Server port. | `8080` | Optional | +| `ENVIRONMENT` | Runtime environment. | `local` | Optional | +| `WEB_CONCURRENCY` | Number of worker processes. | `10` | Optional | +| `RELOAD` | Enable auto-reload for development. | `true` | Optional | +| `STAC_FASTAPI_RATE_LIMIT` | API rate limit per client. | `200/minute` | Optional | -To run the backend with OpenSearch, use the following command: -```bash -docker run -d \ - -p 9202:9202 \ - -p 8080:8080 \ - ghcr.io/stac-utils/stac-fastapi-os:latest -``` -or -```bash -podman run -d \ - -p 9202:9202 \ - -p 8080:8080 \ - ghcr.io/stac-utils/stac-fastapi-os:latest -``` +> [!NOTE] +> The variables `ES_HOST`, `ES_PORT`, `ES_USE_SSL`, and `ES_VERIFY_CERTS` apply to both Elasticsearch and OpenSearch, so there is no need to rename the key names to `OS_` even if you're using OpenSearch. + + +### Step 2: Running the Backend + +Depending on your setup, follow one of the options below: + +#### **Option A: Connect to External Elasticsearch/OpenSearch** + +1. Update the `.env` file to include the `ES_HOST` and `ES_PORT` values of your external ES/OS instance. (Based on the SSL certification you might need to consider changing `ES_USE_SSL` and `ES_VERIFY_CERTS`) +2. Run the container with the appropriate image: + - For Elasticsearch: + ```bash + docker run -d \ + -p 8080:8080 \ + --env-file .env \ + ghcr.io/stac-utils/stac-fastapi-es:latest + ``` + - For OpenSearch: + ```bash + docker run -d \ + -p 8080:8080 \ + --env-file .env \ + ghcr.io/stac-utils/stac-fastapi-os:latest + ``` + +#### **Option B: Run Elasticsearch/OpenSearch Locally in the Same Container** + +If you'd like to run Elasticsearch or OpenSearch in the same container as the API: + +1. In the `.env` file, enable the variable corresponding to your backend choice: + - Set `RUN_LOCAL_ES=1` to use Elasticsearch. + - Set `RUN_LOCAL_OS=1` to use OpenSearch. + +2. Start the container using the appropriate image: + + - For **Elasticsearch**: + ```bash + docker run -d \ + -p 9200:9200 \ + -p 8080:8080 \ + -e RUN_LOCAL_ES=1 \ + ghcr.io/stac-utils/stac-fastapi-es:latest + ``` + - For **OpenSearch**: + ```bash + docker run -d \ + -p 9202:9202 \ + -p 8080:8080 \ + -e RUN_LOCAL_OS=1 \ + ghcr.io/stac-utils/stac-fastapi-os:latest + ``` > [!TIP] > If you need to mount a volume, use the [`-v`](https://docs.docker.com/engine/storage/volumes/#choose-the--v-or---mount-flag) flag. To specify an environment file, use the [`--env-file`](https://docs.docker.com/reference/cli/docker/container/run/#env) flag. -### Step 3: Verifying the Backend is Running +### Step 3: Verifying the STAC-FastAPI ELasticSearch or OpenSearch is Running To check if the container is running, use the following command depending on whether you're using Docker or Podman: diff --git a/dockerfiles/Dockerfile.ci.es b/dockerfiles/Dockerfile.ci.es index 377740e6..f5512fe6 100644 --- a/dockerfiles/Dockerfile.ci.es +++ b/dockerfiles/Dockerfile.ci.es @@ -5,6 +5,7 @@ ENV WEB_CONCURRENCY=10 ENV ES_USE_SSL=false ENV ES_VERIFY_CERTS=false ENV STAC_FASTAPI_RATE_LIMIT="200/minute" +ENV RUN_LOCAL_ES=0 RUN apt-get update && \ apt-get install -y --no-install-recommends \ @@ -44,10 +45,9 @@ ENV ES_JAVA_OPTS="-Xms512m -Xmx1g" \ HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 CMD \ - curl --silent --fail http://${ES_HOST}:${ES_PORT}/_cluster/health || exit 1 && \ curl --silent --fail http://${APP_HOST}:${APP_PORT}/api.html || exit 1 -EXPOSE $APP_PORT $ES_PORT +EXPOSE $APP_PORT USER elasticsearch ENTRYPOINT ["/entrypoint.sh"] diff --git a/dockerfiles/Dockerfile.ci.os b/dockerfiles/Dockerfile.ci.os index bb1c984c..024a1e06 100644 --- a/dockerfiles/Dockerfile.ci.os +++ b/dockerfiles/Dockerfile.ci.os @@ -5,6 +5,7 @@ ENV WEB_CONCURRENCY=10 ENV ES_USE_SSL=false ENV ES_VERIFY_CERTS=false ENV STAC_FASTAPI_RATE_LIMIT="200/minute" +ENV RUN_LOCAL_OS=0 RUN apt-get update && \ apt-get install -y --no-install-recommends \ @@ -42,10 +43,9 @@ ENV OPENSEARCH_JAVA_OPTS="-Xms512m -Xmx1g" \ PATH="/usr/share/opensearch/bin:${PATH}" HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 CMD \ - curl --silent --fail http://${ES_HOST}:${ES_PORT}/_cluster/health || exit 1 && \ curl --silent --fail http://${APP_HOST}:${APP_PORT}/api.html || exit 1 -EXPOSE $APP_PORT $ES_PORT +EXPOSE $APP_PORT USER opensearch ENTRYPOINT ["/entrypoint.sh"] diff --git a/dockerfiles/entrypoint-es.sh b/dockerfiles/entrypoint-es.sh index 5954c5b9..98fd1f62 100644 --- a/dockerfiles/entrypoint-es.sh +++ b/dockerfiles/entrypoint-es.sh @@ -1,5 +1,4 @@ #!/bin/bash -export WEB_CONCURRENCY="${WEB_CONCURRENCY:-10}" function validate_elasticsearch { health=$(curl -s -o /dev/null -w '%{http_code}' "http://${ES_HOST}:${ES_PORT}/_cluster/health") if [ "$health" -eq 200 ]; then @@ -9,15 +8,21 @@ function validate_elasticsearch { fi } -echo "start es" -/usr/share/elasticsearch/bin/elasticsearch & +if [ "${RUN_LOCAL_ES}" = "1" ]; then + echo "starting elasticsearch" + /usr/share/elasticsearch/bin/elasticsearch & -echo "wait for es to be ready" -until validate_elasticsearch; do - echo -n "." - sleep 5 -done -echo "Elasticsearch is up" + echo "wait for es to be ready" + until validate_elasticsearch; do + echo -n "." + sleep 5 + done + echo "Elasticsearch is up" +fi echo "start stac-fastapi-es" -exec uvicorn stac_fastapi.elasticsearch.app:app --host "${APP_HOST}" --port "${APP_PORT}" --reload +exec uvicorn stac_fastapi.elasticsearch.app:app \ + --host "${APP_HOST}" \ + --port "${APP_PORT}" \ + --workers "${WEB_CONCURRENCY}" \ + --reload \ No newline at end of file diff --git a/dockerfiles/entrypoint-os.sh b/dockerfiles/entrypoint-os.sh index bba562d4..5351aef9 100644 --- a/dockerfiles/entrypoint-os.sh +++ b/dockerfiles/entrypoint-os.sh @@ -1,5 +1,4 @@ #!/bin/bash -export WEB_CONCURRENCY="${WEB_CONCURRENCY:-10}" function validate_opensearch { health=$(curl -s -o /dev/null -w '%{http_code}' "http://${ES_HOST}:${ES_PORT}/_cluster/health") if [ "$health" -eq 200 ]; then @@ -12,12 +11,21 @@ function validate_opensearch { echo "start opensearch" /usr/share/opensearch/bin/opensearch & -echo "wait for opensearch to be ready" -until validate_opensearch; do - echo -n "." - sleep 5 -done -echo "opensearch is up." +if [ "${RUN_LOCAL_OS}" = "1" ]; then + echo "starting opensearch" + /usr/share/opensearch/bin/opensearch & + + echo "wait for os to be ready" + until validate_opensearch; do + echo -n "." + sleep 5 + done + echo "opensearch is up" +fi echo "start stac-fastapi-os" -exec uvicorn stac_fastapi.opensearch.app:app --host "${APP_HOST}" --port "${APP_PORT}" --reload +exec uvicorn stac_fastapi.opensearch.app:app \ + --host "${APP_HOST}" \ + --port "${APP_PORT}" \ + --workers "${WEB_CONCURRENCY}" \ + --reload From 7226fc1acfd22ed7a0f5c39439f014112489726e Mon Sep 17 00:00:00 2001 From: Mo Date: Sun, 17 Nov 2024 12:54:35 +0100 Subject: [PATCH 08/21] better docs --- .github/workflows/publish.yml | 2 + README.md | 167 +++++++++++++++++++--------------- dockerfiles/Dockerfile.ci.es | 2 + dockerfiles/Dockerfile.ci.os | 2 + dockerfiles/entrypoint-es.sh | 2 + dockerfiles/entrypoint-os.sh | 2 + 6 files changed, 105 insertions(+), 72 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 927bc0f4..ac25470b 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -107,6 +107,7 @@ jobs: - name: Test Elasticsearch image run: | docker run -d --name stac-es \ + -e RUN_LOCAL_ES=1 \ stac-fastapi-es:test timeout=120 @@ -165,6 +166,7 @@ jobs: - name: Test OpenSearch image run: | docker run -d --name stac-os \ + -e RUN_LOCAL_OS=1 \ stac-fastapi-os:test timeout=120 diff --git a/README.md b/README.md index 06954756..5f356223 100644 --- a/README.md +++ b/README.md @@ -49,24 +49,112 @@ pip install stac_fastapi.opensearch ## Running STAC-FastAPI Elasticsearch or OpenSearch API -Before starting, [Docker](https://docs.docker.com/get-started/) or [Podman](https://podman.io/docs) has to be installed and running on your machine. +### Prerequisites -### Step 1: Configure the `.env` File +- [**Docker**](https://docs.docker.com/get-started/) or [**Podman**](https://podman.io/docs) installed and running on your machine. -The `.env` file lets you customize the runtime configuration. If you plan to connect to an external Elasticsearch or OpenSearch instance, set the `ES_HOST` and `ES_PORT` variables to point to your external server. +### Step 1: Set Up the Environment Variables +Create a `.env` file to configure your setup. Depending on your preference, you can either connect to an external Elasticsearch/OpenSearch instance or run one locally within the same container. -Alternatively, if you want to run Elasticsearch or OpenSearch **within the same container** as the STAC-FastAPI, enable the respective environment variable in the `.env` file: +#### Option A: Connect to an External Elasticsearch/OpenSearch Instance -- **`RUN_LOCAL_ES`**: Set to `1` to run Elasticsearch locally within the container (default: `0`). Use this with the `stac-fastapi-es` image. -- **`RUN_LOCAL_OS`**: Set to `1` to run OpenSearch locally within the container (default: `0`). Use this with the `stac-fastapi-os` image. +1. Open your `.env` file. +2. Set the following variables to point to your external Elasticsearch or OpenSearch server: + + ```env + ES_HOST=your_external_host + ES_PORT=your_external_port + ES_USE_SSL=false # Set to 'true' if your server uses SSL + ES_VERIFY_CERTS=false # Set to 'true' to verify SSL certificates + ``` + +#### Option B: Run Elasticsearch/OpenSearch Locally + +1. Open your `.env` file. +2. Enable one of the following to run the service locally within the container: + + ```env + # For Elasticsearch + RUN_LOCAL_ES=1 + + # For OpenSearch + RUN_LOCAL_OS=1 + ``` > [!IMPORTANT] > The variables `RUN_LOCAL_ES` and `RUN_LOCAL_OS` correspond to **different Docker images**: > - Use `RUN_LOCAL_ES` with the `ghcr.io/stac-utils/stac-fastapi-es` image. > - Use `RUN_LOCAL_OS` with the `ghcr.io/stac-utils/stac-fastapi-os` image. +### Step 2: Run the STAC-FastAPI Container + +#### Option A: Using an External Instance + +- **For Elasticsearch:** + + ```bash + docker run -d \ + -p 8080:8080 \ + --env-file .env \ + ghcr.io/stac-utils/stac-fastapi-es:latest + ``` + +- **For OpenSearch:** + + ```bash + docker run -d \ + -p 8080:8080 \ + --env-file .env \ + ghcr.io/stac-utils/stac-fastapi-os:latest + ``` + +#### Option B: Running Locally in the Same Container as APP + +- **For Elasticsearch:** + + ```bash + docker run -d \ + -p 8080:8080 \ + -p 9200:9200 \ + --env-file .env \ + ghcr.io/stac-utils/stac-fastapi-es:latest + ``` + +- **For OpenSearch:** + + ```bash + docker run -d \ + -p 8080:8080 \ + -p 9202:9202 \ + --env-file .env \ + ghcr.io/stac-utils/stac-fastapi-os:latest + ``` + +> [!TIP] +> If you need to mount a volume, use the [`-v`](https://docs.docker.com/engine/storage/volumes/#choose-the--v-or---mount-flag) flag. To specify an environment file, use the [`--env-file`](https://docs.docker.com/reference/cli/docker/container/run/#env) flag. + +### Step 3: Verify the Service is Running -Here are the key variables to configure: +Run the following command to check if your container is up and running: + +```bash +docker ps # "podman ps" if you are running via podman +``` + +You should see the STAC-FastAPI container listed. + +## Accessing the API + +Once the container is up and running, access the API at: + +``` +http://localhost:8080 +``` + +## Additional Configuration (Optional) + +You can customize additional settings in your `.env` file: +### Key variables to configure: | Variable | Description | Default | Required | |------------------------------|--------------------------------------------------------------------------------------|--------------------------|---------------------------------------------------------------------------------------------| @@ -91,71 +179,6 @@ Here are the key variables to configure: > The variables `ES_HOST`, `ES_PORT`, `ES_USE_SSL`, and `ES_VERIFY_CERTS` apply to both Elasticsearch and OpenSearch, so there is no need to rename the key names to `OS_` even if you're using OpenSearch. -### Step 2: Running the Backend - -Depending on your setup, follow one of the options below: - -#### **Option A: Connect to External Elasticsearch/OpenSearch** - -1. Update the `.env` file to include the `ES_HOST` and `ES_PORT` values of your external ES/OS instance. (Based on the SSL certification you might need to consider changing `ES_USE_SSL` and `ES_VERIFY_CERTS`) -2. Run the container with the appropriate image: - - For Elasticsearch: - ```bash - docker run -d \ - -p 8080:8080 \ - --env-file .env \ - ghcr.io/stac-utils/stac-fastapi-es:latest - ``` - - For OpenSearch: - ```bash - docker run -d \ - -p 8080:8080 \ - --env-file .env \ - ghcr.io/stac-utils/stac-fastapi-os:latest - ``` - -#### **Option B: Run Elasticsearch/OpenSearch Locally in the Same Container** - -If you'd like to run Elasticsearch or OpenSearch in the same container as the API: - -1. In the `.env` file, enable the variable corresponding to your backend choice: - - Set `RUN_LOCAL_ES=1` to use Elasticsearch. - - Set `RUN_LOCAL_OS=1` to use OpenSearch. - -2. Start the container using the appropriate image: - - - For **Elasticsearch**: - ```bash - docker run -d \ - -p 9200:9200 \ - -p 8080:8080 \ - -e RUN_LOCAL_ES=1 \ - ghcr.io/stac-utils/stac-fastapi-es:latest - ``` - - For **OpenSearch**: - ```bash - docker run -d \ - -p 9202:9202 \ - -p 8080:8080 \ - -e RUN_LOCAL_OS=1 \ - ghcr.io/stac-utils/stac-fastapi-os:latest - ``` - -> [!TIP] -> If you need to mount a volume, use the [`-v`](https://docs.docker.com/engine/storage/volumes/#choose-the--v-or---mount-flag) flag. To specify an environment file, use the [`--env-file`](https://docs.docker.com/reference/cli/docker/container/run/#env) flag. - -### Step 3: Verifying the STAC-FastAPI ELasticSearch or OpenSearch is Running - -To check if the container is running, use the following command depending on whether you're using Docker or Podman: - -```bash -docker ps -``` -or -```bash -podman ps -``` - ## Interacting with the API To create a new Collection: diff --git a/dockerfiles/Dockerfile.ci.es b/dockerfiles/Dockerfile.ci.es index f5512fe6..14ea64d7 100644 --- a/dockerfiles/Dockerfile.ci.es +++ b/dockerfiles/Dockerfile.ci.es @@ -1,6 +1,8 @@ FROM debian:bookworm-slim AS base ENV ENVIRONMENT="local" +ENV APP_HOST="0.0.0.0" +ENV APP_PORT="8080" ENV WEB_CONCURRENCY=10 ENV ES_USE_SSL=false ENV ES_VERIFY_CERTS=false diff --git a/dockerfiles/Dockerfile.ci.os b/dockerfiles/Dockerfile.ci.os index 024a1e06..5928c56b 100644 --- a/dockerfiles/Dockerfile.ci.os +++ b/dockerfiles/Dockerfile.ci.os @@ -1,6 +1,8 @@ FROM debian:bookworm-slim AS base ENV ENVIRONMENT="local" +ENV API_HOST="0.0.0.0" +ENV API_PORT="8080" ENV WEB_CONCURRENCY=10 ENV ES_USE_SSL=false ENV ES_VERIFY_CERTS=false diff --git a/dockerfiles/entrypoint-es.sh b/dockerfiles/entrypoint-es.sh index 98fd1f62..82df427b 100644 --- a/dockerfiles/entrypoint-es.sh +++ b/dockerfiles/entrypoint-es.sh @@ -1,5 +1,7 @@ #!/bin/bash function validate_elasticsearch { + export ES_HOST=${ES_HOST:-localhost} + export ES_PORT=${ES_PORT:-9200} health=$(curl -s -o /dev/null -w '%{http_code}' "http://${ES_HOST}:${ES_PORT}/_cluster/health") if [ "$health" -eq 200 ]; then return 0 diff --git a/dockerfiles/entrypoint-os.sh b/dockerfiles/entrypoint-os.sh index 5351aef9..8746ccb7 100644 --- a/dockerfiles/entrypoint-os.sh +++ b/dockerfiles/entrypoint-os.sh @@ -1,5 +1,7 @@ #!/bin/bash function validate_opensearch { + export ES_HOST=${ES_HOST:-localhost} + export ES_PORT=${ES_PORT:-9202} health=$(curl -s -o /dev/null -w '%{http_code}' "http://${ES_HOST}:${ES_PORT}/_cluster/health") if [ "$health" -eq 200 ]; then return 0 From 0e70af2f08932627dae08622627a8bcaa6553b2a Mon Sep 17 00:00:00 2001 From: Mo Date: Sun, 17 Nov 2024 13:32:55 +0100 Subject: [PATCH 09/21] check logs on produced images --- dockerfiles/Dockerfile.ci.os | 4 ++-- dockerfiles/entrypoint-os.sh | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dockerfiles/Dockerfile.ci.os b/dockerfiles/Dockerfile.ci.os index 5928c56b..4c0502a0 100644 --- a/dockerfiles/Dockerfile.ci.os +++ b/dockerfiles/Dockerfile.ci.os @@ -1,8 +1,8 @@ FROM debian:bookworm-slim AS base ENV ENVIRONMENT="local" -ENV API_HOST="0.0.0.0" -ENV API_PORT="8080" +ENV APP_HOST="0.0.0.0" +ENV APP_PORT="8080" ENV WEB_CONCURRENCY=10 ENV ES_USE_SSL=false ENV ES_VERIFY_CERTS=false diff --git a/dockerfiles/entrypoint-os.sh b/dockerfiles/entrypoint-os.sh index 8746ccb7..9a011d91 100644 --- a/dockerfiles/entrypoint-os.sh +++ b/dockerfiles/entrypoint-os.sh @@ -2,17 +2,17 @@ function validate_opensearch { export ES_HOST=${ES_HOST:-localhost} export ES_PORT=${ES_PORT:-9202} - health=$(curl -s -o /dev/null -w '%{http_code}' "http://${ES_HOST}:${ES_PORT}/_cluster/health") - if [ "$health" -eq 200 ]; then + response=$(curl -s "http://${ES_HOST}:${ES_PORT}/_cluster/health") + http_code=$(curl -s -o /dev/null -w '%{http_code}' "http://${ES_HOST}:${ES_PORT}/_cluster/health") + echo "HTTP Status Code: $http_code" + echo "Cluster Health Response: $response" + if [ "$http_code" -eq 200 ]; then return 0 else return 1 fi } -echo "start opensearch" -/usr/share/opensearch/bin/opensearch & - if [ "${RUN_LOCAL_OS}" = "1" ]; then echo "starting opensearch" /usr/share/opensearch/bin/opensearch & From feb24d2d49eacb9e487eb31640ca5ece3d561c00 Mon Sep 17 00:00:00 2001 From: Mo Date: Sun, 17 Nov 2024 14:11:21 +0100 Subject: [PATCH 10/21] added better logs, and considered all different scenarios --- dockerfiles/entrypoint-es.sh | 120 ++++++++++++++++++++++++++------- dockerfiles/entrypoint-os.sh | 124 ++++++++++++++++++++++++++++------- 2 files changed, 197 insertions(+), 47 deletions(-) diff --git a/dockerfiles/entrypoint-es.sh b/dockerfiles/entrypoint-es.sh index 82df427b..97e08f90 100644 --- a/dockerfiles/entrypoint-es.sh +++ b/dockerfiles/entrypoint-es.sh @@ -1,30 +1,106 @@ #!/bin/bash -function validate_elasticsearch { - export ES_HOST=${ES_HOST:-localhost} - export ES_PORT=${ES_PORT:-9200} - health=$(curl -s -o /dev/null -w '%{http_code}' "http://${ES_HOST}:${ES_PORT}/_cluster/health") - if [ "$health" -eq 200 ]; then - return 0 - else +set -e + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +function print_error() { + echo -e "${RED}ERROR: $1${NC}" >&2 +} + +function print_warning() { + echo -e "${YELLOW}WARNING: $1${NC}" +} + +function print_success() { + echo -e "${GREEN}SUCCESS: $1${NC}" +} + +function print_info() { + echo -e "${BLUE}INFO: $1${NC}" +} + +function validate_elasticsearch() { + local retry_count=0 + local max_retries=5 + local wait_time=5 + + while [ $retry_count -lt $max_retries ]; do + print_info "Checking Elasticsearch connection (Attempt $((retry_count + 1))/$max_retries)..." + + health=$(curl -k -s -o /dev/null -w '%{http_code}' "http://${ES_HOST}:${ES_PORT}/_cluster/health" 2>/dev/null) + + if [ "$health" -eq 200 ]; then + print_success "Successfully connected to Elasticsearch via HTTP" + export ES_USE_SSL=false + return 0 + fi + + print_info "HTTP connection failed, trying HTTPS..." + health=$(curl -s -o /dev/null -w '%{http_code}' "https://${ES_HOST}:${ES_PORT}/_cluster/health" 2>/dev/null) + + if [ "$health" -eq 200 ]; then + print_success "Successfully connected to Elasticsearch via HTTPS" + export ES_USE_SSL=true + return 0 + fi + + retry_count=$((retry_count + 1)) + if [ $retry_count -lt $max_retries ]; then + print_warning "Connection attempt $retry_count failed. Waiting ${wait_time} seconds before retry..." + sleep $wait_time + wait_time=$((wait_time * 2)) + fi + done + + print_error "Failed to connect to Elasticsearch after $max_retries attempts:" + print_error " - http://${ES_HOST}:${ES_PORT}" + print_error " - https://${ES_HOST}:${ES_PORT}" + print_error "Please ensure:" + print_error " - Elasticsearch is running" + print_error " - ES_HOST and ES_PORT are correctly set" + print_error " - Network connectivity is available" + print_error " - SSL/TLS settings are correct if using HTTPS" return 1 - fi } +if [ "${RUN_LOCAL_ES}" = "0" ]; then + if [ -z "${ES_HOST}" ] || [ -z "${ES_PORT}" ]; then + print_error "When RUN_LOCAL_ES=0, you must specify both ES_HOST and ES_PORT" + print_error "Current settings:" + print_error " ES_HOST: ${ES_HOST:-not set}" + print_error " ES_PORT: ${ES_PORT:-not set}" + exit 1 + fi +else + export ES_HOST=${ES_HOST:-localhost} + export ES_PORT=${ES_PORT:-9200} +fi + if [ "${RUN_LOCAL_ES}" = "1" ]; then - echo "starting elasticsearch" - /usr/share/elasticsearch/bin/elasticsearch & - - echo "wait for es to be ready" - until validate_elasticsearch; do - echo -n "." - sleep 5 - done - echo "Elasticsearch is up" + print_info "Starting local Elasticsearch instance" + /usr/share/elasticsearch/bin/elasticsearch & + + print_info "Waiting for Elasticsearch to be ready" + until validate_elasticsearch; do + print_info "Elasticsearch not yet ready. Retrying..." + sleep 5 + done + print_success "Elasticsearch is up and running" +else + print_info "Using external Elasticsearch at ${ES_HOST}:${ES_PORT}" + if ! validate_elasticsearch; then + print_error "Cannot connect to external Elasticsearch. Exiting..." + exit 1 + fi fi -echo "start stac-fastapi-es" +print_info "Starting STAC FastAPI Elasticsearch" exec uvicorn stac_fastapi.elasticsearch.app:app \ - --host "${APP_HOST}" \ - --port "${APP_PORT}" \ - --workers "${WEB_CONCURRENCY}" \ - --reload \ No newline at end of file + --host "${APP_HOST}" \ + --port "${APP_PORT}" \ + --workers "${WEB_CONCURRENCY}" \ + --reload \ No newline at end of file diff --git a/dockerfiles/entrypoint-os.sh b/dockerfiles/entrypoint-os.sh index 9a011d91..abc8fa4f 100644 --- a/dockerfiles/entrypoint-os.sh +++ b/dockerfiles/entrypoint-os.sh @@ -1,33 +1,107 @@ #!/bin/bash -function validate_opensearch { - export ES_HOST=${ES_HOST:-localhost} - export ES_PORT=${ES_PORT:-9202} - response=$(curl -s "http://${ES_HOST}:${ES_PORT}/_cluster/health") - http_code=$(curl -s -o /dev/null -w '%{http_code}' "http://${ES_HOST}:${ES_PORT}/_cluster/health") - echo "HTTP Status Code: $http_code" - echo "Cluster Health Response: $response" - if [ "$http_code" -eq 200 ]; then - return 0 - else +set -e + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +function print_error() { + echo -e "${RED}ERROR: $1${NC}" >&2 +} + +function print_warning() { + echo -e "${YELLOW}WARNING: $1${NC}" +} + +function print_success() { + echo -e "${GREEN}SUCCESS: $1${NC}" +} + +function print_info() { + echo -e "${BLUE}INFO: $1${NC}" +} + +function validate_opensearch() { + local retry_count=0 + local max_retries=5 + local wait_time=5 + + while [ $retry_count -lt $max_retries ]; do + print_info "Checking OpenSearch connection (Attempt $((retry_count + 1))/$max_retries)..." + + health=$(curl -k -s -o /dev/null -w '%{http_code}' "http://${ES_HOST}:${ES_PORT}/_cluster/health" 2>/dev/null) + + if [ "$health" -eq 200 ]; then + print_success "Successfully connected to OpenSearch via HTTP" + export ES_USE_SSL=false + return 0 + fi + + print_info "HTTP connection failed, trying HTTPS..." + health=$(curl -s -o /dev/null -w '%{http_code}' "https://${ES_HOST}:${ES_PORT}/_cluster/health" 2>/dev/null) + + if [ "$health" -eq 200 ]; then + print_success "Successfully connected to OpenSearch via HTTPS" + export ES_USE_SSL=true + return 0 + fi + + retry_count=$((retry_count + 1)) + if [ $retry_count -lt $max_retries ]; then + print_warning "Connection attempt $retry_count failed. Waiting ${wait_time} seconds before retry..." + sleep $wait_time + wait_time=$((wait_time * 2)) + fi + done + + print_error "Failed to connect to OpenSearch after $max_retries attempts:" + print_error " - http://${ES_HOST}:${ES_PORT}" + print_error " - https://${ES_HOST}:${ES_PORT}" + print_error "Please ensure:" + print_error " - OpenSearch is running" + print_error " - ES_HOST and ES_PORT are correctly set" + print_error " - Network connectivity is available" + print_error " - SSL/TLS settings are correct if using HTTPS" return 1 - fi } +if [ "${RUN_LOCAL_OS}" = "0" ]; then + if [ -z "${ES_HOST}" ] || [ -z "${ES_PORT}" ]; then + print_error "When RUN_LOCAL_OS=0, you must specify both ES_HOST and ES_PORT" + print_error "Current settings:" + print_error " ES_HOST: ${ES_HOST:-not set}" + print_error " ES_PORT: ${ES_PORT:-not set}" + exit 1 + fi +else + export ES_HOST=${ES_HOST:-localhost} + export ES_PORT=${ES_PORT:-9202} +fi + if [ "${RUN_LOCAL_OS}" = "1" ]; then - echo "starting opensearch" - /usr/share/opensearch/bin/opensearch & - - echo "wait for os to be ready" - until validate_opensearch; do - echo -n "." - sleep 5 - done - echo "opensearch is up" + print_info "Starting local OpenSearch instance" + /usr/share/opensearch/bin/opensearch & + + print_info "Waiting for OpenSearch to be ready" + sleep 10 # Initial wait for OpenSearch to start + until validate_opensearch; do + print_info "OpenSearch not yet ready. Retrying..." + sleep 5 + done + print_success "OpenSearch is up and running" +else + print_info "Using external OpenSearch at ${ES_HOST}:${ES_PORT}" + if ! validate_opensearch; then + print_error "Cannot connect to external OpenSearch. Exiting..." + exit 1 + fi fi -echo "start stac-fastapi-os" +print_info "Starting STAC FastAPI OpenSearch" exec uvicorn stac_fastapi.opensearch.app:app \ - --host "${APP_HOST}" \ - --port "${APP_PORT}" \ - --workers "${WEB_CONCURRENCY}" \ - --reload + --host "${APP_HOST}" \ + --port "${APP_PORT}" \ + --workers "${WEB_CONCURRENCY}" \ + --reload \ No newline at end of file From e8d6fc404cbff9c40e3ed98a57e72e01eb61ca43 Mon Sep 17 00:00:00 2001 From: Mo Date: Sun, 17 Nov 2024 14:37:22 +0100 Subject: [PATCH 11/21] made README well documented --- README.md | 167 +++++++++++++++++++++++++++++------------------------- 1 file changed, 91 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index 5f356223..8f35e4f4 100644 --- a/README.md +++ b/README.md @@ -32,129 +32,144 @@ - For changes, see the [Changelog](CHANGELOG.md) - We are always welcoming contributions. For the development notes: [Contributing](CONTRIBUTING.md) +## Installation and Running: -### Installing STAC-FastAPI from PyPI +### **Method 1: Install via PyPI and Run with Docker Compose or Podman Compose** -To install STAC-FastAPI with Elasticsearch or OpenSearch backend support, run the following command: +#### **Prerequisites** + +- [**Docker Compose**](https://docs.docker.com/compose/install/) or [**Podman Compose**](https://podman-desktop.io/docs/compose) installed and running on your machine. In all the follwoing steps instead of `docker-compose` you can use `podman-compose` as well. + +#### **Step 1: Install STAC-FastAPI** + +To install STAC-FastAPI with Elasticsearch or OpenSearch backend support, execute the following commands: + +- **For Elasticsearch backend:** + + ```bash + pip install stac_fastapi.elasticsearch + ``` + +- **For OpenSearch backend:** + + ```bash + pip install stac_fastapi.opensearch + ``` + +#### **Step 2: Build the Elasticsearch API Backend** + +Start the Elasticsearch service and build the STAC-FastAPI application image: -For Elasticsearch: ```bash -pip install stac_fastapi.elasticsearch +docker-compose up -d elasticsearch +docker-compose build app-elasticsearch ``` -For OpenSearch: +#### **Step 3: Run the Elasticsearch API on `localhost:8080`** + +Launch the STAC-FastAPI application connected to Elasticsearch: + ```bash -pip install stac_fastapi.opensearch +docker-compose up -d app-elasticsearch ``` -## Running STAC-FastAPI Elasticsearch or OpenSearch API +By default, Docker Compose uses Elasticsearch 8.x and OpenSearch 2.11.1. If you prefer to use different versions, create a file named `.env` in the same directory where you run Docker Compose and include the following lines: + +```env +ELASTICSEARCH_VERSION=7.17.1 +OPENSEARCH_VERSION=2.11.0 +``` -### Prerequisites +Most recent Elasticsearch 7.x versions should also be compatible. For detailed compatibility information, please refer to the [opensearch-py documentation](https://github.com/opensearch-project/opensearch-py/blob/main/COMPATIBILITY.md). -- [**Docker**](https://docs.docker.com/get-started/) or [**Podman**](https://podman.io/docs) installed and running on your machine. +### **Method 2: Install and run only with Docker or podman** -### Step 1: Set Up the Environment Variables -Create a `.env` file to configure your setup. Depending on your preference, you can either connect to an external Elasticsearch/OpenSearch instance or run one locally within the same container. +#### Prerequisites -#### Option A: Connect to an External Elasticsearch/OpenSearch Instance +- [**Docker**](https://docs.docker.com/get-started/) or [**Podman**](https://podman.io/docs) installed and running on your machine. In all the follwoing steps instead of `docker` you can use `podman` as well. -1. Open your `.env` file. -2. Set the following variables to point to your external Elasticsearch or OpenSearch server: +#### **Step 1: Create a `.env` File** - ```env - ES_HOST=your_external_host - ES_PORT=your_external_port - ES_USE_SSL=false # Set to 'true' if your server uses SSL - ES_VERIFY_CERTS=false # Set to 'true' to verify SSL certificates - ``` +Configure your environment variables in a `.env` file. You can choose to connect to an external Elasticsearch/OpenSearch instance or run one locally within the container. -#### Option B: Run Elasticsearch/OpenSearch Locally +- **Option A: Connect to an External Instance** -1. Open your `.env` file. -2. Enable one of the following to run the service locally within the container: + ```env + ES_HOST=your_external_host + ES_PORT=your_external_port + ES_USE_SSL=false # Set to 'true' if SSL is used + ES_VERIFY_CERTS=false # Set to 'true' to verify SSL certificates + ``` - ```env - # For Elasticsearch - RUN_LOCAL_ES=1 +- **Option B: Running Locally Within the Container** - # For OpenSearch - RUN_LOCAL_OS=1 - ``` + - **For Elasticsearch:** + + ```env + RUN_LOCAL_ES=1 + ``` + + - **For OpenSearch:** + + ```env + RUN_LOCAL_OS=1 + ``` > [!IMPORTANT] > The variables `RUN_LOCAL_ES` and `RUN_LOCAL_OS` correspond to **different Docker images**: > - Use `RUN_LOCAL_ES` with the `ghcr.io/stac-utils/stac-fastapi-es` image. > - Use `RUN_LOCAL_OS` with the `ghcr.io/stac-utils/stac-fastapi-os` image. -### Step 2: Run the STAC-FastAPI Container +#### **Step 2: Run the Docker Container** -#### Option A: Using an External Instance +- **For Elasticsearch Backend:** -- **For Elasticsearch:** + - **Connecting to External Instance:** - ```bash - docker run -d \ - -p 8080:8080 \ - --env-file .env \ - ghcr.io/stac-utils/stac-fastapi-es:latest - ``` + ```shell + docker run -d -p 8080:8080 --env-file .env ghcr.io/stac-utils/stac-fastapi-es:latest + ``` -- **For OpenSearch:** + - **Running Locally:** - ```bash - docker run -d \ - -p 8080:8080 \ - --env-file .env \ - ghcr.io/stac-utils/stac-fastapi-os:latest - ``` + ```shell + docker run -d -p 8080:8080 -p 9200:9200 --env-file .env ghcr.io/stac-utils/stac-fastapi-es:latest + ``` -#### Option B: Running Locally in the Same Container as APP +- **For OpenSearch Backend:** -- **For Elasticsearch:** + - **Connecting to External Instance:** - ```bash - docker run -d \ - -p 8080:8080 \ - -p 9200:9200 \ - --env-file .env \ - ghcr.io/stac-utils/stac-fastapi-es:latest - ``` + ```shell + docker run -d -p 8080:8080 --env-file .env ghcr.io/stac-utils/stac-fastapi-os:latest + ``` -- **For OpenSearch:** + - **Running Locally:** - ```bash - docker run -d \ - -p 8080:8080 \ - -p 9202:9202 \ - --env-file .env \ - ghcr.io/stac-utils/stac-fastapi-os:latest - ``` + ```shell + docker run -d -p 8080:8080 -p 9202:9202 --env-file .env ghcr.io/stac-utils/stac-fastapi-os:latest + ``` > [!TIP] > If you need to mount a volume, use the [`-v`](https://docs.docker.com/engine/storage/volumes/#choose-the--v-or---mount-flag) flag. To specify an environment file, use the [`--env-file`](https://docs.docker.com/reference/cli/docker/container/run/#env) flag. -### Step 3: Verify the Service is Running -Run the following command to check if your container is up and running: - -```bash -docker ps # "podman ps" if you are running via podman -``` +#### **Step 3: Verify and Access** -You should see the STAC-FastAPI container listed. +- **Check if the container is running:** -## Accessing the API + ```shell + docker ps # "podman ps" if you are running via podman + ``` -Once the container is up and running, access the API at: +- **Access the API:** -``` -http://localhost:8080 -``` + Visit `http://localhost:8080` in your browser or use it as the base URL for API requests. -## Additional Configuration (Optional) +##### **Configuration reference keys:** You can customize additional settings in your `.env` file: -### Key variables to configure: +###### Key variables to configure: | Variable | Description | Default | Required | |------------------------------|--------------------------------------------------------------------------------------|--------------------------|---------------------------------------------------------------------------------------------| From 15b0d65777a362cf389bf9c8dcac47250f77f818 Mon Sep 17 00:00:00 2001 From: Mo Date: Sun, 17 Nov 2024 16:31:24 +0100 Subject: [PATCH 12/21] added better recognition criteria for es and os --- dockerfiles/entrypoint-es.sh | 34 ++++++++++++++++++++++++---------- dockerfiles/entrypoint-os.sh | 29 ++++++++++++++++++++++------- 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/dockerfiles/entrypoint-es.sh b/dockerfiles/entrypoint-es.sh index 97e08f90..f9e7ddff 100644 --- a/dockerfiles/entrypoint-es.sh +++ b/dockerfiles/entrypoint-es.sh @@ -30,24 +30,38 @@ function validate_elasticsearch() { while [ $retry_count -lt $max_retries ]; do print_info "Checking Elasticsearch connection (Attempt $((retry_count + 1))/$max_retries)..." - - health=$(curl -k -s -o /dev/null -w '%{http_code}' "http://${ES_HOST}:${ES_PORT}/_cluster/health" 2>/dev/null) + + local response_body=$(curl -k -s "http://${ES_HOST}:${ES_PORT}/" 2>/dev/null) + local health=$(curl -k -s -o /dev/null -w '%{http_code}' "http://${ES_HOST}:${ES_PORT}/_cluster/health" 2>/dev/null) if [ "$health" -eq 200 ]; then - print_success "Successfully connected to Elasticsearch via HTTP" - export ES_USE_SSL=false - return 0 + if echo "$response_body" | grep -q '"tagline" *: *"You Know, for Search"'; then + print_success "Successfully connected to Elasticsearch via HTTP" + export ES_USE_SSL=false + return 0 + else + print_error "Connected to a service that is not Elasticsearch" + print_error "Found service response: $response_body" + return 1 + fi fi print_info "HTTP connection failed, trying HTTPS..." + response_body=$(curl -k -s "https://${ES_HOST}:${ES_PORT}/" 2>/dev/null) health=$(curl -s -o /dev/null -w '%{http_code}' "https://${ES_HOST}:${ES_PORT}/_cluster/health" 2>/dev/null) if [ "$health" -eq 200 ]; then - print_success "Successfully connected to Elasticsearch via HTTPS" - export ES_USE_SSL=true - return 0 + if echo "$response_body" | grep -q '"tagline" *: *"You Know, for Search"'; then + print_success "Successfully connected to Elasticsearch via HTTPS" + export ES_USE_SSL=true + return 0 + else + print_error "Connected to a service that is not Elasticsearch" + print_error "Found service response: $response_body" + return 1 + fi fi - + retry_count=$((retry_count + 1)) if [ $retry_count -lt $max_retries ]; then print_warning "Connection attempt $retry_count failed. Waiting ${wait_time} seconds before retry..." @@ -59,7 +73,7 @@ function validate_elasticsearch() { print_error "Failed to connect to Elasticsearch after $max_retries attempts:" print_error " - http://${ES_HOST}:${ES_PORT}" print_error " - https://${ES_HOST}:${ES_PORT}" - print_error "Please ensure:" + print_error " Please ensure:" print_error " - Elasticsearch is running" print_error " - ES_HOST and ES_PORT are correctly set" print_error " - Network connectivity is available" diff --git a/dockerfiles/entrypoint-os.sh b/dockerfiles/entrypoint-os.sh index abc8fa4f..3dafba64 100644 --- a/dockerfiles/entrypoint-os.sh +++ b/dockerfiles/entrypoint-os.sh @@ -31,21 +31,35 @@ function validate_opensearch() { while [ $retry_count -lt $max_retries ]; do print_info "Checking OpenSearch connection (Attempt $((retry_count + 1))/$max_retries)..." - health=$(curl -k -s -o /dev/null -w '%{http_code}' "http://${ES_HOST}:${ES_PORT}/_cluster/health" 2>/dev/null) + local response_body=$(curl -k -s "http://${ES_HOST}:${ES_PORT}/" 2>/dev/null) + local health=$(curl -k -s -o /dev/null -w '%{http_code}' "http://${ES_HOST}:${ES_PORT}/_cluster/health" 2>/dev/null) if [ "$health" -eq 200 ]; then - print_success "Successfully connected to OpenSearch via HTTP" - export ES_USE_SSL=false - return 0 + if echo "$response_body" | grep -q '"distribution" *: *"opensearch"'; then + print_success "Successfully connected to OpenSearch via HTTP" + export ES_USE_SSL=false + return 0 + else + print_error "Connected to a service that is not OpenSearch" + print_error "Found service response: $response_body" + return 1 + fi fi print_info "HTTP connection failed, trying HTTPS..." + response_body=$(curl -k -s "https://${ES_HOST}:${ES_PORT}/" 2>/dev/null) health=$(curl -s -o /dev/null -w '%{http_code}' "https://${ES_HOST}:${ES_PORT}/_cluster/health" 2>/dev/null) if [ "$health" -eq 200 ]; then - print_success "Successfully connected to OpenSearch via HTTPS" - export ES_USE_SSL=true - return 0 + if echo "$response_body" | grep -q '"distribution" *: *"opensearch"'; then + print_success "Successfully connected to OpenSearch via HTTPS" + export ES_USE_SSL=true + return 0 + else + print_error "Connected to a service that is not OpenSearch" + print_error "Found service response: $response_body" + return 1 + fi fi retry_count=$((retry_count + 1)) @@ -64,6 +78,7 @@ function validate_opensearch() { print_error " - ES_HOST and ES_PORT are correctly set" print_error " - Network connectivity is available" print_error " - SSL/TLS settings are correct if using HTTPS" + print_error " - You are not connecting to Elasticsearch or another service" return 1 } From 4826f1918ab0dd40a472e716f37896da35be247f Mon Sep 17 00:00:00 2001 From: Mo Date: Sun, 17 Nov 2024 16:50:28 +0100 Subject: [PATCH 13/21] reflect comment on first method of installation of readme --- README.md | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 8f35e4f4..b394625b 100644 --- a/README.md +++ b/README.md @@ -40,37 +40,53 @@ - [**Docker Compose**](https://docs.docker.com/compose/install/) or [**Podman Compose**](https://podman-desktop.io/docs/compose) installed and running on your machine. In all the follwoing steps instead of `docker-compose` you can use `podman-compose` as well. -#### **Step 1: Install STAC-FastAPI** +This approach is for users who want to install the Python package separately before running the app. -To install STAC-FastAPI with Elasticsearch or OpenSearch backend support, execute the following commands: +##### **Step 1: Install STAC-FastAPI** - **For Elasticsearch backend:** - + ```bash pip install stac_fastapi.elasticsearch ``` - **For OpenSearch backend:** - + ```bash pip install stac_fastapi.opensearch ``` -#### **Step 2: Build the Elasticsearch API Backend** +##### **Step 2: Start Elasticsearch/OpenSearch Backend** -Start the Elasticsearch service and build the STAC-FastAPI application image: +Launch Elasticsearch using Docker Compose: ```bash +# For ElasticSearch docker-compose up -d elasticsearch -docker-compose build app-elasticsearch +# For OpenSearch +docker-compose up -d opensearch ``` -#### **Step 3: Run the Elasticsearch API on `localhost:8080`** +##### **Step 3: Run the Application** + +With Elasticsearch running, you can now run the application: + +```bash +uvicorn stac_fastapi.elasticsearch.app:app \ + --host localhost \ + --port 8080 \ + --workers 10 \ + --reload +``` -Launch the STAC-FastAPI application connected to Elasticsearch: +and with OpenSearch running: ```bash -docker-compose up -d app-elasticsearch +uvicorn stac_fastapi.opensearch.app:app \ + --host localhost \ + --port 8080 \ + --workers 10 \ + --reload ``` By default, Docker Compose uses Elasticsearch 8.x and OpenSearch 2.11.1. If you prefer to use different versions, create a file named `.env` in the same directory where you run Docker Compose and include the following lines: From 3e676748dbaf69322a4122cc5e525d791e1e0e39 Mon Sep 17 00:00:00 2001 From: Mo Date: Sun, 17 Nov 2024 20:45:50 +0100 Subject: [PATCH 14/21] minor changes in readme --- README.md | 66 +++++++++++++++++++------------------------------------ 1 file changed, 22 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index b394625b..9b10d2d1 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ ## Installation and Running: -### **Method 1: Install via PyPI and Run with Docker Compose or Podman Compose** +### **Method 1: Install via PyPI and Use Docker/Podman Compose for Backend** #### **Prerequisites** @@ -42,7 +42,7 @@ This approach is for users who want to install the Python package separately before running the app. -##### **Step 1: Install STAC-FastAPI** +#### **Step 1: Install STAC-FastAPI** - **For Elasticsearch backend:** @@ -56,7 +56,7 @@ This approach is for users who want to install the Python package separately bef pip install stac_fastapi.opensearch ``` -##### **Step 2: Start Elasticsearch/OpenSearch Backend** +#### **Step 2: Start Elasticsearch/OpenSearch Backend** Launch Elasticsearch using Docker Compose: @@ -67,7 +67,7 @@ docker-compose up -d elasticsearch docker-compose up -d opensearch ``` -##### **Step 3: Run the Application** +#### **Step 3: Run the Application** With Elasticsearch running, you can now run the application: @@ -104,52 +104,25 @@ Most recent Elasticsearch 7.x versions should also be compatible. For detailed c - [**Docker**](https://docs.docker.com/get-started/) or [**Podman**](https://podman.io/docs) installed and running on your machine. In all the follwoing steps instead of `docker` you can use `podman` as well. -#### **Step 1: Create a `.env` File** - -Configure your environment variables in a `.env` file. You can choose to connect to an external Elasticsearch/OpenSearch instance or run one locally within the container. - -- **Option A: Connect to an External Instance** - - ```env - ES_HOST=your_external_host - ES_PORT=your_external_port - ES_USE_SSL=false # Set to 'true' if SSL is used - ES_VERIFY_CERTS=false # Set to 'true' to verify SSL certificates - ``` - -- **Option B: Running Locally Within the Container** - - - **For Elasticsearch:** - - ```env - RUN_LOCAL_ES=1 - ``` - - - **For OpenSearch:** - - ```env - RUN_LOCAL_OS=1 - ``` - -> [!IMPORTANT] -> The variables `RUN_LOCAL_ES` and `RUN_LOCAL_OS` correspond to **different Docker images**: -> - Use `RUN_LOCAL_ES` with the `ghcr.io/stac-utils/stac-fastapi-es` image. -> - Use `RUN_LOCAL_OS` with the `ghcr.io/stac-utils/stac-fastapi-os` image. - -#### **Step 2: Run the Docker Container** +> [!IMPORTANT] +> The variables `RUN_LOCAL_ES` and `RUN_LOCAL_OS` correspond to **different Docker backend images**. By default, both are set to `0`, indicating that the backend systems are expected to run externally. In this case, you must configure the appropriate `ES_HOST` and `ES_PORT` environment variables to connect to the external Elasticsearch or OpenSearch instance. Alternatively, if you do not have an external backend and wish to run Elasticsearch or OpenSearch alongside the STAC-FastAPI within the container, set the respective variable to `1`: +> - Use `RUN_LOCAL_ES` with the `ghcr.io/stac-utils/stac-fastapi-es` image. +> - Use `RUN_LOCAL_OS` with the `ghcr.io/stac-utils/stac-fastapi-os` image. +#### **Step 1: Run the Docker Container** + - **For Elasticsearch Backend:** - **Connecting to External Instance:** ```shell - docker run -d -p 8080:8080 --env-file .env ghcr.io/stac-utils/stac-fastapi-es:latest + docker run -d -p 8080:8080 -e ES_HOST=external_host -e ES_PORT=external_port ghcr.io/stac-utils/stac-fastapi-es:latest ``` - **Running Locally:** ```shell - docker run -d -p 8080:8080 -p 9200:9200 --env-file .env ghcr.io/stac-utils/stac-fastapi-es:latest + docker run -d -p 8080:8080 -p 9200:9200 -e RUN_LOCAL_ES=1 ghcr.io/stac-utils/stac-fastapi-es:latest ``` - **For OpenSearch Backend:** @@ -157,32 +130,37 @@ Configure your environment variables in a `.env` file. You can choose to connect - **Connecting to External Instance:** ```shell - docker run -d -p 8080:8080 --env-file .env ghcr.io/stac-utils/stac-fastapi-os:latest + docker run -d -p 8080:8080 -e ES_HOST=external_host -e ES_PORT=external_port ghcr.io/stac-utils/stac-fastapi-os:latest ``` - **Running Locally:** ```shell - docker run -d -p 8080:8080 -p 9202:9202 --env-file .env ghcr.io/stac-utils/stac-fastapi-os:latest + docker run -d -p 8080:8080 -p 9202:9202 -e RUN_LOCAL_OS=1 ghcr.io/stac-utils/stac-fastapi-os:latest ``` +> [!Note] +> For external instances of both **Elasticsearch** and **OpenSearch**, configure the following +> environment variables as needed: +> - `-e ES_USE_SSL=false` — Set to `true` if SSL is enabled. +> - `-e ES_VERIFY_CERTS=false` — Set to `true` to enable SSL certificate verification. > [!TIP] > If you need to mount a volume, use the [`-v`](https://docs.docker.com/engine/storage/volumes/#choose-the--v-or---mount-flag) flag. To specify an environment file, use the [`--env-file`](https://docs.docker.com/reference/cli/docker/container/run/#env) flag. -#### **Step 3: Verify and Access** +#### **Step 2: Verify and Access** - **Check if the container is running:** ```shell - docker ps # "podman ps" if you are running via podman + docker ps ``` - **Access the API:** Visit `http://localhost:8080` in your browser or use it as the base URL for API requests. -##### **Configuration reference keys:** +#### **Configuration reference keys:** You can customize additional settings in your `.env` file: ###### Key variables to configure: From 34f36a1d6b038cc7c928fc7f359c787060cba2b6 Mon Sep 17 00:00:00 2001 From: Mo Date: Tue, 19 Nov 2024 16:52:10 +0100 Subject: [PATCH 15/21] resolve the req change --- dockerfiles/Dockerfile.ci.es | 8 -------- dockerfiles/Dockerfile.ci.os | 9 --------- dockerfiles/entrypoint-es.sh | 7 +++++++ dockerfiles/entrypoint-os.sh | 7 +++++++ 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/dockerfiles/Dockerfile.ci.es b/dockerfiles/Dockerfile.ci.es index 14ea64d7..0d932c7e 100644 --- a/dockerfiles/Dockerfile.ci.es +++ b/dockerfiles/Dockerfile.ci.es @@ -1,12 +1,5 @@ FROM debian:bookworm-slim AS base -ENV ENVIRONMENT="local" -ENV APP_HOST="0.0.0.0" -ENV APP_PORT="8080" -ENV WEB_CONCURRENCY=10 -ENV ES_USE_SSL=false -ENV ES_VERIFY_CERTS=false -ENV STAC_FASTAPI_RATE_LIMIT="200/minute" ENV RUN_LOCAL_ES=0 RUN apt-get update && \ @@ -49,7 +42,6 @@ ENV ES_JAVA_OPTS="-Xms512m -Xmx1g" \ HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 CMD \ curl --silent --fail http://${APP_HOST}:${APP_PORT}/api.html || exit 1 -EXPOSE $APP_PORT USER elasticsearch ENTRYPOINT ["/entrypoint.sh"] diff --git a/dockerfiles/Dockerfile.ci.os b/dockerfiles/Dockerfile.ci.os index 4c0502a0..8c5de041 100644 --- a/dockerfiles/Dockerfile.ci.os +++ b/dockerfiles/Dockerfile.ci.os @@ -1,12 +1,5 @@ FROM debian:bookworm-slim AS base -ENV ENVIRONMENT="local" -ENV APP_HOST="0.0.0.0" -ENV APP_PORT="8080" -ENV WEB_CONCURRENCY=10 -ENV ES_USE_SSL=false -ENV ES_VERIFY_CERTS=false -ENV STAC_FASTAPI_RATE_LIMIT="200/minute" ENV RUN_LOCAL_OS=0 RUN apt-get update && \ @@ -47,7 +40,5 @@ ENV OPENSEARCH_JAVA_OPTS="-Xms512m -Xmx1g" \ HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 CMD \ curl --silent --fail http://${APP_HOST}:${APP_PORT}/api.html || exit 1 -EXPOSE $APP_PORT - USER opensearch ENTRYPOINT ["/entrypoint.sh"] diff --git a/dockerfiles/entrypoint-es.sh b/dockerfiles/entrypoint-es.sh index f9e7ddff..e6e9652b 100644 --- a/dockerfiles/entrypoint-es.sh +++ b/dockerfiles/entrypoint-es.sh @@ -7,6 +7,13 @@ YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' +APP_HOST="${APP_HOST:-0.0.0.0}" +APP_PORT="${APP_PORT:-8080}" +WEB_CONCURRENCY="${WEB_CONCURRENCY:-10}" +ES_USE_SSL="${ES_USE_SSL:-false}" +ES_VERIFY_CERTS="${ES_VERIFY_CERTS:-false}" +STAC_FASTAPI_RATE_LIMIT="${STAC_FASTAPI_RATE_LIMIT:-'200/minute'}" + function print_error() { echo -e "${RED}ERROR: $1${NC}" >&2 } diff --git a/dockerfiles/entrypoint-os.sh b/dockerfiles/entrypoint-os.sh index 3dafba64..8c565950 100644 --- a/dockerfiles/entrypoint-os.sh +++ b/dockerfiles/entrypoint-os.sh @@ -7,6 +7,13 @@ YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' +APP_HOST="${APP_HOST:-0.0.0.0}" +APP_PORT="${APP_PORT:-8080}" +WEB_CONCURRENCY="${WEB_CONCURRENCY:-10}" +ES_USE_SSL="${ES_USE_SSL:-false}" +ES_VERIFY_CERTS="${ES_VERIFY_CERTS:-false}" +STAC_FASTAPI_RATE_LIMIT="${STAC_FASTAPI_RATE_LIMIT:-'200/minute'}" + function print_error() { echo -e "${RED}ERROR: $1${NC}" >&2 } From a2ee00bd7d46dbab716960ffa2198a7dffb77026 Mon Sep 17 00:00:00 2001 From: Mo Date: Sun, 24 Nov 2024 12:44:53 +0100 Subject: [PATCH 16/21] dismantled the backends from dockerfiles and chnaged the REAME --- README.md | 144 ++++++----------------------------- docker-compose.yml | 10 +-- dockerfiles/Dockerfile.ci.es | 57 ++++++-------- dockerfiles/Dockerfile.ci.os | 54 ++++++------- dockerfiles/entrypoint-es.sh | 127 ------------------------------ dockerfiles/entrypoint-os.sh | 129 ------------------------------- 6 files changed, 68 insertions(+), 453 deletions(-) delete mode 100644 dockerfiles/entrypoint-es.sh delete mode 100644 dockerfiles/entrypoint-os.sh diff --git a/README.md b/README.md index 9b10d2d1..6180b77a 100644 --- a/README.md +++ b/README.md @@ -32,133 +32,34 @@ - For changes, see the [Changelog](CHANGELOG.md) - We are always welcoming contributions. For the development notes: [Contributing](CONTRIBUTING.md) -## Installation and Running: -### **Method 1: Install via PyPI and Use Docker/Podman Compose for Backend** +### To install from PyPI: -#### **Prerequisites** - -- [**Docker Compose**](https://docs.docker.com/compose/install/) or [**Podman Compose**](https://podman-desktop.io/docs/compose) installed and running on your machine. In all the follwoing steps instead of `docker-compose` you can use `podman-compose` as well. - -This approach is for users who want to install the Python package separately before running the app. - -#### **Step 1: Install STAC-FastAPI** - -- **For Elasticsearch backend:** - - ```bash - pip install stac_fastapi.elasticsearch - ``` - -- **For OpenSearch backend:** - - ```bash - pip install stac_fastapi.opensearch - ``` - -#### **Step 2: Start Elasticsearch/OpenSearch Backend** - -Launch Elasticsearch using Docker Compose: - -```bash -# For ElasticSearch -docker-compose up -d elasticsearch -# For OpenSearch -docker-compose up -d opensearch +```shell +pip install stac_fastapi.elasticsearch ``` - -#### **Step 3: Run the Application** - -With Elasticsearch running, you can now run the application: - -```bash -uvicorn stac_fastapi.elasticsearch.app:app \ - --host localhost \ - --port 8080 \ - --workers 10 \ - --reload +or +``` +pip install stac_fastapi.opensearch ``` -and with OpenSearch running: +## Run Elasticsearch API backend on localhost:8080 + +You need to ensure [**Docker Compose**](https://docs.docker.com/compose/install/) or [**Podman Compose**](https://podman-desktop.io/docs/compose) installed and running on your machine. In the follwoing command instead of `docker-compose` you can use `podman-compose` as well. -```bash -uvicorn stac_fastapi.opensearch.app:app \ - --host localhost \ - --port 8080 \ - --workers 10 \ - --reload +```shell +docker-compose up elasticsearch app-elasticsearch ``` -By default, Docker Compose uses Elasticsearch 8.x and OpenSearch 2.11.1. If you prefer to use different versions, create a file named `.env` in the same directory where you run Docker Compose and include the following lines: +By default, docker-compose uses Elasticsearch 8.x and OpenSearch 2.11.1. +If you wish to use a different version, put the following in a +file named `.env` in the same directory you run docker-compose from: -```env +```shell ELASTICSEARCH_VERSION=7.17.1 OPENSEARCH_VERSION=2.11.0 ``` - -Most recent Elasticsearch 7.x versions should also be compatible. For detailed compatibility information, please refer to the [opensearch-py documentation](https://github.com/opensearch-project/opensearch-py/blob/main/COMPATIBILITY.md). - -### **Method 2: Install and run only with Docker or podman** - -#### Prerequisites - -- [**Docker**](https://docs.docker.com/get-started/) or [**Podman**](https://podman.io/docs) installed and running on your machine. In all the follwoing steps instead of `docker` you can use `podman` as well. - -> [!IMPORTANT] -> The variables `RUN_LOCAL_ES` and `RUN_LOCAL_OS` correspond to **different Docker backend images**. By default, both are set to `0`, indicating that the backend systems are expected to run externally. In this case, you must configure the appropriate `ES_HOST` and `ES_PORT` environment variables to connect to the external Elasticsearch or OpenSearch instance. Alternatively, if you do not have an external backend and wish to run Elasticsearch or OpenSearch alongside the STAC-FastAPI within the container, set the respective variable to `1`: -> - Use `RUN_LOCAL_ES` with the `ghcr.io/stac-utils/stac-fastapi-es` image. -> - Use `RUN_LOCAL_OS` with the `ghcr.io/stac-utils/stac-fastapi-os` image. - -#### **Step 1: Run the Docker Container** - -- **For Elasticsearch Backend:** - - - **Connecting to External Instance:** - - ```shell - docker run -d -p 8080:8080 -e ES_HOST=external_host -e ES_PORT=external_port ghcr.io/stac-utils/stac-fastapi-es:latest - ``` - - - **Running Locally:** - - ```shell - docker run -d -p 8080:8080 -p 9200:9200 -e RUN_LOCAL_ES=1 ghcr.io/stac-utils/stac-fastapi-es:latest - ``` - -- **For OpenSearch Backend:** - - - **Connecting to External Instance:** - - ```shell - docker run -d -p 8080:8080 -e ES_HOST=external_host -e ES_PORT=external_port ghcr.io/stac-utils/stac-fastapi-os:latest - ``` - - - **Running Locally:** - - ```shell - docker run -d -p 8080:8080 -p 9202:9202 -e RUN_LOCAL_OS=1 ghcr.io/stac-utils/stac-fastapi-os:latest - ``` -> [!Note] -> For external instances of both **Elasticsearch** and **OpenSearch**, configure the following -> environment variables as needed: -> - `-e ES_USE_SSL=false` — Set to `true` if SSL is enabled. -> - `-e ES_VERIFY_CERTS=false` — Set to `true` to enable SSL certificate verification. - -> [!TIP] -> If you need to mount a volume, use the [`-v`](https://docs.docker.com/engine/storage/volumes/#choose-the--v-or---mount-flag) flag. To specify an environment file, use the [`--env-file`](https://docs.docker.com/reference/cli/docker/container/run/#env) flag. - - -#### **Step 2: Verify and Access** - -- **Check if the container is running:** - - ```shell - docker ps - ``` - -- **Access the API:** - - Visit `http://localhost:8080` in your browser or use it as the base URL for API requests. +The most recent Elasticsearch 7.x versions should also work. See the [opensearch-py docs](https://github.com/opensearch-project/opensearch-py/blob/main/COMPATIBILITY.md) for compatibility information. #### **Configuration reference keys:** @@ -167,10 +68,8 @@ You can customize additional settings in your `.env` file: | Variable | Description | Default | Required | |------------------------------|--------------------------------------------------------------------------------------|--------------------------|---------------------------------------------------------------------------------------------| -| `RUN_LOCAL_ES` | Enable local Elasticsearch in the container. | `0` | Optional (set to `1` to run local Elasticsearch) | -| `RUN_LOCAL_OS` | Enable local OpenSearch in the container. | `0` | Optional (set to `1` to run local OpenSearch) | -| `ES_HOST` | Hostname for external Elasticsearch/OpenSearch. | `localhost` | **Required if `RUN_LOCAL_ES=0` or `RUN_LOCAL_OS=0`** | -| `ES_PORT` | Port for Elasticsearch/OpenSearch. | `9200` (ES) / `9202` (OS)| **Required if `RUN_LOCAL_ES=0` or `RUN_LOCAL_OS=0`** | +| `ES_HOST` | Hostname for external Elasticsearch/OpenSearch. | `localhost` | Optional | +| `ES_PORT` | Port for Elasticsearch/OpenSearch. | `9200` (ES) / `9202` (OS)| Optional | | `ES_USE_SSL` | Use SSL for connecting to Elasticsearch/OpenSearch. | `false` | Optional | | `ES_VERIFY_CERTS` | Verify SSL certificates when connecting. | `false` | Optional | | `STAC_FASTAPI_TITLE` | Title of the API in the documentation. | `stac-fastapi-elasticsearch` or `stac-fastapi-opensearch` | Optional | @@ -182,11 +81,12 @@ You can customize additional settings in your `.env` file: | `WEB_CONCURRENCY` | Number of worker processes. | `10` | Optional | | `RELOAD` | Enable auto-reload for development. | `true` | Optional | | `STAC_FASTAPI_RATE_LIMIT` | API rate limit per client. | `200/minute` | Optional | - +| `BACKEND` | Tests-related variable | `elasticsearch` or `opensearch` based on the backend | Optional | +| `ELASTICSEARCH_VERSION` | ElasticSearch version | `7.17.1` | Optional | +| `OPENSEARCH_VERSION` | OpenSearch version | `2.11.0` | Optional | > [!NOTE] -> The variables `ES_HOST`, `ES_PORT`, `ES_USE_SSL`, and `ES_VERIFY_CERTS` apply to both Elasticsearch and OpenSearch, so there is no need to rename the key names to `OS_` even if you're using OpenSearch. - +> The variables `ES_HOST`, `ES_PORT`, `ES_USE_SSL`, and `ES_VERIFY_CERTS` apply to both Elasticsearch and OpenSearch backends, so there is no need to rename the key names to `OS_` even if you're using OpenSearch. ## Interacting with the API diff --git a/docker-compose.yml b/docker-compose.yml index da4633b9..8e3f38a7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,11 +3,8 @@ version: '3.9' services: app-elasticsearch: container_name: stac-fastapi-es - image: stac-utils/stac-fastapi-es + image: stac-es restart: always - build: - context: . - dockerfile: dockerfiles/Dockerfile.dev.es environment: - STAC_FASTAPI_TITLE=stac-fastapi-elasticsearch - STAC_FASTAPI_DESCRIPTION=A STAC FastAPI with an Elasticsearch backend @@ -35,11 +32,8 @@ services: app-opensearch: container_name: stac-fastapi-os - image: stac-utils/stac-fastapi-os + image: ghcr.io/stac-utils/stac-fastapi-os restart: always - build: - context: . - dockerfile: dockerfiles/Dockerfile.dev.os environment: - STAC_FASTAPI_TITLE=stac-fastapi-opensearch - STAC_FASTAPI_DESCRIPTION=A STAC FastAPI with an Opensearch backend diff --git a/dockerfiles/Dockerfile.ci.es b/dockerfiles/Dockerfile.ci.es index 0d932c7e..e2d9fb0b 100644 --- a/dockerfiles/Dockerfile.ci.es +++ b/dockerfiles/Dockerfile.ci.es @@ -1,47 +1,34 @@ -FROM debian:bookworm-slim AS base +FROM python:3.12-slim + +ENV APP_HOST="0.0.0.0" +ENV APP_PORT="8080" +ENV WEB_CONCURRENCY="10" +ENV RELOAD="true" +ENV ES_HOST="localhost" +ENV ES_PORT="9200" +ENV ES_USE_SSL="false" +ENV ES_VERIFY_CERTS="false" +ENV STAC_FASTAPI_TITLE="stac-fastapi-elasticsearch" +ENV STAC_FASTAPI_DESCRIPTION="A STAC FastAPI with an Elasticsearch backend" +ENV STAC_FASTAPI_VERSION="2.1" +ENV ENVIRONMENT="local" +ENV BACKEND="elasticsearch" +ENV STAC_FASTAPI_RATE_LIMIT="200/minute" -ENV RUN_LOCAL_ES=0 +WORKDIR /app RUN apt-get update && \ apt-get install -y --no-install-recommends \ gcc \ curl \ - python3 \ - python3-pip \ - python3-venv \ && apt-get clean && \ rm -rf /var/lib/apt/lists/* -# set non-root user -RUN groupadd -g 1000 elasticsearch && \ - useradd -u 1000 -g elasticsearch -s /bin/bash -m elasticsearch - -# elasticsearch binaries and libraries -COPY --from=docker.elastic.co/elasticsearch/elasticsearch:8.11.0 /usr/share/elasticsearch /usr/share/elasticsearch - -# ser ownership -RUN chown -R elasticsearch:elasticsearch /usr/share/elasticsearch - -WORKDIR /app -COPY . /app - -# stac-fastapi-es installation -RUN pip3 install --no-cache-dir --break-system-packages -e ./stac_fastapi/core && \ - pip3 install --no-cache-dir --break-system-packages ./stac_fastapi/elasticsearch[server] - -COPY elasticsearch/config/elasticsearch.yml /usr/share/elasticsearch/config/elasticsearch.yml - -COPY dockerfiles/entrypoint-es.sh /entrypoint.sh -RUN chmod +x /entrypoint.sh - - -ENV ES_JAVA_OPTS="-Xms512m -Xmx1g" \ - PATH="/usr/share/elasticsearch/bin:${PATH}" - +COPY . /app/ -HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 CMD \ - curl --silent --fail http://${APP_HOST}:${APP_PORT}/api.html || exit 1 +RUN pip3 install --no-cache-dir -e ./stac_fastapi/core && \ + pip3 install --no-cache-dir ./stac_fastapi/elasticsearch[server] +USER root -USER elasticsearch -ENTRYPOINT ["/entrypoint.sh"] +CMD ["python", "-m", "stac_fastapi.elasticsearch.app"] \ No newline at end of file diff --git a/dockerfiles/Dockerfile.ci.os b/dockerfiles/Dockerfile.ci.os index 8c5de041..ba8dfd22 100644 --- a/dockerfiles/Dockerfile.ci.os +++ b/dockerfiles/Dockerfile.ci.os @@ -1,44 +1,34 @@ -FROM debian:bookworm-slim AS base +FROM python:3.12-slim + +ENV STAC_FASTAPI_TITLE="stac-fastapi-opensearch" +ENV STAC_FASTAPI_DESCRIPTION="A STAC FastAPI with an Opensearch backend" +ENV STAC_FASTAPI_VERSION="3.0.0a2" +ENV APP_HOST="0.0.0.0" +ENV APP_PORT="8082" +ENV RELOAD="true" +ENV ENVIRONMENT="local" +ENV WEB_CONCURRENCY="10" +ENV ES_HOST="localhost" +ENV ES_PORT="9202" +ENV ES_USE_SSL="false" +ENV ES_VERIFY_CERTS="false" +ENV BACKEND="opensearch" +ENV STAC_FASTAPI_RATE_LIMIT="200/minute" -ENV RUN_LOCAL_OS=0 +WORKDIR /app RUN apt-get update && \ apt-get install -y --no-install-recommends \ gcc \ curl \ - python3 \ - python3-pip \ - python3-venv \ && apt-get clean && \ rm -rf /var/lib/apt/lists/* -# set non-root user -RUN groupadd -g 1000 opensearch && \ - useradd -u 1000 -g opensearch -s /bin/bash -m opensearch - -# opensearch binaries and libraries -COPY --from=opensearchproject/opensearch:2.11.1 /usr/share/opensearch /usr/share/opensearch - -# ser ownership -RUN chown -R opensearch:opensearch /usr/share/opensearch - -WORKDIR /app -COPY . /app - -# stac-fastapi-os installation -RUN pip3 install --no-cache-dir --break-system-packages -e ./stac_fastapi/core && \ - pip3 install --no-cache-dir --break-system-packages ./stac_fastapi/opensearch[server] - -COPY opensearch/config/opensearch.yml /usr/share/opensearch/config/opensearch.yml - -COPY dockerfiles/entrypoint-os.sh /entrypoint.sh -RUN chmod +x /entrypoint.sh +COPY . /app/ -ENV OPENSEARCH_JAVA_OPTS="-Xms512m -Xmx1g" \ - PATH="/usr/share/opensearch/bin:${PATH}" +RUN pip3 install --no-cache-dir -e ./stac_fastapi/core && \ + pip3 install --no-cache-dir ./stac_fastapi/opensearch[server] -HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 CMD \ - curl --silent --fail http://${APP_HOST}:${APP_PORT}/api.html || exit 1 +USER root -USER opensearch -ENTRYPOINT ["/entrypoint.sh"] +CMD ["python", "-m", "stac_fastapi.opensearch.app"] \ No newline at end of file diff --git a/dockerfiles/entrypoint-es.sh b/dockerfiles/entrypoint-es.sh deleted file mode 100644 index e6e9652b..00000000 --- a/dockerfiles/entrypoint-es.sh +++ /dev/null @@ -1,127 +0,0 @@ -#!/bin/bash -set -e - -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' - -APP_HOST="${APP_HOST:-0.0.0.0}" -APP_PORT="${APP_PORT:-8080}" -WEB_CONCURRENCY="${WEB_CONCURRENCY:-10}" -ES_USE_SSL="${ES_USE_SSL:-false}" -ES_VERIFY_CERTS="${ES_VERIFY_CERTS:-false}" -STAC_FASTAPI_RATE_LIMIT="${STAC_FASTAPI_RATE_LIMIT:-'200/minute'}" - -function print_error() { - echo -e "${RED}ERROR: $1${NC}" >&2 -} - -function print_warning() { - echo -e "${YELLOW}WARNING: $1${NC}" -} - -function print_success() { - echo -e "${GREEN}SUCCESS: $1${NC}" -} - -function print_info() { - echo -e "${BLUE}INFO: $1${NC}" -} - -function validate_elasticsearch() { - local retry_count=0 - local max_retries=5 - local wait_time=5 - - while [ $retry_count -lt $max_retries ]; do - print_info "Checking Elasticsearch connection (Attempt $((retry_count + 1))/$max_retries)..." - - local response_body=$(curl -k -s "http://${ES_HOST}:${ES_PORT}/" 2>/dev/null) - local health=$(curl -k -s -o /dev/null -w '%{http_code}' "http://${ES_HOST}:${ES_PORT}/_cluster/health" 2>/dev/null) - - if [ "$health" -eq 200 ]; then - if echo "$response_body" | grep -q '"tagline" *: *"You Know, for Search"'; then - print_success "Successfully connected to Elasticsearch via HTTP" - export ES_USE_SSL=false - return 0 - else - print_error "Connected to a service that is not Elasticsearch" - print_error "Found service response: $response_body" - return 1 - fi - fi - - print_info "HTTP connection failed, trying HTTPS..." - response_body=$(curl -k -s "https://${ES_HOST}:${ES_PORT}/" 2>/dev/null) - health=$(curl -s -o /dev/null -w '%{http_code}' "https://${ES_HOST}:${ES_PORT}/_cluster/health" 2>/dev/null) - - if [ "$health" -eq 200 ]; then - if echo "$response_body" | grep -q '"tagline" *: *"You Know, for Search"'; then - print_success "Successfully connected to Elasticsearch via HTTPS" - export ES_USE_SSL=true - return 0 - else - print_error "Connected to a service that is not Elasticsearch" - print_error "Found service response: $response_body" - return 1 - fi - fi - - retry_count=$((retry_count + 1)) - if [ $retry_count -lt $max_retries ]; then - print_warning "Connection attempt $retry_count failed. Waiting ${wait_time} seconds before retry..." - sleep $wait_time - wait_time=$((wait_time * 2)) - fi - done - - print_error "Failed to connect to Elasticsearch after $max_retries attempts:" - print_error " - http://${ES_HOST}:${ES_PORT}" - print_error " - https://${ES_HOST}:${ES_PORT}" - print_error " Please ensure:" - print_error " - Elasticsearch is running" - print_error " - ES_HOST and ES_PORT are correctly set" - print_error " - Network connectivity is available" - print_error " - SSL/TLS settings are correct if using HTTPS" - return 1 -} - -if [ "${RUN_LOCAL_ES}" = "0" ]; then - if [ -z "${ES_HOST}" ] || [ -z "${ES_PORT}" ]; then - print_error "When RUN_LOCAL_ES=0, you must specify both ES_HOST and ES_PORT" - print_error "Current settings:" - print_error " ES_HOST: ${ES_HOST:-not set}" - print_error " ES_PORT: ${ES_PORT:-not set}" - exit 1 - fi -else - export ES_HOST=${ES_HOST:-localhost} - export ES_PORT=${ES_PORT:-9200} -fi - -if [ "${RUN_LOCAL_ES}" = "1" ]; then - print_info "Starting local Elasticsearch instance" - /usr/share/elasticsearch/bin/elasticsearch & - - print_info "Waiting for Elasticsearch to be ready" - until validate_elasticsearch; do - print_info "Elasticsearch not yet ready. Retrying..." - sleep 5 - done - print_success "Elasticsearch is up and running" -else - print_info "Using external Elasticsearch at ${ES_HOST}:${ES_PORT}" - if ! validate_elasticsearch; then - print_error "Cannot connect to external Elasticsearch. Exiting..." - exit 1 - fi -fi - -print_info "Starting STAC FastAPI Elasticsearch" -exec uvicorn stac_fastapi.elasticsearch.app:app \ - --host "${APP_HOST}" \ - --port "${APP_PORT}" \ - --workers "${WEB_CONCURRENCY}" \ - --reload \ No newline at end of file diff --git a/dockerfiles/entrypoint-os.sh b/dockerfiles/entrypoint-os.sh deleted file mode 100644 index 8c565950..00000000 --- a/dockerfiles/entrypoint-os.sh +++ /dev/null @@ -1,129 +0,0 @@ -#!/bin/bash -set -e - -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' - -APP_HOST="${APP_HOST:-0.0.0.0}" -APP_PORT="${APP_PORT:-8080}" -WEB_CONCURRENCY="${WEB_CONCURRENCY:-10}" -ES_USE_SSL="${ES_USE_SSL:-false}" -ES_VERIFY_CERTS="${ES_VERIFY_CERTS:-false}" -STAC_FASTAPI_RATE_LIMIT="${STAC_FASTAPI_RATE_LIMIT:-'200/minute'}" - -function print_error() { - echo -e "${RED}ERROR: $1${NC}" >&2 -} - -function print_warning() { - echo -e "${YELLOW}WARNING: $1${NC}" -} - -function print_success() { - echo -e "${GREEN}SUCCESS: $1${NC}" -} - -function print_info() { - echo -e "${BLUE}INFO: $1${NC}" -} - -function validate_opensearch() { - local retry_count=0 - local max_retries=5 - local wait_time=5 - - while [ $retry_count -lt $max_retries ]; do - print_info "Checking OpenSearch connection (Attempt $((retry_count + 1))/$max_retries)..." - - local response_body=$(curl -k -s "http://${ES_HOST}:${ES_PORT}/" 2>/dev/null) - local health=$(curl -k -s -o /dev/null -w '%{http_code}' "http://${ES_HOST}:${ES_PORT}/_cluster/health" 2>/dev/null) - - if [ "$health" -eq 200 ]; then - if echo "$response_body" | grep -q '"distribution" *: *"opensearch"'; then - print_success "Successfully connected to OpenSearch via HTTP" - export ES_USE_SSL=false - return 0 - else - print_error "Connected to a service that is not OpenSearch" - print_error "Found service response: $response_body" - return 1 - fi - fi - - print_info "HTTP connection failed, trying HTTPS..." - response_body=$(curl -k -s "https://${ES_HOST}:${ES_PORT}/" 2>/dev/null) - health=$(curl -s -o /dev/null -w '%{http_code}' "https://${ES_HOST}:${ES_PORT}/_cluster/health" 2>/dev/null) - - if [ "$health" -eq 200 ]; then - if echo "$response_body" | grep -q '"distribution" *: *"opensearch"'; then - print_success "Successfully connected to OpenSearch via HTTPS" - export ES_USE_SSL=true - return 0 - else - print_error "Connected to a service that is not OpenSearch" - print_error "Found service response: $response_body" - return 1 - fi - fi - - retry_count=$((retry_count + 1)) - if [ $retry_count -lt $max_retries ]; then - print_warning "Connection attempt $retry_count failed. Waiting ${wait_time} seconds before retry..." - sleep $wait_time - wait_time=$((wait_time * 2)) - fi - done - - print_error "Failed to connect to OpenSearch after $max_retries attempts:" - print_error " - http://${ES_HOST}:${ES_PORT}" - print_error " - https://${ES_HOST}:${ES_PORT}" - print_error "Please ensure:" - print_error " - OpenSearch is running" - print_error " - ES_HOST and ES_PORT are correctly set" - print_error " - Network connectivity is available" - print_error " - SSL/TLS settings are correct if using HTTPS" - print_error " - You are not connecting to Elasticsearch or another service" - return 1 -} - -if [ "${RUN_LOCAL_OS}" = "0" ]; then - if [ -z "${ES_HOST}" ] || [ -z "${ES_PORT}" ]; then - print_error "When RUN_LOCAL_OS=0, you must specify both ES_HOST and ES_PORT" - print_error "Current settings:" - print_error " ES_HOST: ${ES_HOST:-not set}" - print_error " ES_PORT: ${ES_PORT:-not set}" - exit 1 - fi -else - export ES_HOST=${ES_HOST:-localhost} - export ES_PORT=${ES_PORT:-9202} -fi - -if [ "${RUN_LOCAL_OS}" = "1" ]; then - print_info "Starting local OpenSearch instance" - /usr/share/opensearch/bin/opensearch & - - print_info "Waiting for OpenSearch to be ready" - sleep 10 # Initial wait for OpenSearch to start - until validate_opensearch; do - print_info "OpenSearch not yet ready. Retrying..." - sleep 5 - done - print_success "OpenSearch is up and running" -else - print_info "Using external OpenSearch at ${ES_HOST}:${ES_PORT}" - if ! validate_opensearch; then - print_error "Cannot connect to external OpenSearch. Exiting..." - exit 1 - fi -fi - -print_info "Starting STAC FastAPI OpenSearch" -exec uvicorn stac_fastapi.opensearch.app:app \ - --host "${APP_HOST}" \ - --port "${APP_PORT}" \ - --workers "${WEB_CONCURRENCY}" \ - --reload \ No newline at end of file From 12af96a0d7d132301f8cec6b5db21d8e7e0255dd Mon Sep 17 00:00:00 2001 From: Mo Date: Sun, 24 Nov 2024 12:52:14 +0100 Subject: [PATCH 17/21] prepared publish ci action --- .github/workflows/publish.yml | 76 ----------------------------------- 1 file changed, 76 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ac25470b..eb84e7fc 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -92,44 +92,6 @@ jobs: type=raw,value=latest type=ref,event=tag - - name: Build Elasticsearch image - uses: docker/build-push-action@v6 - with: - context: . - file: dockerfiles/Dockerfile.ci.es - platforms: linux/amd64 - push: false - load: true - tags: stac-fastapi-es:test - cache-from: type=gha - cache-to: type=gha,mode=max - - - name: Test Elasticsearch image - run: | - docker run -d --name stac-es \ - -e RUN_LOCAL_ES=1 \ - stac-fastapi-es:test - - timeout=120 - while [ $timeout -gt 0 ]; do - if docker inspect stac-es --format='{{.State.Health.Status}}' | grep -q 'healthy'; then - echo "Container is healthy" - break - fi - if [ $timeout -eq 0 ]; then - echo "Health check failed" - docker logs stac-es - docker stop stac-es - docker rm stac-es - exit 1 - fi - sleep 5 - timeout=$((timeout-5)) - done - - docker stop stac-es - docker rm stac-es - - name: Push Elasticsearch image uses: docker/build-push-action@v6 with: @@ -151,44 +113,6 @@ jobs: type=raw,value=latest type=ref,event=tag - - name: Build OpenSearch image - uses: docker/build-push-action@v6 - with: - context: . - file: dockerfiles/Dockerfile.ci.os - platforms: linux/amd64 - push: false - load: true - tags: stac-fastapi-os:test - cache-from: type=gha - cache-to: type=gha,mode=max - - - name: Test OpenSearch image - run: | - docker run -d --name stac-os \ - -e RUN_LOCAL_OS=1 \ - stac-fastapi-os:test - - timeout=120 - while [ $timeout -gt 0 ]; do - if docker inspect stac-os --format='{{.State.Health.Status}}' | grep -q 'healthy'; then - echo "Container is healthy" - break - fi - if [ $timeout -eq 0 ]; then - echo "Health check failed" - docker logs stac-os - docker stop stac-os - docker rm stac-os - exit 1 - fi - sleep 5 - timeout=$((timeout-5)) - done - - docker stop stac-os - docker rm stac-os - - name: Push OpenSearch image uses: docker/build-push-action@v6 with: From 808ee37e46995e2ec2c7d47bd9e7b80511cfb7ec Mon Sep 17 00:00:00 2001 From: Mo Date: Sun, 24 Nov 2024 13:15:35 +0100 Subject: [PATCH 18/21] added latest version on image links --- docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 8e3f38a7..7dc00277 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,7 @@ version: '3.9' services: app-elasticsearch: container_name: stac-fastapi-es - image: stac-es + image: ghcr.io/stac-utils/stac-fastapi-es:latest restart: always environment: - STAC_FASTAPI_TITLE=stac-fastapi-elasticsearch @@ -32,7 +32,7 @@ services: app-opensearch: container_name: stac-fastapi-os - image: ghcr.io/stac-utils/stac-fastapi-os + image: ghcr.io/stac-utils/stac-fastapi-os:latest restart: always environment: - STAC_FASTAPI_TITLE=stac-fastapi-opensearch From f4ab11008b123d9bb5e6205a8652ba58c6fe49c6 Mon Sep 17 00:00:00 2001 From: Mo Date: Wed, 27 Nov 2024 09:55:45 +0100 Subject: [PATCH 19/21] removed env var from dockerfiles and minor change in docker-compose --- docker-compose.yml | 4 ++-- dockerfiles/Dockerfile.ci.es | 15 --------------- dockerfiles/Dockerfile.ci.os | 15 --------------- 3 files changed, 2 insertions(+), 32 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 7dc00277..ca18a19f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,7 @@ version: '3.9' services: app-elasticsearch: container_name: stac-fastapi-es - image: ghcr.io/stac-utils/stac-fastapi-es:latest + image: stac-utils/stac-fastapi-es restart: always environment: - STAC_FASTAPI_TITLE=stac-fastapi-elasticsearch @@ -32,7 +32,7 @@ services: app-opensearch: container_name: stac-fastapi-os - image: ghcr.io/stac-utils/stac-fastapi-os:latest + image: stac-utils/stac-fastapi-os restart: always environment: - STAC_FASTAPI_TITLE=stac-fastapi-opensearch diff --git a/dockerfiles/Dockerfile.ci.es b/dockerfiles/Dockerfile.ci.es index e2d9fb0b..a6fb6a53 100644 --- a/dockerfiles/Dockerfile.ci.es +++ b/dockerfiles/Dockerfile.ci.es @@ -1,20 +1,5 @@ FROM python:3.12-slim -ENV APP_HOST="0.0.0.0" -ENV APP_PORT="8080" -ENV WEB_CONCURRENCY="10" -ENV RELOAD="true" -ENV ES_HOST="localhost" -ENV ES_PORT="9200" -ENV ES_USE_SSL="false" -ENV ES_VERIFY_CERTS="false" -ENV STAC_FASTAPI_TITLE="stac-fastapi-elasticsearch" -ENV STAC_FASTAPI_DESCRIPTION="A STAC FastAPI with an Elasticsearch backend" -ENV STAC_FASTAPI_VERSION="2.1" -ENV ENVIRONMENT="local" -ENV BACKEND="elasticsearch" -ENV STAC_FASTAPI_RATE_LIMIT="200/minute" - WORKDIR /app RUN apt-get update && \ diff --git a/dockerfiles/Dockerfile.ci.os b/dockerfiles/Dockerfile.ci.os index ba8dfd22..a046a3b6 100644 --- a/dockerfiles/Dockerfile.ci.os +++ b/dockerfiles/Dockerfile.ci.os @@ -1,20 +1,5 @@ FROM python:3.12-slim -ENV STAC_FASTAPI_TITLE="stac-fastapi-opensearch" -ENV STAC_FASTAPI_DESCRIPTION="A STAC FastAPI with an Opensearch backend" -ENV STAC_FASTAPI_VERSION="3.0.0a2" -ENV APP_HOST="0.0.0.0" -ENV APP_PORT="8082" -ENV RELOAD="true" -ENV ENVIRONMENT="local" -ENV WEB_CONCURRENCY="10" -ENV ES_HOST="localhost" -ENV ES_PORT="9202" -ENV ES_USE_SSL="false" -ENV ES_VERIFY_CERTS="false" -ENV BACKEND="opensearch" -ENV STAC_FASTAPI_RATE_LIMIT="200/minute" - WORKDIR /app RUN apt-get update && \ From 10eba9be2e56a7dcb05bb11afc361409b7f3abdd Mon Sep 17 00:00:00 2001 From: Mo Date: Wed, 27 Nov 2024 09:58:23 +0100 Subject: [PATCH 20/21] added forgotten build stage in docker-compose es and os services --- docker-compose.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index ca18a19f..da4633b9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,6 +5,9 @@ services: container_name: stac-fastapi-es image: stac-utils/stac-fastapi-es restart: always + build: + context: . + dockerfile: dockerfiles/Dockerfile.dev.es environment: - STAC_FASTAPI_TITLE=stac-fastapi-elasticsearch - STAC_FASTAPI_DESCRIPTION=A STAC FastAPI with an Elasticsearch backend @@ -34,6 +37,9 @@ services: container_name: stac-fastapi-os image: stac-utils/stac-fastapi-os restart: always + build: + context: . + dockerfile: dockerfiles/Dockerfile.dev.os environment: - STAC_FASTAPI_TITLE=stac-fastapi-opensearch - STAC_FASTAPI_DESCRIPTION=A STAC FastAPI with an Opensearch backend From c033dfb354da380b816a11f0d343955bfd7006a0 Mon Sep 17 00:00:00 2001 From: Mo Date: Thu, 28 Nov 2024 10:48:38 +0100 Subject: [PATCH 21/21] added docs in README --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 6180b77a..05b1627b 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,18 @@ or pip install stac_fastapi.opensearch ``` +### To install and run via pre-built Docker Images + +We provide ready-to-use Docker images through GitHub Container Registry ([ElasticSearch](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pkgs/container/stac-fastapi-es) and [OpenSearch](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pkgs/container/stac-fastapi-os) backends). You can easily pull and run these images: + +```shell +# For Elasticsearch backend +docker pull ghcr.io/stac-utils/stac-fastapi-es:latest + +# For OpenSearch backend +docker pull ghcr.io/stac-utils/stac-fastapi-os:latest +``` + ## Run Elasticsearch API backend on localhost:8080 You need to ensure [**Docker Compose**](https://docs.docker.com/compose/install/) or [**Podman Compose**](https://podman-desktop.io/docs/compose) installed and running on your machine. In the follwoing command instead of `docker-compose` you can use `podman-compose` as well.