|
| 1 | + |
| 2 | +# Hosting Langfuse V3 on Amazon ECS with Fargate using CDK Python |
| 3 | + |
| 4 | +This repository contains the AWS CDK Python code for deploying the [Langfuse](https://langfuse.com/) application using Amazon Elastic Container Registry (ECR) and Amazon Elastic Container Service (ECS). |
| 5 | + |
| 6 | +Langfuse is an open-source LLM engineering platform that helps teams collaboratively debug, analyze, and iterate on their LLM applications. |
| 7 | + |
| 8 | + |
| 9 | +> :information_source: For more information on Langfuse's architecture, please check [the official documentation](https://langfuse.com/self-hosting#architecture) |
| 10 | +
|
| 11 | +The `cdk.json` file tells the CDK Toolkit how to execute your app. |
| 12 | + |
| 13 | +This project is set up like a standard Python project. The initialization |
| 14 | +process also creates a virtualenv within this project, stored under the `.venv` |
| 15 | +directory. To create the virtualenv it assumes that there is a `python3` |
| 16 | +(or `python` for Windows) executable in your path with access to the `venv` |
| 17 | +package. If for any reason the automatic creation of the virtualenv fails, |
| 18 | +you can create the virtualenv manually. |
| 19 | + |
| 20 | +To manually create a virtualenv on MacOS and Linux: |
| 21 | + |
| 22 | +``` |
| 23 | +$ git clone --depth=1 https://github.com/aws-samples/deploy-langfuse-on-ecs-with-fargate.git |
| 24 | +$ cd deploy-langfuse-on-ecs-with-fargate |
| 25 | +$ git sparse-checkout init --cone |
| 26 | +$ git sparse-checkout set langfuse-v3 |
| 27 | +$ cd langfuse-v3 |
| 28 | +
|
| 29 | +$ python3 -m venv .venv |
| 30 | +``` |
| 31 | + |
| 32 | +After the init process completes and the virtualenv is created, you can use the following |
| 33 | +step to activate your virtualenv. |
| 34 | + |
| 35 | +``` |
| 36 | +$ source .venv/bin/activate |
| 37 | +``` |
| 38 | + |
| 39 | +If you are a Windows platform, you would activate the virtualenv like this: |
| 40 | + |
| 41 | +``` |
| 42 | +% .venv\Scripts\activate.bat |
| 43 | +``` |
| 44 | + |
| 45 | +Once the virtualenv is activated, you can install the required dependencies. |
| 46 | + |
| 47 | +``` |
| 48 | +(.venv) $ pip install -r requirements.txt |
| 49 | +``` |
| 50 | +> To add additional dependencies, for example other CDK libraries, just add |
| 51 | +them to your `setup.py` file and rerun the `pip install -r requirements.txt` |
| 52 | +command. |
| 53 | + |
| 54 | +## Prerequisites |
| 55 | + |
| 56 | +**Set up `cdk.context.json`** |
| 57 | + |
| 58 | +Then, we need to set approperly the cdk context configuration file, `cdk.context.json`. |
| 59 | + |
| 60 | +For example, |
| 61 | + |
| 62 | +``` |
| 63 | +{ |
| 64 | + "private_dns_namespace_name": "langfuse.local", |
| 65 | + "db_cluster_name": "langfuse-db", |
| 66 | + "ecr": [ |
| 67 | + { |
| 68 | + "repository_name": "langfuse-web", |
| 69 | + "docker_image_name": "langfuse/langfuse", |
| 70 | + "tag": "3" |
| 71 | + }, |
| 72 | + { |
| 73 | + "repository_name": "langfuse-worker", |
| 74 | + "docker_image_name": "langfuse/langfuse-worker", |
| 75 | + "tag": "3" |
| 76 | + }, |
| 77 | + { |
| 78 | + "repository_name": "clickhouse", |
| 79 | + "docker_image_name": "clickhouse", |
| 80 | + "tag": "24.12.3.47" |
| 81 | + } |
| 82 | + ], |
| 83 | + "ecs_cluster_name": "langfuse", |
| 84 | + "langfuse_worker_desired_count": 1, |
| 85 | + "langfuse_worker_env": { |
| 86 | + "NODE_ENV": "production", |
| 87 | + "SALT": "salt (generate by running 'openssl rand -base64 32')", |
| 88 | + "ENCRYPTION_KEY": "encryption key (generate by running 'openssl rand -hex 32')", |
| 89 | + "TELEMETRY_ENABLED": "true", |
| 90 | + "LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES": "true" |
| 91 | + }, |
| 92 | + "langfuse_web_env": { |
| 93 | + "NODE_ENV": "production", |
| 94 | + "NEXTAUTH_SECRET": "secret (generate by running 'openssl rand -base64 32')", |
| 95 | + "SALT": "salt (generate by running 'openssl rand -base64 32')", |
| 96 | + "ENCRYPTION_KEY": "encryption key (generate by running 'openssl rand -hex 32')", |
| 97 | + "HOSTNAME": "0.0.0.0", |
| 98 | + "LANGFUSE_S3_MEDIA_DOWNLOAD_URL_EXPIRY_SECONDS": "604800", |
| 99 | + "TELEMETRY_ENABLED": "true", |
| 100 | + "LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES": "true", |
| 101 | + "LANGFUSE_SDK_CI_SYNC_PROCESSING_ENABLED": "false", |
| 102 | + "LANGFUSE_READ_FROM_POSTGRES_ONLY": "false", |
| 103 | + "LANGFUSE_READ_FROM_CLICKHOUSE_ONLY": "true", |
| 104 | + "LANGFUSE_RETURN_FROM_CLICKHOUSE": "true" |
| 105 | + } |
| 106 | +} |
| 107 | +``` |
| 108 | + |
| 109 | +:information_source: This guide covers Langfuse v3. The docker image version (`tag`) of `langfuse-web` and `langfuse-worker` should be set to `3`. |
| 110 | + |
| 111 | +:information_source: For more details on environment variables for the Langfuse Web (`langfuse_web_env`) and Langfuse Worker (`langfuse_worker_env`) containers, please refer to the [official configuration guide](https://langfuse.com/self-hosting/configuration#environment-variables). |
| 112 | + |
| 113 | +**Bootstrap AWS environment for AWS CDK app** |
| 114 | + |
| 115 | +Also, before any AWS CDK app can be deployed, you have to bootstrap your AWS environment to create certain AWS resources that the AWS CDK CLI (Command Line Interface) uses to deploy your AWS CDK app. |
| 116 | + |
| 117 | +Run the `cdk bootstrap` command to bootstrap the AWS environment. |
| 118 | + |
| 119 | +``` |
| 120 | +(.venv) $ cdk bootstrap |
| 121 | +``` |
| 122 | + |
| 123 | +### Deploy |
| 124 | + |
| 125 | +At this point you can now synthesize the CloudFormation template for this code. |
| 126 | + |
| 127 | +``` |
| 128 | +(.venv) $ export CDK_DEFAULT_ACCOUNT=$(aws sts get-caller-identity --query Account --output text) |
| 129 | +(.venv) $ export CDK_DEFAULT_REGION=$(aws configure get region) |
| 130 | +(.venv) $ cdk synth --all |
| 131 | +``` |
| 132 | + |
| 133 | +Use `cdk deploy` command to create the stack shown above. |
| 134 | + |
| 135 | +``` |
| 136 | +(.venv) $ cdk deploy --require-approval never --all |
| 137 | +``` |
| 138 | + |
| 139 | +We can list all the CDK stacks by using the `cdk list` command prior to deployment. |
| 140 | + |
| 141 | +``` |
| 142 | +(.venv) $ cdk list |
| 143 | +LangfuseECRStack |
| 144 | +LangfuseVpcStack |
| 145 | +LangfuseWebALBStack |
| 146 | +LangfuseCacheStack |
| 147 | +LangfuseAuroraPostgreSQLStack |
| 148 | +LangfuseS3BucketStack |
| 149 | +LangfuseServiceDiscoveryStack |
| 150 | +LangfuseECSClusterStack |
| 151 | +LangfuseClickhouseEFSStack |
| 152 | +LangfuseClickhouseECSTaskStack |
| 153 | +LangfuseClickhouseECSServiceStack |
| 154 | +LangfuseWorkerECSTaskStack |
| 155 | +LangfuseWorkerECSServiceStack |
| 156 | +LangfuseWebECSTaskStack |
| 157 | +LangfuseWebECSServiceStack |
| 158 | +``` |
| 159 | + |
| 160 | +## Clean Up |
| 161 | + |
| 162 | +Delete the CloudFormation stack by running the below command. |
| 163 | + |
| 164 | +``` |
| 165 | +(.venv) $ cdk destroy --force --all |
| 166 | +``` |
| 167 | + |
| 168 | +## Useful commands |
| 169 | + |
| 170 | + * `cdk ls` list all stacks in the app |
| 171 | + * `cdk synth` emits the synthesized CloudFormation template |
| 172 | + * `cdk deploy` deploy this stack to your default AWS account/region |
| 173 | + * `cdk diff` compare deployed stack with current state |
| 174 | + * `cdk docs` open CDK documentation |
| 175 | + |
| 176 | +Enjoy! |
| 177 | + |
| 178 | +## Tracing for your LLM Application with Langfuse |
| 179 | + |
| 180 | +After deploying all CDK stacks, you can find the **Langfuse URL** using the following command: |
| 181 | + |
| 182 | +```bash |
| 183 | +aws cloudformation describe-stacks --stack-name LangfuseWebECSServiceStack --region ${CDK_DEFAULT_REGION} | \ |
| 184 | + jq -r '.Stacks[0].Outputs | map(select(.OutputKey == "LoadBalancerDNS")) | .[0].OutputValue' |
| 185 | +``` |
| 186 | + |
| 187 | +Next, open the **Langfuse URL** in your browser to create a new project for tracking your LLM application with Langfuse. |
| 188 | + |
| 189 | +### Create a New Project in Langfuse |
| 190 | + |
| 191 | +1. Create a Langfuse Account |
| 192 | + |
| 193 | +  |
| 194 | + |
| 195 | +  |
| 196 | +2. Create a New Project |
| 197 | +  |
| 198 | +3. Create New API Credentials in the Project Settings |
| 199 | +  |
| 200 | + |
| 201 | +### Log Your First LLM Call to Langfuse |
| 202 | + |
| 203 | +Open the `tracing_for_langchain_bedrock` notebook in the `examples` folder and run it. (See [here](./examples/tracing_for_langchain_bedrock.ipynb) for more information) |
| 204 | + |
| 205 | +You will the see the list of traces as follows: |
| 206 | + |
| 207 | + |
| 208 | +You will also see the details of the selected trace as follows: |
| 209 | + |
| 210 | + |
| 211 | + |
| 212 | +## References |
| 213 | + |
| 214 | +#### General |
| 215 | + |
| 216 | + * [(Official) Self-host Langfuse](https://langfuse.com/self-hosting) |
| 217 | + * [(Official) Langfuse configuration guide](https://langfuse.com/self-hosting/configuration) |
| 218 | + * [(GitHub) langfuse](https://github.com/langfuse/langfuse/) |
| 219 | + * [(GitHub) Langfuse v3 Terraform Module Sample](https://github.com/tubone24/langfuse-v3-terraform/) |
| 220 | + * [AWS CDK Reference Documentation](https://docs.aws.amazon.com/cdk/api/v2/) |
| 221 | + * [cdk-ecr-deployment](https://github.com/cdklabs/cdk-ecr-deployment) - A CDK construct to deploy docker image to Amazon ECR. |
| 222 | + * [Terraform - AWS Provider Docs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs) |
| 223 | + |
| 224 | +#### Langfuse User Guide |
| 225 | + |
| 226 | + * [Get Started with Langfuse Tracing](https://langfuse.com/docs/get-started) |
| 227 | + * [Observability & Tracing for Langchain (Python & JS/TS)](https://langfuse.com/docs/integrations/langchain/tracing) |
| 228 | + |
| 229 | +#### Amazon ElastiCache |
| 230 | + |
| 231 | + * [Amazon ElastiCache Supported node types](https://docs.aws.amazon.com/AmazonElastiCache/latest/dg/CacheNodes.SupportedTypes.html#CacheNodes.CurrentGen) |
| 232 | + * [Amazon ElastiCache Supported engines and versions](https://docs.aws.amazon.com/AmazonElastiCache/latest/dg/supported-engine-versions.html) |
| 233 | + * [Comparing Valkey, Memcached, and Redis OSS self-designed caches](https://docs.aws.amazon.com/AmazonElastiCache/latest/dg/SelectEngine.html) |
| 234 | + |
| 235 | +#### Amazon Aurora PostgreSQL |
| 236 | + |
| 237 | + * [Working with Amazon Aurora PostgreSQL](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Aurora.AuroraPostgreSQL.html) |
| 238 | + |
| 239 | +#### Clickhouse |
| 240 | + |
| 241 | + * [Clickhouse for self-hosting Langfuse v3](https://langfuse.com/self-hosting/infrastructure/clickhouse) |
| 242 | + * [(DockerHub) Clickhouse Docker Official Image](https://hub.docker.com/_/clickhouse) |
| 243 | + * [Clickhouse CLI](https://clickhouse.com/docs/en/integrations/sql-clients/clickhouse-client-local) |
| 244 | + |
| 245 | +## Security |
| 246 | + |
| 247 | +See [CONTRIBUTING](../CONTRIBUTING.md#security-issue-notifications) for more information. |
| 248 | + |
| 249 | +## License |
| 250 | + |
| 251 | +This library is licensed under the MIT-0 License. See the LICENSE file. |
0 commit comments