Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/helmchart #40

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,23 @@ For a quick setup of AgentKit, use the steps below, where both the backend app a
```
Wait for the containers to build and start, which may take a few minutes depending on your system. Once the containers are up and running, you can access the apps in your browser at [http://localhost](http://localhost/).

4. (optional) Setup some alias for easier docker compose command:

On Windows PowerShell you can run for the demo :

```powershell
function ddf { docker compose -f .\docker-compose-demo.yml @args }; New-Alias dd ddf
```

Then you can simply use the shortcuts:
* `dd build` : rebuild the necessary docker images
* `dd up -d` : spin-up the set of docker images and detach from execution (-d means background mode)
* `dd logs -f` : attatch to log streaming for all containers
* `dd logs <containername> -f` : attatch to log streaming for a particular container
* `dd down` : spin-down the set of docker images, add a `-v` to auto remove volumes & network



## Chinook music database demo
- If docker containers are running, run `docker-compose down --volumes`
- Follow the installation instructions above and swap `docker-compose.yml` with `docker-compose-demo.yml` to run the app
Expand Down
3 changes: 3 additions & 0 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ RUN curl -sSL https://install.python-poetry.org | POETRY_HOME=/opt/poetry python
# Copy poetry.lock* in case it doesn't exist in the repo
COPY app/pyproject.toml app/poetry.lock* /code/

RUN mkdir /scripts
COPY scripts app/poetry.lock* /scripts/

# Allow installing dev dependencies to run tests
ARG INSTALL_DEV=false
RUN bash -c "if [ $INSTALL_DEV == 'true' ] ; then poetry install --with dev --no-root ; else poetry install --no-root --no-dev ; fi"
Expand Down
File renamed without changes.
56 changes: 56 additions & 0 deletions docker-compose-coding.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
version: '3.8'

services:
fastapi_server:
container_name: fastapi_server
build: ./backend
restart: always
# Enable debug mode run .vscode/launch.json -> "Debug: Attach to FastAPI Docker"
# command: "sh -c 'pip install debugpy -t /tmp && alembic upgrade head && python /tmp/debugpy --wait-for-client --listen 0.0.0.0:5678 -m uvicorn app.main:app --reload --workers 1 --host 0.0.0.0 --port 9090 --loop asyncio'"
# ports:
# - 5678:5678
# Disable debug mode if only frontend development
#command: "sh -c 'alembic upgrade head && python app/document_ingestion.py && uvicorn app.main:app --reload --workers 1 --host 0.0.0.0 --port 9090'"
command: "sh -c 'alembic upgrade head && uvicorn app.main:app --reload --workers 1 --host 0.0.0.0 --port 9090'"
volumes:
- ./backend/app:/code
ports:
- 9090:9090
expose:
- 9090
env_file: ".env"
depends_on:
- database

database:
image: ankane/pgvector:v0.4.1
restart: always
container_name: database
env_file: ".env"
user: root
volumes:
- ./db_docker:/var/lib/postgresql
- ./backend/scripts/1-create-dbs.sql:/docker-entrypoint-initdb.d/1-create-dbs.sql
ports:
- 5432:5432
expose:
- 5432
environment:
- POSTGRES_USERNAME=${DATABASE_USER}
- POSTGRES_PASSWORD=${DATABASE_PASSWORD}
- POSTGRES_DATABASE=${DATABASE_NAME}
- POSTGRES_HOST_AUTH_METHOD= "trust"

redis_server:
image: redis:alpine
container_name: redis_server
restart: always
ports:
- 6379:6379 # Remove this on production
expose:
- 6379
env_file: .env

volumes:
langchain-db-data:
langchain-redis-data:
4 changes: 2 additions & 2 deletions docker-compose-demo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ services:
user: root
volumes:
- ./db_docker:/var/lib/postgresql
- ./scripts/1-create-dbs.sql:/docker-entrypoint-initdb.d/1-create-dbs.sql
- ./scripts/sql_db_tool/2-chinook_psql_load.sql:/docker-entrypoint-initdb.d/2-chinook_psql_load.sql
- ./backend/scripts/1-create-dbs.sql:/docker-entrypoint-initdb.d/1-create-dbs.sql
- ./backend/scripts/sql_db_tool/2-chinook_psql_load.sql:/docker-entrypoint-initdb.d/2-chinook_psql_load.sql
ports:
- 5432:5432
expose:
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ services:
user: root
volumes:
- ./db_docker:/var/lib/postgresql
- ./scripts/1-create-dbs.sql:/docker-entrypoint-initdb.d/1-create-dbs.sql
- ./backend/scripts/1-create-dbs.sql:/docker-entrypoint-initdb.d/1-create-dbs.sql
ports:
- 5432:5432
expose:
Expand Down
12 changes: 0 additions & 12 deletions frontend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,6 @@ WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

# Declare all build args are env vars for build
Copy link
Contributor

Choose a reason for hiding this comment

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

if we removed these, we need to skip validation during build time in
frontend/src/env.mjs
try to build it without .env available in build time which will be the case in a ci/cd pipeline.

also with skipping validation, anything that starts with NEXT_PUBLIC, we need to pass it in publicRuntimeConfig instead of envs otherwise won't be picked up during the running time and will be undefined.

my approach was to put the build-time envs that we needed, in
publicRuntimeConfig check : runtime-configuration
we can ignore the hostname and use just /api/v1.
and then if the backend is hosted in a different host, the dev can just put the full address; (HTTP://......./api/v1)...

#ARG GITHUB_ID
#ENV GITHUB_ID ${GITHUB_ID}
#ARG GITHUB_SECRET
#ENV GITHUB_SECRET ${GITHUB_SECRET}
#ARG NEXTAUTH_SECRET
#ENV NEXTAUTH_SECRET ${NEXTAUTH_SECRET}
#ARG NEXTAUTH_URL
#ENV NEXTAUTH_URL ${NEXTAUTH_URL}
#ARG NEXT_PUBLIC_API_URL
#ENV NEXT_PUBLIC_API_URL ${NEXT_PUBLIC_API_URL}

RUN yarn run prisma:generate
RUN yarn run build

Expand Down
140 changes: 140 additions & 0 deletions helm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@

# Helm Charts Documentation

This documentation covers the deployment process for the backend and frontend Agentkit services using Helm charts.
Below are the steps to follow for building Docker images and managing deployments with Helm.

Pre-requisites:

- Have Docker registry availlable to push the images
- Have Kubectl & Helm installed on your machine
- Have a Kubernetes cluster available and connectable from your machine

- Know what namespace you will use to deploy your services. In this documentation, we will use the namespace `akit` as an example.
- Define the name of the release you want to use for backend and frontend services. In this documentation, we will use `akitfrt` and `akitback` as examples.




## Backend Service

### Building the Docker Image

To build the Docker image for the backend service, you need to run the following commands.
Use the script `bash helm/scripts/build-docker-image.sh` for reference if needed.

```shell

# Define variables for registry, image name, and image tag
REGISTRY=your-registry
IMAGE_NAME=akitbackend
IMAGE_TAG=latest

# Navigate to the backend directory where the Dockerfile is located
cd "$(dirname "$0")/../../backend"

# Build the Docker image
docker build -t ${REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} .

# Push the image to the registry
docker push ${REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}

```


### Deploying with Helm

After building the image, use the following Helm commands to manage your deployment:

```shell
# For the first time deployment
helm install -n akit akitback helm/backend

# Updating the deployment
helm upgrade -n akit akitback helm/backend
```

You may want to configure the deployment using a custom `values.yaml` file, by using --values flag in the Helm commands.

Alternatively, you can set the values directly in the command line; ex : `--set image.repository=your-registry/akitbackend,image.tag=latest`


## Frontend Service

### Building the Docker Image

To build the Docker image for the frontend service :

```shell
REGISTRY=your-registry
IMAGE_NAME=agentkitfrt
IMAGE_TAG=latest


# Navigate to the frontend directory where the Dockerfile is located
cd "$(dirname "$0")/../../frontend"

# Build the Docker image
docker buildx build --no-cache --platform linux/amd64 -t ${REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} .

# Push the image to a registry if needed, for example:
docker push ${REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}

echo "Docker image ${REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} built successfully."
```

### Deploying with Helm

Use the following Helm commands for the frontend service:

```shell
# For the first time deployment
helm install -n akit akitfrt helm/frontend

# Updating the deployment
helm upgrade -n akit akitfrt helm/frontend
```

## Secrets Management

Secrets should be managed securely and not stored in version control. Use Kubernetes secrets or a third-party secrets manager to inject secrets into your deployments.

You can use the script [set-secrets.sh](helm/scripts/set-secrets.sh) to create secrets in your Kubernetes cluster.

```shell
# copy the example secrets file
cp helm/scripts/secrets_example.sh helm/scripts/secrets.sh
# edit the secrets.sh file with your secrets
bash set-secrets.sh
```

Be carefull to match the namespace and the release name you are using for your deployment. In our example, the `secrets.sh` file should start like this:

```shell
# Set the namespace variable - change this to your namespace
NAMESPACE="akit"

# Set the release name variable - change this to your release name
RELEASE_NAME="akitback"
FRONT_RELEASE_NAME="akitfrt"
# rest of the file ...
```



## Routing and Ingress

Ingress routes should be defined to expose the services. Configure the `ingress.yaml` within each chart to specify the hostnames and paths for routing.

## Optional Dependencies

The backend service may optionally depend on `pgvectordb` and `rediscache`. These dependencies can be managed as sub-charts or separate deployments. Ensure that the connection details are configured correctly in the `values.yaml` file of the backend service.

To include these dependencies, set the appropriate flags in the `values.yaml` file or pass them as parameters during the Helm install/upgrade commands.

```shell
helm install backend-chart ./backend --set pgvectordb.enabled=true,rediscache.enabled=true
```

For more detailed configuration, refer to the individual chart `values.yaml` files.

23 changes: 23 additions & 0 deletions helm/backend/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
18 changes: 18 additions & 0 deletions helm/backend/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
apiVersion: v2
name: agentkit-backend
description: A Helm chart for Agentkit backend
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "1.0"
maintainers:
- email: [email protected]
name: fanf
13 changes: 13 additions & 0 deletions helm/backend/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{{- if .Values.ingress.enabled }}
1. Get the application URL by running these commands:
{{- if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "backend.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:{{ .Values.service.port }}
{{- else }}
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "backend.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "Visit http://$SERVICE_IP to use your application"
{{- end }}
{{- else }}
1. The application is not externally accessible by default since the ingress is disabled. To enable it, set the ingress.enabled to true and configure the ingress settings in your values.yaml file.
{{- end }}
41 changes: 41 additions & 0 deletions helm/backend/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{{/*
Selector labels
*/}}
{{- define "backend.selectorLabels" -}}
app.kubernetes.io/name: {{ include "backend.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}

{{/*
Common labels
*/}}
{{- define "backend.labels" -}}
app.kubernetes.io/name: {{ include "backend.name" . }}
helm.sh/chart: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}

{{/*
Expand the name of the chart.
*/}}
{{- define "backend.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
*/}}
{{- define "backend.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}