diff --git a/.env.example b/.env.example index 11c83e1..711ad2e 100644 --- a/.env.example +++ b/.env.example @@ -4,3 +4,7 @@ OPENAI_API_KEY=your_openai_api_key_here # Browserbase Configuration BROWSERBASE_API_KEY=your_browserbase_api_key_here BROWSERBASE_PROJECT_ID=your_browserbase_project_id_here + +# Docker Configuration +TARGET=development +NODE_ENV=development diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ec385fc --- /dev/null +++ b/Dockerfile @@ -0,0 +1,66 @@ +FROM node:20-alpine AS base + +# Install dependencies only when needed +FROM base AS deps +RUN apk add --no-cache libc6-compat +WORKDIR /app + +# Install pnpm using npm instead of corepack +RUN npm install -g pnpm@latest + +# Install dependencies based on the preferred package manager +COPY package.json pnpm-lock.yaml* ./ +RUN pnpm install --frozen-lockfile + +# Development image +FROM base AS development +WORKDIR /app +RUN npm install -g pnpm@latest +COPY --from=deps /app/node_modules ./node_modules +COPY . . + +# Add debug output +RUN echo "Directory contents:" && ls -la +RUN echo "Node version:" && node -v +RUN echo "PNPM version:" && pnpm -v +RUN echo "Package.json contents:" && cat package.json + +# Use shell form to see the command being executed +CMD echo "Starting development server..." && pnpm dev + +# Rebuild the source code only when needed +FROM base AS builder +WORKDIR /app +RUN npm install -g pnpm@latest +COPY --from=deps /app/node_modules ./node_modules +COPY . . +RUN pnpm build + +# Production image, copy all the files and run next +FROM base AS runner +WORKDIR /app + +ENV NODE_ENV production + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +COPY --from=builder /app/public ./public + +# Set the correct permission for prerender cache +RUN mkdir .next +RUN chown nextjs:nodejs .next + +# Automatically leverage output traces to reduce image size +# https://nextjs.org/docs/advanced-features/output-file-tracing +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static + +USER nextjs + +EXPOSE 3000 + +ENV PORT 3000 +ENV HOSTNAME "0.0.0.0" + +CMD ["node", "server.js"] \ No newline at end of file diff --git a/README.md b/README.md index 104e7a6..025ebe5 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,53 @@ pnpm dev Open [http://localhost:3000](http://localhost:3000) with your browser to see Open Operator in action. +## Docker Deployment + +You can run Open Operator using Docker in both development and production environments. + +### Prerequisites + +- Docker +- Docker Compose + +### Running with Docker + +1. First, copy the example environment variables: + +```bash +cp .env.example .env +``` + +2. Update the `.env` file with your API keys as described in the Getting Started section, and add these variables: +``` +# For development +TARGET=deps +NODE_ENV=development + +# For production +# TARGET=runner +# NODE_ENV=production +``` + +3. Run the application: +```bash +docker compose up --build +``` + +The application will be available at `http://localhost:3000`. + +### Environment Variables for Docker + +The following environment variables can be set in your `.env` file: + +- `TARGET`: Build target ('runner' for production, 'deps' for development) +- `NODE_ENV`: Node environment ('production' or 'development') +- `OPENAI_API_KEY`: Your OpenAI API key +- `BROWSERBASE_API_KEY`: Your Browserbase API key +- `BROWSERBASE_PROJECT_ID`: Your Browserbase project ID +- `NEXT_PUBLIC_POSTHOG_KEY`: (Optional) PostHog API key +- `NEXT_PUBLIC_POSTHOG_HOST`: (Optional) PostHog host URL + ## How It Works Building a web agent is a complex task. You need to understand the user's intent, convert it into headless browser operations, and execute actions, each of which can be incredibly complex on their own. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..7795a24 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,27 @@ +version: '3.8' + +services: + web: + build: + context: . + target: ${TARGET:-development} + image: open-operator + ports: + - "3000:3000" + environment: + - NODE_ENV=${NODE_ENV:-development} + - OPENAI_API_KEY=${OPENAI_API_KEY} + - BROWSERBASE_API_KEY=${BROWSERBASE_API_KEY} + - BROWSERBASE_PROJECT_ID=${BROWSERBASE_PROJECT_ID} + - NEXT_PUBLIC_POSTHOG_KEY=${NEXT_PUBLIC_POSTHOG_KEY} + - NEXT_PUBLIC_POSTHOG_HOST=${NEXT_PUBLIC_POSTHOG_HOST} + volumes: + - .:/app + - /app/node_modules + - /app/.next + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + restart: "no" \ No newline at end of file