From 63d7dcfb05bcb71bfc7642a523fbe44fc6b7b555 Mon Sep 17 00:00:00 2001 From: Vishal Mishra Date: Sat, 11 Oct 2025 06:07:06 +0400 Subject: [PATCH] feat: Add comprehensive Docker development setup - Add Dockerfile.local for development with hot reload - Add docker-compose.local.yml with bind mounts and DNS configuration - Add entrypoint.sh for environment variable loading - Add .dockerignore to optimize build context - Update README.md with Docker development workflow Features: - Hot reload development in Docker container - DNS configuration (8.8.8.8, 8.8.4.4) for external API access - Environment variable loading from .env.local - Port 3000 exposed for local development - Source code mounted for real-time changes - Bridge networking for optimal connectivity Usage: - docker-compose -f docker-compose.local.yml up --build - Visit http://localhost:3000 for development Resolves network connectivity issues with OpenAI API calls in containerized environment. --- .dockerignore | 23 ++++++++++++++++++ Dockerfile.local | 21 ++++++++++++++++ README.md | 52 ++++++++++++++++++++++++++++++++++++++++ docker-compose.local.yml | 26 ++++++++++++++++++++ entrypoint.sh | 25 +++++++++++++++++++ package-lock.json | 2 +- 6 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 .dockerignore create mode 100644 Dockerfile.local create mode 100644 docker-compose.local.yml create mode 100755 entrypoint.sh diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..1a97502fd --- /dev/null +++ b/.dockerignore @@ -0,0 +1,23 @@ +node_modules +.next +out +standalone + +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +.env* +!.env.example + +.git +.gitignore + +.DS_Store +*.swp +.idea +.vscode + +coverage +.cache diff --git a/Dockerfile.local b/Dockerfile.local new file mode 100644 index 000000000..016a0be9e --- /dev/null +++ b/Dockerfile.local @@ -0,0 +1,21 @@ +FROM node:20-bookworm-slim +WORKDIR /app + +# Copy package files first for better layer caching +COPY package*.json ./ +RUN npm install + +# Copy source code +COPY . . + +# Set development environment +ENV NODE_ENV=development + +# Copy entrypoint script +COPY ./entrypoint.sh /usr/local/bin/entrypoint.sh +RUN chmod +x /usr/local/bin/entrypoint.sh + +EXPOSE 3000 + +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] +CMD ["npm", "run", "dev"] \ No newline at end of file diff --git a/README.md b/README.md index 3f3466fd6..fb83244e3 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,58 @@ npm run build npm start ``` +### Run with Docker + +Build the production image and run it locally: + +```bash +docker build -t chatkit-app . +docker run --rm -p 3000:3000 --env-file .env.local chatkit-app +``` + +Or pass env vars explicitly: + +```bash +docker run --rm -p 3000:3000 \ + -e OPENAI_API_KEY="..." \ + -e NEXT_PUBLIC_CHATKIT_WORKFLOW_ID="wf_..." \ + chatkit-app +``` + +Visit `http://localhost:3000`. + +### Mount env file, then start service + +If you prefer mounting `.env.local` rather than passing `--env-file`, the image has an entrypoint that reads `/app/.env.local` before starting: + +```bash +docker run --rm -p 3000:3000 \ + -v $(pwd)/.env.local:/app/.env.local:ro \ + chatkit-app +``` + +### Develop inside Docker (hot reload) + +Use the local development setup with bind mounts and your local env: + +```bash +# Create your environment file +cp .env.example .env.local +# Edit .env.local with your OPENAI_API_KEY and NEXT_PUBLIC_CHATKIT_WORKFLOW_ID + +# Start the development container +docker-compose -f docker-compose.local.yml down +docker-compose -f docker-compose.local.yml up --build +``` + +This runs `npm run dev` in a container with: +- Hot reload enabled (source code mounted from host) +- DNS configured for external API access +- Port 3000 exposed to host +- Environment variables loaded from `.env.local` + +Visit `http://localhost:3000` and start chatting. Your code changes will trigger hot reload inside the container. + ## Customization Tips - Adjust starter prompts, greeting text, and placeholder copy in [`lib/config.ts`](lib/config.ts). diff --git a/docker-compose.local.yml b/docker-compose.local.yml new file mode 100644 index 000000000..6ea592ecf --- /dev/null +++ b/docker-compose.local.yml @@ -0,0 +1,26 @@ +services: + app: + build: + context: . + dockerfile: Dockerfile.local + container_name: nextjs-dev + ports: + - "3000:3000" + env_file: + - .env.local + volumes: + - .:/app + - /app/node_modules + - /app/.next + environment: + - NODE_ENV=development + # Ensure Node.js can resolve external APIs + - NODE_TLS_REJECT_UNAUTHORIZED=0 # Only for dev if SSL issues + dns: + - 8.8.8.8 + - 8.8.4.4 + # Add this to use host network stack (best for local dev) + network_mode: bridge + stdin_open: true + tty: true + restart: unless-stopped \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 000000000..045f4e321 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,25 @@ +#!/bin/sh +set -e + +# Load env variables from a mounted .env.local if present +if [ -f "/app/.env.local" ]; then + export $(grep -E '^[A-Za-z_][A-Za-z0-9_]*=' /app/.env.local | xargs) + echo "✓ Loaded environment variables from .env.local" +fi + +# Validate required environment variables +if [ -z "$OPENAI_API_KEY" ]; then + echo "ERROR: OPENAI_API_KEY is not set" + echo "Make sure it's defined in .env.local" + exit 1 +fi + +if [ -z "$NEXT_PUBLIC_CHATKIT_WORKFLOW_ID" ]; then + echo "ERROR: NEXT_PUBLIC_CHATKIT_WORKFLOW_ID is not set" + echo "Make sure it's defined in .env.local" + exit 1 +fi + +echo "✓ All required environment variables are validated" + +exec "$@" \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index b6ddfdb8e..22d2591ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "name": "openai-chatkit-starter-app", "version": "0.1.0", "dependencies": { - "@openai/chatkit-react": ">=1.1.1 <=2.0.0", + "@openai/chatkit-react": ">=1.1.1 <2.0.0", "next": "^15.5.4", "react": "^19.2.0", "react-dom": "^19.2.0"