Node.js API (TypeScript) ├── Redis (session/memory) ├── Postgres (state) ├── Local LLM endpoint (optional) └── Frontend debug UI
Node.js API (TypeScript) ├── Redis (session/memory) ├── Postgres (state) ├── Local LLM endpoint (optional) └── Frontend debug UI
Node.js API (TypeScript) ├── Redis (session/memory) ├── Postgres (state) ├── Local LLM endpoint (optional) └── Frontend debug UI
docker compose up --watch
docker compose up --watch
docker compose up --watch
FROM node:22-slim WORKDIR /app COPY package*.json ./
RUN npm ci COPY tsconfig.json ./
COPY src ./src CMD ["npx", "tsx", "watch", "src/index.ts"]
FROM node:22-slim WORKDIR /app COPY package*.json ./
RUN npm ci COPY tsconfig.json ./
COPY src ./src CMD ["npx", "tsx", "watch", "src/index.ts"]
FROM node:22-slim WORKDIR /app COPY package*.json ./
RUN npm ci COPY tsconfig.json ./
COPY src ./src CMD ["npx", "tsx", "watch", "src/index.ts"]
services: api: build: context: . dockerfile: Dockerfile.dev ports: - "3000:3000" environment: NODE_ENV: development REDIS_URL: redis://redis:6379 OPENAI_BASE_URL: ${OPENAI_BASE_URL:-http://host.docker.internal:12434/engines/llama.cpp/v1} OPENAI_API_KEY: ${OPENAI_API_KEY:-local-development-key} depends_on: - redis develop: watch: - action: sync path: ./src target: /app/src ignore: - "**/*.test.ts" - "**/*.spec.ts" - action: rebuild path: ./package.json - action: rebuild path: ./package-lock.json - action: rebuild path: ./tsconfig.json redis: image: redis:7-alpine ports: - "6379:6379"
services: api: build: context: . dockerfile: Dockerfile.dev ports: - "3000:3000" environment: NODE_ENV: development REDIS_URL: redis://redis:6379 OPENAI_BASE_URL: ${OPENAI_BASE_URL:-http://host.docker.internal:12434/engines/llama.cpp/v1} OPENAI_API_KEY: ${OPENAI_API_KEY:-local-development-key} depends_on: - redis develop: watch: - action: sync path: ./src target: /app/src ignore: - "**/*.test.ts" - "**/*.spec.ts" - action: rebuild path: ./package.json - action: rebuild path: ./package-lock.json - action: rebuild path: ./tsconfig.json redis: image: redis:7-alpine ports: - "6379:6379"
services: api: build: context: . dockerfile: Dockerfile.dev ports: - "3000:3000" environment: NODE_ENV: development REDIS_URL: redis://redis:6379 OPENAI_BASE_URL: ${OPENAI_BASE_URL:-http://host.docker.internal:12434/engines/llama.cpp/v1} OPENAI_API_KEY: ${OPENAI_API_KEY:-local-development-key} depends_on: - redis develop: watch: - action: sync path: ./src target: /app/src ignore: - "**/*.test.ts" - "**/*.spec.ts" - action: rebuild path: ./package.json - action: rebuild path: ./package-lock.json - action: rebuild path: ./tsconfig.json redis: image: redis:7-alpine ports: - "6379:6379"
docker compose up --watch
docker compose up --watch
docker compose up --watch
export function buildSummaryPrompt(input: string) { return [ { role: "system", content: "You summarize technical logs clearly. Mention the likely cause and next action." }, { role: "user", content: input } ];
}
export function buildSummaryPrompt(input: string) { return [ { role: "system", content: "You summarize technical logs clearly. Mention the likely cause and next action." }, { role: "user", content: input } ];
}
export function buildSummaryPrompt(input: string) { return [ { role: "system", content: "You summarize technical logs clearly. Mention the likely cause and next action." }, { role: "user", content: input } ];
}
services: frontend: build: context: ./frontend dockerfile: Dockerfile.dev ports: - "5173:5173" environment: VITE_API_URL: http://localhost:3000 develop: watch: - action: sync path: ./frontend/src target: /app/src ignore: - node_modules/ - action: rebuild path: ./frontend/package.json - action: rebuild path: ./frontend/package-lock.json api: build: context: ./api dockerfile: Dockerfile.dev ports: - "3000:3000" environment: REDIS_URL: redis://redis:6379 depends_on: - redis develop: watch: - action: sync path: ./api/src target: /app/src - action: rebuild path: ./api/package.json - action: rebuild path: ./api/package-lock.json redis: image: redis:7-alpine
services: frontend: build: context: ./frontend dockerfile: Dockerfile.dev ports: - "5173:5173" environment: VITE_API_URL: http://localhost:3000 develop: watch: - action: sync path: ./frontend/src target: /app/src ignore: - node_modules/ - action: rebuild path: ./frontend/package.json - action: rebuild path: ./frontend/package-lock.json api: build: context: ./api dockerfile: Dockerfile.dev ports: - "3000:3000" environment: REDIS_URL: redis://redis:6379 depends_on: - redis develop: watch: - action: sync path: ./api/src target: /app/src - action: rebuild path: ./api/package.json - action: rebuild path: ./api/package-lock.json redis: image: redis:7-alpine
services: frontend: build: context: ./frontend dockerfile: Dockerfile.dev ports: - "5173:5173" environment: VITE_API_URL: http://localhost:3000 develop: watch: - action: sync path: ./frontend/src target: /app/src ignore: - node_modules/ - action: rebuild path: ./frontend/package.json - action: rebuild path: ./frontend/package-lock.json api: build: context: ./api dockerfile: Dockerfile.dev ports: - "3000:3000" environment: REDIS_URL: redis://redis:6379 depends_on: - redis develop: watch: - action: sync path: ./api/src target: /app/src - action: rebuild path: ./api/package.json - action: rebuild path: ./api/package-lock.json redis: image: redis:7-alpine
volumes: - ./src:/app/src
volumes: - ./src:/app/src
volumes: - ./src:/app/src
- action: sync path: ./src target: /app/src
- action: sync path: ./src target: /app/src
- action: sync path: ./src target: /app/src
- action: rebuild path: ./package.json - action: rebuild path: ./package-lock.json
- action: rebuild path: ./package.json - action: rebuild path: ./package-lock.json
- action: rebuild path: ./package.json - action: rebuild path: ./package-lock.json
- action: sync+restart path: ./config target: /app/config
- action: sync+restart path: ./config target: /app/config
- action: sync+restart path: ./config target: /app/config
ignore: - node_modules/ - "**/*.test.ts" - "**/*.spec.ts" - coverage/
ignore: - node_modules/ - "**/*.test.ts" - "**/*.spec.ts" - coverage/
ignore: - node_modules/ - "**/*.test.ts" - "**/*.spec.ts" - coverage/ - Edit a TypeScript file
- Stop containers
- Rebuild the API image
- Restart containers
- Wait for services to initialize
- Test the change - Run your local AI stack with Docker Compose
- Use sync for source files
- Use rebuild for dependency and build configuration changes
- Use sync+restart when a process cannot hot reload by itself
- Keep Redis, Postgres, and other services running while you iterate on the code