LlamaIndex Tutorial (TypeScript): deploying with Docker for advanced developers

By Cyprian AaronsUpdated 2026-04-21
llamaindexdeploying-with-docker-for-advanced-developerstypescript

This tutorial shows you how to package a TypeScript LlamaIndex app into Docker, run it locally, and keep it production-friendly for deployment. You need this when your agent works on your laptop but still has to run the same way in CI, on a VM, or inside a container platform.

What You'll Need

  • Node.js 20+
  • Docker Engine 24+
  • An OpenAI API key exported as OPENAI_API_KEY
  • A working TypeScript project with npm
  • Packages:
    • llamaindex
    • dotenv
    • typescript
    • tsx for local execution
  • Basic familiarity with LlamaIndex query engines and embeddings

Step-by-Step

  1. Start with a minimal project layout that keeps source code, config, and container files separate. This makes the image easier to build and avoids copying junk into the container.
mkdir llamaindex-docker-ts
cd llamaindex-docker-ts
npm init -y
npm i llamaindex dotenv
npm i -D typescript tsx @types/node
mkdir src
  1. Add a TypeScript config that targets modern Node.js and keeps compilation simple. For Docker deployments, you want predictable module resolution and no browser-specific settings.
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "outDir": "dist",
    "rootDir": "src"
  },
  "include": ["src/**/*.ts"]
}
  1. Build a real LlamaIndex script that loads environment variables, creates a vector index from in-memory documents, and runs a query. This is enough to validate your runtime inside Docker before wiring in external data sources.
// src/index.ts
import 'dotenv/config';
import { Document, VectorStoreIndex } from 'llamaindex';

async function main() {
  if (!process.env.OPENAI_API_KEY) {
    throw new Error('OPENAI_API_KEY is required');
  }

  const docs = [
    new Document({
      text: 'LlamaIndex helps connect LLMs to data sources.',
      metadata: { source: 'doc-1' },
    }),
    new Document({
      text: 'Docker makes the runtime reproducible across environments.',
      metadata: { source: 'doc-2' },
    }),
  ];

  const index = await VectorStoreIndex.fromDocuments(docs);
  const queryEngine = index.asQueryEngine();

  const response = await queryEngine.query({
    query: 'What does Docker help with?',
  });

  console.log(String(response));
}

main().catch((err) => {
  console.error(err);
  process.exit(1);
});
  1. Add scripts so you can run the app locally the same way you’ll run it in the container. Keep one command for development and one for production-style execution.
{
  "name": "llamaindex-docker-ts",
  "version": "1.0.0",
  "private": true,
  "type": "module",
  "scripts": {
    "dev": "tsx src/index.ts",
    "build": "tsc",
    "start": "node dist/index.js"
  },
  "dependencies": {
    "dotenv": "^16.4.5",
    "llamaindex": "^0.6.0"
  },
  "devDependencies": {
    "@types/node": "^22.10.2",
    "tsx": "^4.19.2",
    "typescript": "^5.7.2"
  }
}
  1. Create a .dockerignore and a multi-stage Dockerfile. The first stage installs dependencies and builds TypeScript; the second stage ships only what you need to run.
# .dockerignore
node_modules
dist
.git
.env
npm-debug.log

# Dockerfile
FROM node:20-alpine AS builder

WORKDIR /app

COPY package*.json tsconfig.json ./
RUN npm ci

COPY src ./src
RUN npm run build

FROM node:20-alpine AS runner

WORKDIR /app
ENV NODE_ENV=production

COPY package*.json ./
RUN npm ci --omit=dev

COPY --from=builder /app/dist ./dist

CMD ["node", "dist/index.js"]
  1. Run it locally first, then build and execute the container with your API key injected at runtime. If this fails here, do not move on to Kubernetes or ECS yet.
export OPENAI_API_KEY="your-api-key-here"

npm run dev

docker build -t llamaindex-ts-app .
docker run --rm \
  -e OPENAI_API_KEY="$OPENAI_API_KEY" \
  llamaindex-ts-app

Testing It

You should see a natural-language answer printed to stdout, not a stack trace or empty output. If the container exits immediately with an auth error, verify that OPENAI_API_KEY is present in the runtime environment and not only on your host shell.

For deeper verification, rebuild after changing one of the document texts and confirm the response changes accordingly. That tells you the image is using the code you shipped, not stale local artifacts.

If you want stronger confidence, run docker logs against a detached container and compare output between local npm run dev and docker run. They should match closely aside from minor model variation.

Next Steps

  • Replace in-memory documents with loaders for PDF, HTML, or database-backed content.
  • Add structured logging and request IDs before moving this into an API service.
  • Introduce OpenTelemetry or Prometheus metrics if this container will sit behind an internal gateway or job runner

Keep learning

By Cyprian Aarons, AI Consultant at Topiax.

Want the complete 8-step roadmap?

Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.

Get the Starter Kit

Related Guides