# Build stage FROM node:20-slim AS builder WORKDIR /app # Copy package files COPY package*.json ./ # Install dependencies RUN npm ci # Copy source COPY tsconfig.json ./ COPY src ./src # Build RUN npm run build # Production stage - must match playwright version in package.json FROM mcr.microsoft.com/playwright:v1.50.0-jammy WORKDIR /app # Xvfb for headful browser mode (Teams blocks headless browsers). RUN apt-get update && apt-get install -y xvfb && rm -rf /var/lib/apt/lists/* # Copy built files and dependencies COPY --from=builder /app/dist ./dist COPY --from=builder /app/node_modules ./node_modules COPY package*.json ./ COPY .env ./ # Real Google Chrome (stable channel) + its OS deps. Required for anonymous # Teams joins: the bundled Playwright Chromium gets detected as automation # by Teams' light-meetings flow and forced into a lobby + the buggy # preheated-PC code path. Real Chrome bypasses both. Configured via # BOT_BROWSER_CHANNEL=chrome (passed to chromium.launch({ channel })). # See wiki/b-reference/teams-bot/architecture.md → "Browser-Channel". RUN npx playwright install --with-deps chrome # Create output directories RUN mkdir -p output/logs output/screenshots # Set environment ENV NODE_ENV=production ENV BOT_HEADLESS=false ENV DISPLAY=:99 ENV BOT_BROWSER_CHANNEL=chrome # Expose port EXPOSE 4100 # Health check HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD curl -f http://localhost:4100/health || exit 1 # Start Xvfb in background, then run the bot CMD Xvfb :99 -screen 0 1280x720x24 -nolisten tcp & node dist/index.js