## Prerequisites
- [Docker](https://www.docker.com/get-started)
- [Visual Studio Code](https://code.visualstudio.com/)
- [Remote - Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) VS Code extension
## Features
- **Base Image**: Built on `mcr.microsoft.com/devcontainers/javascript-node:1-18-bookworm`, thus Node.JS LTS v18.
- **Additional Tools**: Includes `hadolint`, and essential apt-packages such as `curl`, `gnupg`, and more.
- **Ports**: Configured to auto-forward ports `3000` (Frontend) and `3001` (Backend).
- **Environment Variables**: Sets `NODE_ENV` to `development` and `ESLINT_USE_FLAT_CONFIG` to `true`.
- **VS Code Extensions**: A suite of extensions such as `Prettier`, `Docker`, `ESLint`, and more are automatically installed. Please revise if you do not agree with any of these extensions. AI-powered extensions and time trackers are (for now) not included to avoid any privacy concerns, but you can install them later in your own environment.
## Getting Started
1. Using GitHub Codespaces. Just select to create a new workspace, and the devcontainer will be created for you.
2. Using your Local VSCode (Release or Insiders). We suggest you first make a fork of the repo and then clone it to your local machine using VSCode tools. Then open the project folder in VSCode, which will prompt you to open the project in a devcontainer. Select yes, and the devcontainer will be created for you. If this does not happen, you can open the command palette and select "Remote-Containers: Reopen in Container".
## On Creation:
When the container is built for the first time, it will automatically run `yarn setup` to ensure everything is in place for the Collector, Server and Frontend. This command is expected to be automatically re-run if there is a content change on next reboot.
## Work in the Container:
Once the container is up, be patient. Some extensions may complain because dependencies are still being installed, and in the Extensions tab, some may ask you to "Reload" the project. Don't do that yet. First, wait until all settle down for the first time. We suggest you create a new VSCode profile for this devcontainer, so any configuration and extensions you change, won't affect your default profile.
Checklist:
- [ ] The usual message asking you to start the Server and Frontend in different windows are now "hidden" in the building process of the devcontainer. Don't forget to do as suggested.
- [ ] Open a JavaScript file, for example "server/index.js" and check if `eslint` is working. It will complain that `'err' is defined but never used.`. This means it is working.
- [ ] Open a React File, for example, "frontend/src/main.jsx," and check if `eslint` complains about `Fast refresh only works when a file has exports. Move your component(s) to a separate file.`. Again, it means `eslint` is working. Now check at the status bar if the `Prettier` has a double checkmark :heavy_check_mark: (double). It means Prettier is working. You will see a nice extension `Formatting:`:heavy_check_mark: that can be used to disable the `Format on Save` feature temporarily.
- [ ] Check if, on the left pane, you have the NPM Scripts (this may be disabled; look at the "Explorer" tree-dots up-right). There will be scripts inside the `package.json` files. You will basically need to run the `dev:collector`, `dev:server` and the `dev:frontend` in this order. When the frontend finishes starting, a window browser will open **inside** the VSCode. Still, you can open it outside.
:warning: **Important for all developers** :warning:
- [ ] When you are using the `NODE_ENV=development` the server will not store the configurations you set for security reasons. Please set the proper config on file `.env.development`. The side-effect if you don't, everytime you restart the server, you will be sent to the "Onboarding" page again.
**Note when using GitHub Codespaces**
- [ ] When running the "Server" for the first time, it will automatically configure its port to be publicly accessible by default, as this is required for the front end to reach the server backend. To know more, read the content of the `.env` file on the frontend folder about this, and if any issues occur, make sure to manually set the port "Visibility" of the "Server" is set to "Public" if needed. Again, this is only needed for developing on GitHub Codespaces.
**For the Collector:**
- [x] In the past, the Collector dwelled within the Python domain, but now it has journeyed to the splendid realm of Node.JS. Consequently, the configuration complexities of bygone versions are no longer a concern.
### Now it is ready to start
In the status bar you will see three shortcuts names `Collector`, `Server` and `Frontend`. Just click-and-wait on that order (don't forget to set the Server port 3001 to Public if you are using GH Codespaces **_before_** starting the Frontend).
Now you can enjoy your time developing instead of reconfiguring everything.
## Debugging with the devcontainers
### For debugging the collector, server and frontend
First, make sure the built-in extension (ms-vscode.js-debug) is active (I don't know why it would not be, but just in case). If you want, you can install the nightly version (ms-vscode.js-debug-nightly)
Then, in the "Run and Debug" tab (Ctrl+shift+D), you can select on the menu:
- Collector debug. This will start the collector in debug mode and attach the debugger. Works very well.
- Server debug. This will start the server in debug mode and attach the debugger. Works very well.
- Frontend debug. This will start the frontend in debug mode and attach the debugger. I am still struggling with this one. I don't know if VSCode can handle the .jsx files seamlessly as the pure .js on the server. Maybe there is a need for a particular configuration for Vite or React. Anyway, it starts. Another two configurations launch Chrome and Edge, and I think we could add breakpoints on .jsx files somehow. The best scenario would be always to use the embedded browser. WIP.
Please leave comments on the Issues tab or the []("https://discord.gg/6UyHPeGZAC")
================================================
FILE: .devcontainer/devcontainer.json
================================================
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/javascript-node
{
"name": "Node.js",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
// "build": {
// "args": {
// "ARG_UID": "1000",
// "ARG_GID": "1000"
// },
// "dockerfile": "Dockerfile"
// },
// "containerUser": "anythingllm",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/javascript-node:1-18-bookworm",
"forwardPorts": [3001, 3000],
// Features to add to the dev container. More info: https://containers.dev/features.
"features": {
// Docker very useful linter
"ghcr.io/dhoeric/features/hadolint:1": {
"version": "latest"
},
// Terraform support
"ghcr.io/devcontainers/features/terraform:1": {},
// Just a wrap to install needed packages
"ghcr.io/devcontainers-contrib/features/apt-packages:1": {
// Dependencies copied from ../docker/Dockerfile plus some dev stuff
"packages": [
"build-essential",
"ca-certificates",
"curl",
"ffmpeg",
"fonts-liberation",
"git",
"gnupg",
"htop",
"less",
"libappindicator1",
"libasound2",
"libatk-bridge2.0-0",
"libatk1.0-0",
"libc6",
"libcairo2",
"libcups2",
"libdbus-1-3",
"libexpat1",
"libfontconfig1",
"libgbm1",
"libgcc1",
"libgfortran5",
"libglib2.0-0",
"libgtk-3-0",
"libnspr4",
"libnss3",
"libpango-1.0-0",
"libpangocairo-1.0-0",
"libstdc++6",
"libx11-6",
"libx11-xcb1",
"libxcb1",
"libxcomposite1",
"libxcursor1",
"libxdamage1",
"libxext6",
"libxfixes3",
"libxi6",
"libxrandr2",
"libxrender1",
"libxss1",
"libxtst6",
"locales",
"lsb-release",
"procps",
"tzdata",
"wget",
"xdg-utils"
]
}
},
"updateContentCommand": "cd server && yarn && cd ../collector && PUPPETEER_DOWNLOAD_BASE_URL=https://storage.googleapis.com/chrome-for-testing-public yarn && cd ../frontend && yarn && cd .. && yarn setup:envs && yarn prisma:setup && echo \"Please run yarn dev:server, yarn dev:collector, and yarn dev:frontend in separate terminal tabs.\"",
// Use 'postCreateCommand' to run commands after the container is created.
// This configures VITE for github codespaces and installs gh cli
"postCreateCommand": "if [ \"${CODESPACES}\" = \"true\" ]; then echo 'VITE_API_BASE=\"https://$CODESPACE_NAME-3001.$GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN/api\"' > ./frontend/.env && (type -p wget >/dev/null || (sudo apt update && sudo apt-get install wget -y)) && sudo mkdir -p -m 755 /etc/apt/keyrings && wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null && sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg && echo \"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main\" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null && sudo apt update && sudo apt install gh -y; fi",
"portsAttributes": {
"3001": {
"label": "Backend",
"onAutoForward": "notify"
},
"3000": {
"label": "Frontend",
"onAutoForward": "openPreview"
}
},
"capAdd": [
"SYS_ADMIN" // needed for puppeteer using headless chrome in sandbox
],
"remoteEnv": {
"NODE_ENV": "development",
"ESLINT_USE_FLAT_CONFIG": "true",
"ANYTHING_LLM_RUNTIME": "docker"
},
// "initializeCommand": "echo Initialize....",
"shutdownAction": "stopContainer",
// Configure tool-specific properties.
"customizations": {
"codespaces": {
"openFiles": [
"README.md",
".devcontainer/README.md"
]
},
"vscode": {
"openFiles": [
"README.md",
".devcontainer/README.md"
],
"extensions": [
"bierner.github-markdown-preview",
"bradlc.vscode-tailwindcss",
"dbaeumer.vscode-eslint",
"editorconfig.editorconfig",
"esbenp.prettier-vscode",
"exiasr.hadolint",
"flowtype.flow-for-vscode",
"gamunu.vscode-yarn",
"hashicorp.terraform",
"mariusschulz.yarn-lock-syntax",
"ms-azuretools.vscode-docker",
"streetsidesoftware.code-spell-checker",
"actboy168.tasks",
"tombonnike.vscode-status-bar-format-toggle",
"ms-vscode.js-debug"
],
"settings": {
"[css]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[dockercompose]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[dockerfile]": {
"editor.defaultFormatter": "ms-azuretools.vscode-docker"
},
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[postcss]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[toml]": {
"editor.defaultFormatter": "tamasfe.even-better-toml"
},
"eslint.debug": true,
"eslint.enable": true,
"eslint.experimental.useFlatConfig": true,
"eslint.run": "onSave",
"files.associations": {
".*ignore": "ignore",
".editorconfig": "editorconfig",
".env*": "properties",
".flowconfig": "ini",
".prettierrc": "json",
"*.css": "tailwindcss",
"*.md": "markdown",
"*.sh": "shellscript",
"docker-compose.*": "dockercompose",
"Dockerfile*": "dockerfile",
"yarn.lock": "yarnlock"
},
"javascript.format.enable": false,
"javascript.inlayHints.enumMemberValues.enabled": true,
"javascript.inlayHints.functionLikeReturnTypes.enabled": true,
"javascript.inlayHints.parameterTypes.enabled": true,
"javascript.inlayHints.variableTypes.enabled": true,
"js/ts.implicitProjectConfig.module": "CommonJS",
"json.format.enable": false,
"json.schemaDownload.enable": true,
"npm.autoDetect": "on",
"npm.packageManager": "yarn",
"prettier.useEditorConfig": false,
"tailwindCSS.files.exclude": [
"**/.git/**",
"**/node_modules/**",
"**/.hg/**",
"**/.svn/**",
"**/dist/**"
],
"typescript.validate.enable": false,
"workbench.editorAssociations": {
"*.md": "vscode.markdown.preview.editor"
}
}
}
}
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}
================================================
FILE: .dockerignore
================================================
**/server/utils/agents/aibitat/example/**
**/server/storage/documents/**
**/server/storage/vector-cache/**
**/server/storage/*.db
**/server/storage/lancedb
**/collector/hotdir/**
**/collector/outputs/**
**/node_modules/
**/dist/
**/v-env/
**/__pycache__/
**/.env
**/.env.*
**/bundleinspector.html
**/tmp/**
**/.log
!docker/.env.example
!frontend/.env.production
================================================
FILE: .editorconfig
================================================
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
[*]
# Non-configurable Prettier behaviors
charset = utf-8
insert_final_newline = true
trim_trailing_whitespace = true
# Configurable Prettier behaviors
# (change these if your Prettier config differs)
end_of_line = lf
indent_style = space
indent_size = 2
max_line_length = 80
================================================
FILE: .gitattributes
================================================
* text=auto eol=lf
================================================
FILE: .github/FUNDING.yml
================================================
github: Mintplex-Labs
================================================
FILE: .github/ISSUE_TEMPLATE/01_bug.yml
================================================
name: 🐛 Bug Report
description: File a bug report for AnythingLLM
title: "[BUG]: "
labels: [possible bug]
body:
- type: markdown
attributes:
value: |
Use this template to file a bug report for AnythingLLM. Please be as descriptive as possible to allow everyone to replicate and solve your issue.
- type: dropdown
id: runtime
attributes:
label: How are you running AnythingLLM?
description: AnythingLLM can be run in many environments, pick the one that best represents where you encounter the bug.
options:
- Docker (local)
- Docker (remote machine)
- Local development
- AnythingLLM desktop app
- All versions
- Not listed
default: 0
validations:
required: true
- type: textarea
id: what-happened
attributes:
label: What happened?
description: Also tell us, what did you expect to happen?
validations:
required: true
- type: textarea
id: reproduction
attributes:
label: Are there known steps to reproduce?
description: |
Let us know how to reproduce the bug and we may be able to fix it more
quickly. This is not required, but it is helpful.
validations:
required: false
================================================
FILE: .github/ISSUE_TEMPLATE/02_feature.yml
================================================
name: ✨ New Feature suggestion
description: Suggest a new feature for AnythingLLM!
title: "[FEAT]: "
labels: [enhancement, feature request]
body:
- type: markdown
attributes:
value: |
Share a new idea for a feature or improvement. Be sure to search existing
issues first to avoid duplicates.
- type: textarea
id: description
attributes:
label: What would you like to see?
description: |
Describe the feature and why it would be useful to your use-case as well as others.
validations:
required: true
================================================
FILE: .github/ISSUE_TEMPLATE/03_documentation.yml
================================================
name: 📚 Documentation improvement
title: "[DOCS]: "
description: Report an issue or problem with the documentation.
labels: [documentation]
body:
- type: textarea
id: description
attributes:
label: Description
description: Describe the issue with the documentation that is giving you trouble or causing confusion.
validations:
required: true
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: true
contact_links:
- name: 🧑🤝🧑 Community Discord
url: https://discord.gg/6UyHPeGZAC
about: Interact with the Mintplex Labs community here by asking for help, discussing and more!
================================================
FILE: .github/workflows/build-and-push-image-semver.yaml
================================================
name: Publish AnythingLLM Docker image on Release (amd64 & arm64)
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
release:
types: [published]
jobs:
push_multi_platform_to_registries:
name: Push Docker multi-platform image to multiple registries
runs-on: ubuntu-22.04-arm
permissions:
packages: write
contents: read
steps:
- name: Check out the repo
uses: actions/checkout@v4
- name: Check if DockerHub build needed
shell: bash
run: |
# Check if the secret for USERNAME is set (don't even check for the password)
if [[ -z "${{ secrets.DOCKER_USERNAME }}" ]]; then
echo "DockerHub build not needed"
echo "enabled=false" >> $GITHUB_OUTPUT
else
echo "DockerHub build needed"
echo "enabled=true" >> $GITHUB_OUTPUT
fi
id: dockerhub
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
version: v0.22.0
- name: Log in to Docker Hub
uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a
# Only login to the Docker Hub if the repo is mintplex/anythingllm, to allow for forks to build on GHCR
if: steps.dockerhub.outputs.enabled == 'true'
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
with:
images: |
${{ steps.dockerhub.outputs.enabled == 'true' && 'mintplexlabs/anythingllm' || '' }}
ghcr.io/${{ github.repository }}
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
- name: Build and push multi-platform Docker image
uses: docker/build-push-action@v6
with:
context: .
file: ./docker/Dockerfile
push: true
sbom: true
provenance: mode=max
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
# For Docker scout there are some intermediary reported CVEs which exists outside
# of execution content or are unreachable by an attacker but exist in image.
# We create VEX files for these so they don't show in scout summary.
- name: Collect known and verified CVE exceptions
id: cve-list
run: |
# Collect CVEs from filenames in vex folder
CVE_NAMES=""
for file in ./docker/vex/*.vex.json; do
[ -e "$file" ] || continue
filename=$(basename "$file")
stripped_filename=${filename%.vex.json}
CVE_NAMES+=" $stripped_filename"
done
echo "CVE_EXCEPTIONS=$CVE_NAMES" >> $GITHUB_OUTPUT
shell: bash
# About VEX attestations https://docs.docker.com/scout/explore/exceptions/
# Justifications https://github.com/openvex/spec/blob/main/OPENVEX-SPEC.md#status-justifications
- name: Add VEX attestations
env:
CVE_EXCEPTIONS: ${{ steps.cve-list.outputs.CVE_EXCEPTIONS }}
run: |
echo $CVE_EXCEPTIONS
curl -sSfL https://raw.githubusercontent.com/docker/scout-cli/main/install.sh | sh -s --
for cve in $CVE_EXCEPTIONS; do
for tag in "${{ join(fromJSON(steps.meta.outputs.json).tags, ' ') }}"; do
echo "Attaching VEX exception $cve to $tag"
docker scout attestation add \
--file "./docker/vex/$cve.vex.json" \
--predicate-type https://openvex.dev/ns/v0.2.0 \
$tag
done
done
shell: bash
================================================
FILE: .github/workflows/build-and-push-image.yaml
================================================
# This GitHub action is for publishing of the primary image for AnythingLLM
# It will publish a linux/amd64 and linux/arm64 image at the same time
# This file should ONLY BY USED FOR `master` BRANCH.
# TODO: GitHub now has an ubuntu-24.04-arm64 runner, but we still need
# to use QEMU to build the arm64 image because Chromium is not available for Linux arm64
# so builds will still fail, or fail much more often. Its inconsistent and frustrating.
name: Publish AnythingLLM Primary Docker image (amd64/arm64)
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
push:
branches: ['master'] # master branch only. Do not modify.
paths-ignore:
- '**.md'
- '.gitmodules'
- 'cloud-deployments/**/*'
- 'images/**/*'
- '.vscode/**/*'
- '**/.env.example'
- '.github/ISSUE_TEMPLATE/**/*'
- '.devcontainer/**/*'
- 'embed/**/*' # Embed is submodule
- 'browser-extension/**/*' # Chrome extension is submodule
- 'server/utils/agents/aibitat/example/**/*' # Do not push new image for local dev testing of new aibitat images.
- 'extras/**/*' # Extra is just for news and other local content.
jobs:
push_multi_platform_to_registries:
name: Push Docker multi-platform image to multiple registries
runs-on: ubuntu-22.04-arm
permissions:
packages: write
contents: read
steps:
- name: Check out the repo
uses: actions/checkout@v4
- name: Check if DockerHub build needed
shell: bash
run: |
# Check if the secret for USERNAME is set (don't even check for the password)
if [[ -z "${{ secrets.DOCKER_USERNAME }}" ]]; then
echo "DockerHub build not needed"
echo "enabled=false" >> $GITHUB_OUTPUT
else
echo "DockerHub build needed"
echo "enabled=true" >> $GITHUB_OUTPUT
fi
id: dockerhub
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
version: v0.22.0
- name: Log in to Docker Hub
uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a
# Only login to the Docker Hub if the repo is mintplex/anythingllm, to allow for forks to build on GHCR
if: steps.dockerhub.outputs.enabled == 'true'
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
with:
images: |
${{ steps.dockerhub.outputs.enabled == 'true' && 'mintplexlabs/anythingllm' || '' }}
ghcr.io/${{ github.repository }}
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=ref,event=branch
type=ref,event=tag
type=ref,event=pr
- name: Build and push multi-platform Docker image
uses: docker/build-push-action@v6
with:
context: .
file: ./docker/Dockerfile
push: true
sbom: true
provenance: mode=max
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
# For Docker scout there are some intermediary reported CVEs which exists outside
# of execution content or are unreachable by an attacker but exist in image.
# We create VEX files for these so they don't show in scout summary.
- name: Collect known and verified CVE exceptions
id: cve-list
run: |
# Collect CVEs from filenames in vex folder
CVE_NAMES=""
for file in ./docker/vex/*.vex.json; do
[ -e "$file" ] || continue
filename=$(basename "$file")
stripped_filename=${filename%.vex.json}
CVE_NAMES+=" $stripped_filename"
done
echo "CVE_EXCEPTIONS=$CVE_NAMES" >> $GITHUB_OUTPUT
shell: bash
# About VEX attestations https://docs.docker.com/scout/explore/exceptions/
# Justifications https://github.com/openvex/spec/blob/main/OPENVEX-SPEC.md#status-justifications
- name: Add VEX attestations
env:
CVE_EXCEPTIONS: ${{ steps.cve-list.outputs.CVE_EXCEPTIONS }}
run: |
echo $CVE_EXCEPTIONS
curl -sSfL https://raw.githubusercontent.com/docker/scout-cli/main/install.sh | sh -s --
for cve in $CVE_EXCEPTIONS; do
for tag in "${{ join(fromJSON(steps.meta.outputs.json).tags, ' ') }}"; do
echo "Attaching VEX exception $cve to $tag"
docker scout attestation add \
--file "./docker/vex/$cve.vex.json" \
--predicate-type https://openvex.dev/ns/v0.2.0 \
$tag
done
done
shell: bash
================================================
FILE: .github/workflows/build-qa-tag.yaml
================================================
# Builds a QA GHCR image for a PR when the "PR: Ready for QA" label is present.
# Triggers on:
# - "PR: Ready for QA" label added to a PR
# - New commits pushed to a PR that already has the label will trigger a new build
name: Build QA GHCR Image
on:
pull_request:
types: [labeled, synchronize]
paths-ignore:
- "**.md"
- ".gitmodules"
- "cloud-deployments/**/*"
- "images/**/*"
- ".vscode/**/*"
- "**/.env.example"
- ".github/ISSUE_TEMPLATE/**/*"
- ".devcontainer/**/*"
- "embed/**/*"
- "browser-extension/**/*"
- "extras/**/*"
concurrency:
group: qa-build-pr-${{ github.event.pull_request.number }}
cancel-in-progress: true
jobs:
build:
name: Build and push QA image for PR
runs-on: ubuntu-22.04-arm
# Run when labeled with "PR: Ready for QA"
if: >-
${{ contains(github.event.pull_request.labels.*.name, 'PR: Ready for QA') }}
permissions:
packages: write
contents: read
pull-requests: write
steps:
- name: Check out the repo
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
version: v0.22.0
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set lowercase repository owner
run: echo "REPO_OWNER_LC=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
file: ./docker/Dockerfile
push: true
sbom: true
provenance: mode=max
platforms: linux/arm64
tags: ghcr.io/${{ env.REPO_OWNER_LC }}/${{ github.event.repository.name }}:pr-${{ github.event.pull_request.number }}
cache-from: type=gha
cache-to: type=gha,mode=max
================================================
FILE: .github/workflows/check-package-versions.yaml
================================================
# This GitHub action is for checking the versions of the packages in the project.
# Any package that is present in both the `server` and `collector` package.json file
# is checked to ensure that they are the same version.
name: Check package versions
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
pull_request:
types: [opened, synchronize, reopened]
paths:
- "server/package.json"
- "collector/package.json"
jobs:
run-script:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Run verifyPackageVersions.mjs script
run: |
cd extras/scripts
node verifyPackageVersions.mjs
- name: Fail job on error
if: failure()
run: exit 1
================================================
FILE: .github/workflows/check-translations.yaml
================================================
# This GitHub action is for validation of all languages which translations are offered for
# in the locales folder in `frontend/src`. All languages are compared to the EN translation
# schema since that is the fallback language setting. This workflow will run on all PRs that
# modify any files in the translation directory
name: Verify translations files
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
pull_request:
types: [opened, synchronize, reopened]
paths:
- "frontend/src/locales/**.js"
jobs:
run-script:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Run verifyTranslations.mjs script
run: |
cd frontend/src/locales
node verifyTranslations.mjs
- name: Fail job on error
if: failure()
run: exit 1
================================================
FILE: .github/workflows/cleanup-qa-tag.yaml
================================================
# Cleans up the GHCR image tag when the PR is closed or the "PR: Ready for QA" label is removed.
name: Cleanup QA GHCR Image
on:
pull_request:
types: [closed, unlabeled]
workflow_dispatch:
inputs:
pr_number:
description: 'PR number to clean up (e.g., 123)'
required: true
jobs:
cleanup-manual:
name: Delete QA GHCR image tag (manual)
runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch'
permissions:
packages: write
steps:
- name: Delete PR tag from GHCR
env:
GH_TOKEN: ${{ secrets.ALLM_RW_PACKAGES }}
PR_NUMBER: ${{ inputs.pr_number }}
run: |
# Must use lowercase - packages are published with lowercase owner
ORG_LC="${GITHUB_REPOSITORY_OWNER,,}"
REPO_LC="${GITHUB_REPOSITORY#*/}"
REPO_LC="${REPO_LC,,}"
echo "Looking for tag: pr-${PR_NUMBER}"
echo "Package: /orgs/${ORG_LC}/packages/container/${REPO_LC}/versions"
VERSION_ID=$(gh api \
-H "Accept: application/vnd.github+json" \
--paginate \
"/orgs/${ORG_LC}/packages/container/${REPO_LC}/versions" \
--jq ".[] | select(.metadata.container.tags[] == \"pr-${PR_NUMBER}\") | .id")
if [ -n "$VERSION_ID" ]; then
echo "Deleting package version $VERSION_ID (tag: pr-${PR_NUMBER})"
gh api \
--method DELETE \
-H "Accept: application/vnd.github+json" \
"/orgs/${ORG_LC}/packages/container/${REPO_LC}/versions/$VERSION_ID"
else
echo "No package found with tag pr-${PR_NUMBER}, skipping cleanup"
fi
cleanup-auto:
name: Delete QA GHCR image tag (auto)
runs-on: ubuntu-latest
if: >-
(github.event.action == 'closed' && contains(github.event.pull_request.labels.*.name, 'PR: Ready for QA')) ||
(github.event.action == 'unlabeled' && github.event.label.name == 'PR: Ready for QA')
permissions:
packages: write
steps:
- name: Delete PR tag from GHCR
env:
GH_TOKEN: ${{ secrets.ALLM_RW_PACKAGES }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
# Must use lowercase - packages are published with lowercase owner
ORG_LC="${GITHUB_REPOSITORY_OWNER,,}"
REPO_LC="${GITHUB_REPOSITORY#*/}"
REPO_LC="${REPO_LC,,}"
VERSION_ID=$(gh api \
-H "Accept: application/vnd.github+json" \
--paginate \
"/orgs/${ORG_LC}/packages/container/${REPO_LC}/versions" \
--jq ".[] | select(.metadata.container.tags[] == \"pr-${PR_NUMBER}\") | .id" \
2>/dev/null || true)
if [ -n "$VERSION_ID" ]; then
echo "Deleting package version $VERSION_ID (tag: pr-${PR_NUMBER})"
gh api \
--method DELETE \
-H "Accept: application/vnd.github+json" \
"/orgs/${ORG_LC}/packages/container/${REPO_LC}/versions/$VERSION_ID"
else
echo "No package found with tag pr-${PR_NUMBER}, skipping cleanup"
fi
================================================
FILE: .github/workflows/lint.yaml
================================================
name: Lint
concurrency:
group: lint-${{ github.ref }}
cancel-in-progress: true
on:
pull_request:
types: [opened, synchronize, reopened]
paths:
- "server/**/*.js"
- "server/eslint.config.mjs"
- "collector/**/*.js"
- "collector/eslint.config.mjs"
- "frontend/src/**/*.js"
- "frontend/src/**/*.jsx"
- "frontend/eslint.config.js"
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "18"
- name: Cache server dependencies
uses: actions/cache@v4
with:
path: server/node_modules
key: ${{ runner.os }}-yarn-server-${{ hashFiles('server/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-server-
- name: Cache frontend dependencies
uses: actions/cache@v4
with:
path: frontend/node_modules
key: ${{ runner.os }}-yarn-frontend-${{ hashFiles('frontend/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-frontend-
- name: Cache collector dependencies
uses: actions/cache@v4
with:
path: collector/node_modules
key: ${{ runner.os }}-yarn-collector-${{ hashFiles('collector/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-collector-
- name: Install server dependencies
run: cd server && yarn install --frozen-lockfile
- name: Install frontend dependencies
run: cd frontend && yarn install --frozen-lockfile
- name: Install collector dependencies
run: cd collector && yarn install --frozen-lockfile
env:
PUPPETEER_SKIP_DOWNLOAD: "true"
SHARP_IGNORE_GLOBAL_LIBVIPS: "true"
- name: Lint server
run: cd server && yarn lint:check
- name: Lint frontend
run: cd frontend && yarn lint:check
- name: Lint collector
run: cd collector && yarn lint:check
================================================
FILE: .github/workflows/run-tests.yaml
================================================
name: Run backend tests
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
pull_request:
types: [opened, synchronize, reopened]
paths:
- "server/**.js"
- "collector/**.js"
jobs:
run-script:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Cache root dependencies
uses: actions/cache@v3
with:
path: |
node_modules
~/.cache/yarn
key: ${{ runner.os }}-yarn-root-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-root-
- name: Cache server dependencies
uses: actions/cache@v3
with:
path: |
server/node_modules
~/.cache/yarn
key: ${{ runner.os }}-yarn-server-${{ hashFiles('server/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-server-
- name: Cache collector dependencies
uses: actions/cache@v3
with:
path: |
collector/node_modules
~/.cache/yarn
key: ${{ runner.os }}-yarn-collector-${{ hashFiles('collector/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-collector-
- name: Install root dependencies
if: steps.cache-root.outputs.cache-hit != 'true'
run: yarn install --frozen-lockfile
- name: Install server dependencies
if: steps.cache-server.outputs.cache-hit != 'true'
run: cd server && yarn install --frozen-lockfile
- name: Install collector dependencies
if: steps.cache-collector.outputs.cache-hit != 'true'
run: cd collector && yarn install --frozen-lockfile
env:
PUPPETEER_SKIP_DOWNLOAD: "true"
SHARP_IGNORE_GLOBAL_LIBVIPS: "true"
- name: Setup environment and Prisma
run: yarn setup:envs && yarn prisma:setup
- name: Run test suites
run: yarn test
- name: Fail job on error
if: failure()
run: exit 1
================================================
FILE: .github/workflows/sponsors.yaml
================================================
name: Generate Sponsors README
on:
schedule:
- cron: "0 12 * * 3" # Run every Wednesday at 12:00 PM UTC
permissions:
contents: write
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout 🛎️
uses: actions/checkout@v2
- name: Generate All Sponsors README
id: generate-all-sponsors
uses: JamesIves/github-sponsors-readme-action@v1
with:
token: ${{ secrets.SPONSOR_PAT }}
file: 'README.md'
organization: true
active-only: false
marker: 'all-sponsors'
- name: Commit and Push 🚀
uses: stefanzweifel/git-auto-commit-action@v5
id: auto-commit-action
with:
commit_message: 'Update Sponsors README'
file_pattern: 'README.md'
- name: Generate PR if changes detected
uses: peter-evans/create-pull-request@v7
if: steps.auto-commit-action.outputs.files_changed == 'true'
with:
token: ${{ secrets.GITHUB_TOKEN }}
title: 'Update Sponsors README'
branch: 'chore/update-sponsors'
base: 'master'
draft: false
reviewers: 'timothycarambat'
assignees: 'timothycarambat'
maintainer-can-modify: true
================================================
FILE: .gitignore
================================================
v-env
.env
!.env.example
node_modules
__pycache__
v-env
.DS_Store
aws_cf_deploy_anything_llm.json
yarn.lock
*.bak
.idea
================================================
FILE: .gitmodules
================================================
[submodule "browser-extension"]
path = browser-extension
url = https://github.com/Mintplex-Labs/anythingllm-extension.git
[submodule "embed"]
path = embed
url = https://github.com/Mintplex-Labs/anythingllm-embed.git
branch = main
================================================
FILE: .hadolint.yaml
================================================
failure-threshold: warning
ignored:
- DL3008
- DL3013
format: tty
trustedRegistries:
- docker.io
- gcr.io
================================================
FILE: .nvmrc
================================================
v18.18.0
================================================
FILE: .prettierignore
================================================
# defaults
**/.git
**/.svn
**/.hg
**/node_modules
#frontend
frontend/bundleinspector.html
**/dist
#server
server/swagger/openapi.json
server/**/*.mjs
#embed
**/static/**
embed/src/utils/chat/hljs.js
================================================
FILE: .prettierrc
================================================
{
"tabWidth": 2,
"useTabs": false,
"endOfLine": "lf",
"semi": true,
"singleQuote": false,
"printWidth": 80,
"trailingComma": "es5",
"bracketSpacing": true,
"bracketSameLine": false,
"overrides": [
{
"files": ["*.js", "*.mjs", "*.jsx"],
"options": {
"parser": "flow",
"arrowParens": "always"
}
},
{
"files": ["*.config.js"],
"options": {
"semi": false,
"parser": "flow",
"trailingComma": "none"
}
},
{
"files": "*.html",
"options": {
"bracketSameLine": true
}
},
{
"files": ".prettierrc",
"options": { "parser": "json" }
}
]
}
================================================
FILE: .vscode/launch.json
================================================
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Collector debug",
"request": "launch",
"cwd": "${workspaceFolder}/collector",
"env": {
"NODE_ENV": "development"
},
"runtimeArgs": [
"index.js"
],
// not using yarn/nodemon because it doesn't work with breakpoints
// "runtimeExecutable": "yarn",
"skipFiles": [
"/**"
],
"type": "node"
},
{
"name": "Server debug",
"request": "launch",
"cwd": "${workspaceFolder}/server",
"env": {
"NODE_ENV": "development"
},
"runtimeArgs": [
"index.js"
],
// not using yarn/nodemon because it doesn't work with breakpoints
// "runtimeExecutable": "yarn",
"skipFiles": [
"/**"
],
"type": "node"
},
{
"name": "Frontend debug",
"request": "launch",
"cwd": "${workspaceFolder}/frontend",
"env": {
"NODE_ENV": "development",
},
"runtimeExecutable": "${workspaceFolder}/frontend/node_modules/.bin/vite",
"runtimeArgs": [
"--debug",
"--host=0.0.0.0"
],
// "runtimeExecutable": "yarn",
"skipFiles": [
"/**"
],
"type": "node"
},
{
"name": "Launch Edge",
"request": "launch",
"type": "msedge",
"url": "http://localhost:3000",
"webRoot": "${workspaceFolder}"
},
{
"type": "chrome",
"request": "launch",
"name": "Launch Chrome against localhost",
"url": "http://localhost:3000",
"webRoot": "${workspaceFolder}"
}
]
}
================================================
FILE: .vscode/settings.json
================================================
{
"cSpell.words": [
"adoc",
"aibitat",
"AIbitat",
"allm",
"anythingllm",
"Apipie",
"Astra",
"Chartable",
"cleancss",
"comkey",
"cooldown",
"cooldowns",
"datafile",
"Deduplicator",
"Dockerized",
"docpath",
"elevenlabs",
"Embeddable",
"epub",
"fireworksai",
"GROQ",
"hljs",
"huggingface",
"inferencing",
"koboldcpp",
"Langchain",
"lmstudio",
"localai",
"mbox",
"Milvus",
"Mintplex",
"mixtral",
"moderations",
"novita",
"numpages",
"Ollama",
"Oobabooga",
"openai",
"opendocument",
"openrouter",
"pagerender",
"ppio",
"Qdrant",
"royalblue",
"SearchApi",
"searxng",
"SerpApi",
"Serper",
"Serply",
"streamable",
"textgenwebui",
"togetherai",
"Unembed",
"uuidv",
"vectordbs",
"Weaviate",
"XAILLM",
"Zilliz"
],
"eslint.experimental.useFlatConfig": true,
"docker.languageserver.formatter.ignoreMultilineInstructions": true
}
================================================
FILE: .vscode/tasks.json
================================================
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"options": {
"cwd": "${workspaceFolder}/collector",
"statusbar": {
"color": "#ffea00",
"detail": "Runs the collector",
"label": "Collector: $(play) run",
"running": {
"color": "#ffea00",
"label": "Collector: $(gear~spin) running"
}
}
},
"command": "cd ${workspaceFolder}/collector/ && yarn dev",
"runOptions": {
"instanceLimit": 1,
"reevaluateOnRerun": true
},
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared",
"showReuseMessage": true,
"clear": false
},
"label": "Collector: run"
},
{
"type": "shell",
"options": {
"cwd": "${workspaceFolder}/server",
"statusbar": {
"color": "#ffea00",
"detail": "Runs the server",
"label": "Server: $(play) run",
"running": {
"color": "#ffea00",
"label": "Server: $(gear~spin) running"
}
}
},
"command": "if [ \"${CODESPACES}\" = \"true\" ]; then while ! gh codespace ports -c $CODESPACE_NAME | grep 3001; do sleep 1; done; gh codespace ports visibility 3001:public -c $CODESPACE_NAME; fi & cd ${workspaceFolder}/server/ && yarn dev",
"runOptions": {
"instanceLimit": 1,
"reevaluateOnRerun": true
},
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared",
"showReuseMessage": true,
"clear": false
},
"label": "Server: run"
},
{
"type": "shell",
"options": {
"cwd": "${workspaceFolder}/frontend",
"statusbar": {
"color": "#ffea00",
"detail": "Runs the frontend",
"label": "Frontend: $(play) run",
"running": {
"color": "#ffea00",
"label": "Frontend: $(gear~spin) running"
}
}
},
"command": "cd ${workspaceFolder}/frontend/ && yarn dev",
"runOptions": {
"instanceLimit": 1,
"reevaluateOnRerun": true
},
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared",
"showReuseMessage": true,
"clear": false
},
"label": "Frontend: run"
}
]
}
================================================
FILE: BARE_METAL.md
================================================
# Run AnythingLLM in production without Docker
> [!WARNING]
> This method of deployment is **not supported** by the core-team and is to be used as a reference for your deployment.
> You are fully responsible for securing your deployment and data in this mode.
> **Any issues** experienced from bare-metal or non-containerized deployments will be **not** answered or supported.
Here you can find the scripts and known working process to run AnythingLLM outside of a Docker container.
### Minimum Requirements
> [!TIP]
> You should aim for at least 2GB of RAM. Disk storage is proportional to however much data
> you will be storing (documents, vectors, models, etc). Minimum 10GB recommended.
- NodeJS v18
- Yarn
## Getting started
1. Clone the repo into your server as the user who the application will run as.
`git clone git@github.com:Mintplex-Labs/anything-llm.git`
2. `cd anything-llm` and run `yarn setup`. This will install all dependencies to run in production as well as debug the application.
3. `cp server/.env.example server/.env` to create the basic ENV file for where instance settings will be read from on service start.
4. Ensure that the `server/.env` file has _at least_ these keys to start. These values will persist and this file will be automatically written and managed after your first successful boot.
```
STORAGE_DIR="/your/absolute/path/to/server/storage"
```
5. Edit the `frontend/.env` file for the `VITE_BASE_API` to now be set to `/api`. This is documented in the .env for which one you should use.
```
# VITE_API_BASE='http://localhost:3001/api' # Use this URL when developing locally
# VITE_API_BASE="https://$CODESPACE_NAME-3001.$GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN/api" # for GitHub Codespaces
VITE_API_BASE='/api' # Use this URL deploying on non-localhost address OR in docker.
```
## To start the application
AnythingLLM is comprised of three main sections. The `frontend`, `server`, and `collector`. When running in production you will be running `server` and `collector` on two different processes, with a build step for compilation of the frontend.
1. Build the frontend application.
`cd frontend && yarn build` - this will produce a `frontend/dist` folder that will be used later.
2. Copy `frontend/dist` to `server/public` - `cp -R frontend/dist server/public`.
This should create a folder in `server` named `public` which contains a top level `index.html` file and various other files/folders.
3. Migrate and prepare your database file.
```
cd server && npx prisma generate --schema=./prisma/schema.prisma
cd server && npx prisma migrate deploy --schema=./prisma/schema.prisma
```
4. Boot the server in production
`cd server && NODE_ENV=production node index.js &`
5. Boot the collection in another process
`cd collector && NODE_ENV=production node index.js &`
AnythingLLM should now be running on `http://localhost:3001`!
## Updating AnythingLLM
To update AnythingLLM with future updates you can `git pull origin master` to pull in the latest code and then repeat steps 2 - 5 to deploy with all changes fully.
_note_ You should ensure that each folder runs `yarn` again to ensure packages are up to date in case any dependencies were added, changed, or removed.
_note_ You should `pkill node` before running an update so that you are not running multiple AnythingLLM processes on the same instance as this can cause conflicts.
### Example update script
```shell
#!/bin/bash
cd $HOME/anything-llm &&\
git checkout . &&\
git pull origin master &&\
echo "HEAD pulled to commit $(git log -1 --pretty=format:"%h" | tail -n 1)"
echo "Freezing current ENVs"
curl -I "http://localhost:3001/api/env-dump" | head -n 1|cut -d$' ' -f2
echo "Rebuilding Frontend"
cd $HOME/anything-llm/frontend && yarn && yarn build && cd $HOME/anything-llm
echo "Copying to Server Public"
rm -rf server/public
cp -r frontend/dist server/public
echo "Killing node processes"
pkill node
echo "Installing collector dependencies"
cd $HOME/anything-llm/collector && yarn
echo "Installing server dependencies & running migrations"
cd $HOME/anything-llm/server && yarn
cd $HOME/anything-llm/server && npx prisma migrate deploy --schema=./prisma/schema.prisma
cd $HOME/anything-llm/server && npx prisma generate
echo "Booting up services."
truncate -s 0 /logs/server.log # Or any other log file location.
truncate -s 0 /logs/collector.log
cd $HOME/anything-llm/server
(NODE_ENV=production node index.js) &> /logs/server.log &
cd $HOME/anything-llm/collector
(NODE_ENV=production node index.js) &> /logs/collector.log &
```
## Using Nginx?
If you are using Nginx, you can use the following example configuration to proxy the requests to the server. Chats for streaming require **websocket** connections, so you need to ensure that the Nginx configuration is set up to support websockets. You can do this with a simple reverse proxy configuration.
```nginx
server {
# Enable websocket connections for agent protocol.
location ~* ^/api/agent-invocation/(.*) {
proxy_pass http://0.0.0.0:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
listen 80;
server_name [insert FQDN here];
location / {
# Prevent timeouts on long-running requests.
proxy_connect_timeout 605;
proxy_send_timeout 605;
proxy_read_timeout 605;
send_timeout 605;
keepalive_timeout 605;
# Enable readable HTTP Streaming for LLM streamed responses
proxy_buffering off;
proxy_cache off;
# Proxy your locally running service
proxy_pass http://0.0.0.0:3001;
}
}
```
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to AnythingLLM
AnythingLLM is an open-source project and we welcome contributions from the community.
## Reporting Issues
If you encounter a bug or have a feature request, please open an issue on the
[GitHub issue tracker](https://github.com/mintplex-labs/anything-llm).
## Picking an issue
We track issues on the GitHub issue tracker. If you are looking for something to
work on, check the [good first issue](https://github.com/mintplex-labs/anything-llm/contribute) label. These issues are typically the best described and have the smallest scope. There may be issues that are not labeled as good first issue, but are still a good starting point.
If there's an issue you are interested in working on, please leave a comment on the issue. This will help us avoid duplicate work. Additionally, if you have questions about the issue, please ask them in the issue comments. We are happy to provide guidance on how to approach the issue.
## Before you start
Keep in mind that we are a small team and have limited resources. We will do our best to review and merge your PRs, but please be patient. Ultimately, **we become the maintainer** of your changes. It is our responsibility to make sure that the changes are working as expected and are of high quality as well as being compatible with the rest of the project both for existing users and for future users & features.
Before you start working on an issue, please read the following so that you don't waste time on something that is not a good fit for the project or is more suitable for a personal fork. We would rather answer a comment on an issue than close a PR after you've spent time on it. Your time is valuable and we appreciate your time and effort to make AnythingLLM better.
0. (most important) If you are making a PR that does not have a corresponding issue, **it will not be merged.** _The only exception to this is language translations._
1. If you are modifying the permission system for a new role or something custom, you are likely better off forking the project and building your own version since this is a core part of the project and is only to be maintained by the AnythingLLM team.
2. Integrations (LLM, Vector DB, etc.) are reviewed at our discretion. We will eventually get to them. Do not expect us to merge your integration PR instantly since there are often many moving parts and we want to make sure we get it right. We will get to it!
3. It is our discretion to merge or not merge a PR. We value every contribution, but we also value the quality of the code and the user experience we envision for the project. It is a fine line to walk when running a project like this and please understand that merging or not merging a PR is not a reflection of the quality of the contribution and is not personal. We will do our best to provide feedback on the PR and help you make the changes necessary to get it merged.
4. **Security** is always important. If you have a security concern, please do not open an issue. Instead, please open a CVE on our designated reporting platform [Huntr](https://huntr.com) or contact us at [team@mintplexlabs.com](mailto:team@mintplexlabs.com).
## Configuring Git
First, fork the repository on GitHub, then clone your fork:
```bash
git clone https://github.com//anything-llm.git
cd anything-llm
```
Then add the main repository as a remote:
```bash
git remote add upstream https://github.com/mintplex-labs/anything-llm.git
git fetch upstream
```
## Setting up your development environment
In the root of the repository, run:
```bash
yarn setup
```
This will install the dependencies, set up the proper and expected ENV files for the project, and run the prisma setup script.
Next, run:
```bash
yarn dev:all
```
This will start the server, frontend, and collector in development mode. Changes to the code will be hot reloaded.
## Best practices for pull requests
For the best chance of having your pull request accepted, please follow these guidelines:
1. Unit test all bug fixes and new features. Your code will not be merged if it
doesn't have tests.
1. If you change the public API, update the documentation in the `anythingllm-docs` repository.
1. Aim to minimize the number of changes in each pull request. Keep to solving
one problem at a time, when possible.
1. Before marking a pull request ready-for-review, do a self review of your code.
Is it clear why you are making the changes? Are the changes easy to understand?
1. Use [conventional commit messages](https://www.conventionalcommits.org/en/) as pull request titles. Examples:
* New feature: `feat: adding foo API`
* Bug fix: `fix: issue with foo API`
* Documentation change: `docs: adding foo API documentation`
1. If your pull request is a work in progress, leave the pull request as a draft.
We will assume the pull request is ready for review when it is opened.
1. When writing tests, test the error cases. Make sure they have understandable
error messages.
## Project structure
The core library is written in Node.js. There are additional sub-repositories for the embed widget and browser extension. These are not part of the core AnythingLLM project, but are maintained by the AnythingLLM team.
* `server`: Node.js server source code
* `frontend`: React frontend source code
* `collector`: Python collector source code
## Release process
Changes to the core AnythingLLM project are released through the `master` branch. When a PR is merged into `master`, a new version of the package is published to Docker and GitHub Container Registry under the `latest` tag.
When a new version is released, the following steps are taken a new image is built and pushed to Docker Hub and GitHub Container Registry under the associated version tag. Version tags are of the format `v..` and are pinned code, while `latest` is the latest version of the code at any point in time.
### Desktop propagation
Changes to the desktop app are downstream of the core AnythingLLM project. Releases of the desktop app are published at the same time as the core AnythingLLM project. Code from the core AnythingLLM project is copied into the desktop app into an Electron wrapper. The Electron wrapper that wraps around the core AnythingLLM project is **not** part of the core AnythingLLM project, but is maintained by the AnythingLLM team.
## License
By contributing to AnythingLLM (this repository), you agree to license your contributions under the MIT license.
================================================
FILE: LICENSE
================================================
The MIT License
Copyright (c) Mintplex Labs Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================
FILE: README.md
================================================
AnythingLLM: The all-in-one AI app you were looking for.
Chat with your docs, use AI Agents, hyper-configurable, multi-user, & no frustrating setup required.
👉 AnythingLLM for desktop (Mac, Windows, & Linux)! Download Now
Chat with your docs. Automate complex workflows with AI Agents. Hyper-configurable, multi-user ready, battle-tested—and runs locally by default with zero setup friction.

Watch the demo!
[](https://youtu.be/f95rGD9trL0)
### Product Overview
AnythingLLM is the all-in-one AI application that lets you build a private, fully-featured ChatGPT—without compromises. Connect your favorite local or cloud LLM, ingest your documents, and start chatting in minutes. Out of the box you get built-in agents, multi-user support, vector databases, and document pipelines — no extra configuration required.
AnythingLLM supports multiple users as well where you can control the access and experience per user without compromising the security or privacy of the instance or your intellectual property.
## Cool features of AnythingLLM
- [Intelligent Skill Selection](https://docs.anythingllm.com/agent/intelligent-tool-selection) Enable **unlimited** tools for your models while reducing token usage by up to 80% per query
- [**No-code AI Agent builder**](https://docs.anythingllm.com/agent-flows/overview)
- [**Full MCP-compatibility**](https://docs.anythingllm.com/mcp-compatibility/overview)
- **Multi-modal support (both closed and open-source LLMs!)**
- [**Custom AI Agents**](https://docs.anythingllm.com/agent/custom/introduction)
- 👤 Multi-user instance support and permissioning _Docker version only_
- 🦾 Agents inside your workspace (browse the web, etc)
- 💬 [Custom Embeddable Chat widget for your website](https://github.com/Mintplex-Labs/anythingllm-embed/blob/main/README.md) _Docker version only_
- 📖 Multiple document type support (PDF, TXT, DOCX, etc)
- Intuitive chat UI with drag-and-drop uploads and source citations.
- Production-ready for any cloud deployment.
- Works with all popular [closed and open-source LLM providers](#supported-llms-embedder-models-speech-models-and-vector-databases).
- Built-in optimizations for large document sets—lower costs and faster responses than other chat UIs.
- Full Developer API for custom integrations!
- ...and much more—install in minutes and see for yourself.
### Supported LLMs, Embedder Models, Speech models, and Vector Databases
**Large Language Models (LLMs):**
- [Any open-source llama.cpp compatible model](/server/storage/models/README.md#text-generation-llm-selection)
- [OpenAI](https://openai.com)
- [OpenAI (Generic)](https://openai.com)
- [Azure OpenAI](https://azure.microsoft.com/en-us/products/ai-services/openai-service)
- [AWS Bedrock](https://aws.amazon.com/bedrock/)
- [Anthropic](https://www.anthropic.com/)
- [NVIDIA NIM (chat models)](https://build.nvidia.com/explore/discover)
- [Google Gemini Pro](https://ai.google.dev/)
- [Hugging Face (chat models)](https://huggingface.co/)
- [Ollama (chat models)](https://ollama.ai/)
- [LM Studio (all models)](https://lmstudio.ai)
- [LocalAI (all models)](https://localai.io/)
- [Together AI (chat models)](https://www.together.ai/)
- [Fireworks AI (chat models)](https://fireworks.ai/)
- [Perplexity (chat models)](https://www.perplexity.ai/)
- [OpenRouter (chat models)](https://openrouter.ai/)
- [DeepSeek (chat models)](https://deepseek.com/)
- [Mistral](https://mistral.ai/)
- [Groq](https://groq.com/)
- [Cohere](https://cohere.com/)
- [KoboldCPP](https://github.com/LostRuins/koboldcpp)
- [LiteLLM](https://github.com/BerriAI/litellm)
- [Text Generation Web UI](https://github.com/oobabooga/text-generation-webui)
- [Apipie](https://apipie.ai/)
- [xAI](https://x.ai/)
- [Z.AI (chat models)](https://z.ai/model-api)
- [Novita AI (chat models)](https://novita.ai/model-api/product/llm-api?utm_source=github_anything-llm&utm_medium=github_readme&utm_campaign=link)
- [PPIO](https://ppinfra.com?utm_source=github_anything-llm)
- [Gitee AI](https://ai.gitee.com/)
- [Moonshot AI](https://www.moonshot.ai/)
- [Microsoft Foundry Local](https://github.com/microsoft/Foundry-Local)
- [CometAPI (chat models)](https://api.cometapi.com/)
- [Docker Model Runner](https://docs.docker.com/ai/model-runner/)
- [PrivateModeAI (chat models)](https://privatemode.ai/)
- [SambaNova Cloud (chat models)](https://cloud.sambanova.ai/)
- [Lemonade by AMD](https://lemonade-server.ai)
**Embedder models:**
- [AnythingLLM Native Embedder](/server/storage/models/README.md) (default)
- [OpenAI](https://openai.com)
- [Azure OpenAI](https://azure.microsoft.com/en-us/products/ai-services/openai-service)
- [LocalAI (all)](https://localai.io/)
- [Ollama (all)](https://ollama.ai/)
- [LM Studio (all)](https://lmstudio.ai)
- [Cohere](https://cohere.com/)
**Audio Transcription models:**
- [AnythingLLM Built-in](https://github.com/Mintplex-Labs/anything-llm/tree/master/server/storage/models#audiovideo-transcription) (default)
- [OpenAI](https://openai.com/)
**TTS (text-to-speech) support:**
- Native Browser Built-in (default)
- [PiperTTSLocal - runs in browser](https://github.com/rhasspy/piper)
- [OpenAI TTS](https://platform.openai.com/docs/guides/text-to-speech/voice-options)
- [ElevenLabs](https://elevenlabs.io/)
- Any OpenAI Compatible TTS service.
**STT (speech-to-text) support:**
- Native Browser Built-in (default)
**Vector Databases:**
- [LanceDB](https://github.com/lancedb/lancedb) (default)
- [PGVector](https://github.com/pgvector/pgvector)
- [Astra DB](https://www.datastax.com/products/datastax-astra)
- [Pinecone](https://pinecone.io)
- [Chroma & ChromaCloud](https://trychroma.com)
- [Weaviate](https://weaviate.io)
- [Qdrant](https://qdrant.tech)
- [Milvus](https://milvus.io)
- [Zilliz](https://zilliz.com)
### Technical Overview
This monorepo consists of six main sections:
- `frontend`: A viteJS + React frontend that you can run to easily create and manage all your content the LLM can use.
- `server`: A NodeJS express server to handle all the interactions and do all the vectorDB management and LLM interactions.
- `collector`: NodeJS express server that processes and parses documents from the UI.
- `docker`: Docker instructions and build process + information for building from source.
- `embed`: Submodule for generation & creation of the [web embed widget](https://github.com/Mintplex-Labs/anythingllm-embed).
- `browser-extension`: Submodule for the [chrome browser extension](https://github.com/Mintplex-Labs/anythingllm-extension).
## 🛳 Self-Hosting
Mintplex Labs & the community maintain a number of deployment methods, scripts, and templates that you can use to run AnythingLLM locally. Refer to the table below to read how to deploy on your preferred environment or to automatically deploy.
| Docker | AWS | GCP | Digital Ocean | Render.com |
|----------------------------------------|----|-----|---------------|------------|
| [![Deploy on Docker][docker-btn]][docker-deploy] | [![Deploy on AWS][aws-btn]][aws-deploy] | [![Deploy on GCP][gcp-btn]][gcp-deploy] | [![Deploy on DigitalOcean][do-btn]][do-deploy] | [![Deploy on Render.com][render-btn]][render-deploy] |
| Railway | RepoCloud | Elestio | Northflank |
| --------------------------------------------------- | --------------------------------------------------------- | --------------------------------------------------- | ------------------------------------------------------------ |
| [![Deploy on Railway][railway-btn]][railway-deploy] | [![Deploy on RepoCloud][repocloud-btn]][repocloud-deploy] | [![Deploy on Elestio][elestio-btn]][elestio-deploy] | [![Deploy on Northflank][northflank-btn]][northflank-deploy] |
[or set up a production AnythingLLM instance without Docker →](./BARE_METAL.md)
## How to setup for development
- `yarn setup` To fill in the required `.env` files you'll need in each of the application sections (from root of repo).
- Go fill those out before proceeding. Ensure `server/.env.development` is filled or else things won't work right.
- `yarn dev:server` To boot the server locally (from root of repo).
- `yarn dev:frontend` To boot the frontend locally (from root of repo).
- `yarn dev:collector` To then run the document collector (from root of repo).
[Learn about documents](./server/storage/documents/DOCUMENTS.md)
## Telemetry & Privacy
AnythingLLM by Mintplex Labs Inc contains a telemetry feature that collects anonymous usage information.
More about Telemetry & Privacy for AnythingLLM
### Why?
We use this information to help us understand how AnythingLLM is used, to help us prioritize work on new features and bug fixes, and to help us improve AnythingLLM's performance and stability.
### Opting out
Set `DISABLE_TELEMETRY` in your server or docker .env settings to "true" to opt out of telemetry. You can also do this in-app by going to the sidebar > `Privacy` and disabling telemetry.
### What do you explicitly track?
We will only track usage details that help us make product and roadmap decisions, specifically:
- Type of your installation (Docker or Desktop)
- When a document is added or removed. No information _about_ the document. Just that the event occurred. This gives us an idea of use.
- Type of vector database in use. This helps us prioritize changes when updates arrive for that provider.
- Type of LLM provider & model tag in use. This helps us prioritize changes when updates arrive for that provider or model, or combination thereof. eg: reasoning vs regular, multi-modal models, etc.
- When a chat is sent. This is the most regular "event" and gives us an idea of the daily-activity of this project across all installations. Again, only the **event** is sent - we have no information on the nature or content of the chat itself.
You can verify these claims by finding all locations `Telemetry.sendTelemetry` is called. Additionally these events are written to the output log so you can also see the specific data which was sent - if enabled. **No IP or other identifying information is collected**. The Telemetry provider is [PostHog](https://posthog.com/) - an open-source telemetry collection service.
We take privacy very seriously, and we hope you understand that we want to learn how our tool is used, without using annoying popup surveys, so we can build something worth using. The anonymous data is _never_ shared with third parties, ever.
[View all telemetry events in source code](https://github.com/search?q=repo%3AMintplex-Labs%2Fanything-llm%20.sendTelemetry(&type=code)
## 👋 Contributing
- [Contributing to AnythingLLM](./CONTRIBUTING.md) - How to contribute to AnythingLLM.
## 💖 Sponsors
### Premium Sponsors
### All Sponsors
## 🌟 Contributors
[](https://github.com/mintplex-labs/anything-llm/graphs/contributors)
[](https://star-history.com/#mintplex-labs/anything-llm&Date)
## 🔗 More Products
- **[VectorAdmin][vector-admin]:** An all-in-one GUI & tool-suite for managing vector databases.
- **[OpenAI Assistant Swarm][assistant-swarm]:** Turn your entire library of OpenAI assistants into one single army commanded from a single agent.