npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

cdk-cheshire-cat

v1.0.0

Published

![1705925803352](image/README/cheshire-cat-rocket-cloud.png)

Downloads

30

Readme

1705925803352

What is this?

CDK construct library that allows you to create a Cheshire Cat using the AWS Cloud Development Kit (CDK) in TypeScript. The project's infrastructure includes setting up a Qdrant server, the vector search engine, as part of its architecture.

CAUTION cdk-cheshire-cat needs cheshire cat core version >= 1.4.8

Quickstart

Installation

Use the npm or yarn package manager to install the package

npm install cdk-cheshire-cat

Usage

Use the construct in your CDK application:

import { CdkCheshireCat } from 'cdk-cheshire-cat';

new CdkCheshireCat(this, 'CheshireCat');

Deployment

  1. Configure AWS CLI as per instruction Get started with the AWS CLI
  2. Run cdk bootstrap
  3. Run cdk deploy
  4. Wait a few minutes for the deployment to complete 1705925307100
  5. Go to CatHost output url with /admin to access the CheshireCat admin
  6. Go to QdrantHost output url with /dashboard to access the Qdrant Server dashboard

Infrastructure (AWS)

  • ECS Cluster (Fargate) for Qdrant: Hosts the Qdrant server, integrated with EFS for data storage and retrieval.
  • ECS Cluster (Fargate) for Cheshire Cat: Dedicated cluster running the Docker container of the Cheshire Cat application.
  • EFS (Elastic File System): Centralized storage for persistent data, utilized by both the Qdrant server and the Cheshire Cat application.

Examples

All default

The simplest example shows all defaults below.

import { CfnOutput, Stack, StackProps, App } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { CdkCheshireCat } from 'cdk-cheshire-cat';

export class DefaultCat extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const cheshireCat = new CdkCheshireCat(this, 'CheshireCat');

    new CfnOutput(this, "CatHost", {
      value: cheshireCat.catEcsCluster.fargateService.loadBalancer.loadBalancerDnsName,
    });
    new CfnOutput(this, "QdrantHost", {
      value: cheshireCat.qdrantEcsCluster.fargateService.loadBalancer.loadBalancerDnsName,
    });
  }
}

const app = new App();
new DefaultCat(app, 'default');

The initial deployment takes a few minutes, after which a URL for CheshireCat and one for Qdrant Server will appear in the terminal. After a few minutes of adjustment, the services will be available at the relevant URLs.

By default, all the following are created:

  • A VPC
  • An Internet-facing load balancer serving HTTP (not HTTPS) traffic for CheshireCat server
  • An ECS cluster with CheshireCat running on it
  • An Internet-facing load balancer serving HTTP (not HTTPS) traffic for Qdrant server
  • An ECS cluster with Qdrant server running on it
  • An EFS mounted on both qdrant and cheshirecat tasks to storage permanent data

Custom Cat Image

If you need to use a custom docker image for the cat you can replace the default one like this:

import { CfnOutput, Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { CdkCheshireCat } from 'cdk-cheshire-cat';
import * as ecs from 'aws-cdk-lib/aws-ecs'
import * as cdk from 'aws-cdk-lib'
import * as path from 'path'

export class CustomCatImage extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);
  
    const qdrantImage = ecs.ContainerImage.fromRegistry('qdrant/qdrant:v1.7.2');
    // You have to link the Dockerfile folder, for example ./core
    const catImage = ecs.ContainerImage.fromAsset(path.resolve(__dirname, 'core'));

    const cheshireCat = new CdkCheshireCat(this, 'CheshireCat', {
      customQdrantContainerImage: qdrantImage,
      customCatContainerImage: catImage,
      // Disable catPluginFolderInEFS to include local plugins
      catPluginFolderInEFS: false
    });

    new CfnOutput(this, "CatHost", {
      value: cheshireCat.catEcsCluster.fargateService.loadBalancer.loadBalancerDnsName,
    });
    new CfnOutput(this, "QdrantHost", {
      value: cheshireCat.qdrantEcsCluster.fargateService.loadBalancer.loadBalancerDnsName,
    });
  }
}

const app = new cdk.App();
new CustomCatImage(app, 'custom-cat-image');

Secure Cat

To run a Cheshire Cat ready for production you definitely need to secure both the cat and the qdrant server by setting api keys. You can set the Cheshire Cat and Qdrant Server api keys by passing the AWS Secrects to the cdk construct.

import { CfnOutput, Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { CdkCheshireCat } from 'cdk-cheshire-cat';
import * as cdk from 'aws-cdk-lib'
import * as sm from 'aws-cdk-lib/aws-secretsmanager';

export class SecureCat extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const catApiKeySecret = new sm.Secret(this, 'CatApiKey', {
      secretName: 'cat-api-key'
    });
    const qdrantApiKeySecret = new sm.Secret(this, 'QdrantApiKey', {
      secretName: 'qdrant-api-key'
    });

    const cheshireCat = new CdkCheshireCat(this, 'CheshireCat', {
      catApiKeySecret,
      qdrantApiKeySecret,
    });

    new CfnOutput(this, "CatHost", {
      value: cheshireCat.catEcsCluster.fargateService.loadBalancer.loadBalancerDnsName,
    });
    new CfnOutput(this, "QdrantHost", {
      value: cheshireCat.qdrantEcsCluster.fargateService.loadBalancer.loadBalancerDnsName,
    });
  }
}

const app = new cdk.App();
new SecureCat(app, 'secure');

In this example, the api key values will be automatically generated by cdk at the first deployment and will be inserted into the AWS Secrets.

1705925803352

If you want to set a custom values for the api keys you can create manually the AWS Secrets and then import it in the cdk stack

import { CfnOutput, Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { CdkCheshireCat } from 'cdk-cheshire-cat';
import * as cdk from 'aws-cdk-lib'
import * as sm from 'aws-cdk-lib/aws-secretsmanager';

export class SecureCat extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const catApiKeySecret = sm.Secret.fromSecretCompleteArn(this, 'CatApiKey', "arn:aws:secretsmanager:<Region>:<AccountId>:secret:SecretName-6RandomCharacters");
    const qdrantApiKeySecret = sm.Secret.fromSecretCompleteArn(this, 'QdrantApiKey', "arn:aws:secretsmanager:<Region>:<AccountId>:secret:SecretName-6RandomCharacters");

    const cheshireCat = new CdkCheshireCat(this, 'CheshireCat', {
      catApiKeySecret,
      qdrantApiKeySecret,
    });

    new CfnOutput(this, "CatHost", {
      value: cheshireCat.catEcsCluster.fargateService.loadBalancer.loadBalancerDnsName,
    });
    new CfnOutput(this, "QdrantHost", {
      value: cheshireCat.qdrantEcsCluster.fargateService.loadBalancer.loadBalancerDnsName,
    });
  }
}

const app = new cdk.App();
new SecureCat(app, 'secure');

Domain Cat

To run a Cheshire Cat under a custom domain to have SSL protection, you can implement the following example.

To set up this example, keep these considerations in mind:

  • The domain specified in the cat configuration must be hosted on Route 53
  • You must specify in the cdk stack instance the id of the deployment destination account and the region where the domain certificate is also located
import * as cdk from 'aws-cdk-lib';
import { DomainCat } from './stack';
import { CfnOutput, Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { CdkCheshireCat } from 'cdk-cheshire-cat';

export class DomainCat extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const cheshireCat = new CdkCheshireCat(this, 'CheshireCat', {
      domainProps: {
        catDomainProps: {
          domainName: 'example.com',
          subDomain: 'cat'
        },
        qdrantDomainProps: {
          domainName: 'example.com',
          subDomain: 'qdrant'
        }
      }
    });

    new CfnOutput(this, "CatHost", {
      value: cheshireCat.domain?.catDomain.domainName ?? cheshireCat.catEcsCluster.fargateService.loadBalancer.loadBalancerDnsName,
    });
    new CfnOutput(this, "QdrantHost", {
      value: cheshireCat.domain?.qdrantDomain.domainName ?? cheshireCat.qdrantEcsCluster.fargateService.loadBalancer.loadBalancerDnsName,
    });
  }
}

const app = new cdk.App();
new DomainCat(app, 'domain-cat', { env: { account: '000000000000', region: 'eu-central-1' } });

if you want to use a domain not hosted in route53 you will have to manually create the certificate and import it into the stack in this way:

import * as cdk from 'aws-cdk-lib';
import { DomainCat } from './stack';
import { CfnOutput, Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { CdkCheshireCat } from 'cdk-cheshire-cat';
import * as cm from 'aws-cdk-lib/aws-certificatemanager'

export class DomainCat extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const domainCert = cm.Certificate.fromCertificateArn(this, 'Certificate', 'arn:aws:acm:region:account:certificate/certificate_ID');

    const cheshireCat = new CdkCheshireCat(this, 'CheshireCat', {
      domainProps: {
        catDomainProps: {
          certificate: domainCert,
          domainName: 'lucapirrone.com',
          subDomain: 'cat'
        },
        qdrantDomainProps: {
          certificate: domainCert,
          domainName: 'lucapirrone.com',
          subDomain: 'qdrant'
        }
      }
    });

    new CfnOutput(this, "CatHost", {
      value: cheshireCat.domain?.catDomain.domainName ?? cheshireCat.catEcsCluster.fargateService.loadBalancer.loadBalancerDnsName,
    });
    new CfnOutput(this, "QdrantHost", {
      value: cheshireCat.domain?.qdrantDomain.domainName ?? cheshireCat.qdrantEcsCluster.fargateService.loadBalancer.loadBalancerDnsName,
    });
  }
}

const app = new cdk.App();
new DomainCat(app, 'domain-cat', { env: { account: '000000000000', region: 'eu-central-1' } });

See these example CDK apps here.

Way of Work

Release once and install plugins manually

By default the EFS is mounted in the folder containing the cat's plugins in order to make them persistent. If you want to manually load the plugins from the cat's admin panel, just release CdkCheshireCat with the default configuration:

import { CfnOutput, Stack, StackProps, App } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { CdkCheshireCat } from 'cdk-cheshire-cat';

export class DefaultCat extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const cheshireCat = new CdkCheshireCat(this, 'CheshireCat');

    new CfnOutput(this, "CatHost", {
      value: cheshireCat.catEcsCluster.fargateService.loadBalancer.loadBalancerDnsName,
    });
    new CfnOutput(this, "QdrantHost", {
      value: cheshireCat.qdrantEcsCluster.fargateService.loadBalancer.loadBalancerDnsName,
    });
  }
}

const app = new App();
new DefaultCat(app, 'default');

Upload plugin admin

The plugins will be persisted even if the cluster service tasks are restarted.

Keep plugins in the codebase

If you want to keep your plugins within your codebase and deploy them along with the cat then you can use this setup:

CAUTION Plugins loaded manually from the cat's admin panel WILL NOT BE PERSISTED.

import { CfnOutput, Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { CdkCheshireCat } from 'cdk-cheshire-cat';
import * as ecs from 'aws-cdk-lib/aws-ecs'
import * as cdk from 'aws-cdk-lib'
import * as path from 'path'

export class CustomCatImage extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);
  
    const qdrantImage = ecs.ContainerImage.fromRegistry('qdrant/qdrant:v1.7.2');
    // You have to link the Dockerfile folder, for example ./core with local custom plugins installed
    const catImage = ecs.ContainerImage.fromAsset(path.resolve(__dirname, 'core'));

    const cheshireCat = new CdkCheshireCat(this, 'CheshireCat', {
      customQdrantContainerImage: qdrantImage,
      customCatContainerImage: catImage
      // Disable catPluginFolderInEFS to include local plugins
      catPluginFolderInEFS: false
    });

    new CfnOutput(this, "CatHost", {
      value: cheshireCat.catEcsCluster.fargateService.loadBalancer.loadBalancerDnsName,
    });
    new CfnOutput(this, "QdrantHost", {
      value: cheshireCat.qdrantEcsCluster.fargateService.loadBalancer.loadBalancerDnsName,
    });
  }
}

const app = new cdk.App();
new CustomCatImage(app, 'custom-cat-image');

After deployment you will have to manually enable the plugins from the cat admin panel:

Upload plugin admin

The plugin will be persisted even if the cluster service tasks are restarted. However, plugins loaded manually from the cat's admin panel WILL NOT BE PERSISTED.