FROM python:3.11-slim # Create a non-root user RUN useradd -ms /bin/bash mcp WORKDIR /app # Install Node.js, curl, unzip, and system dependencies for Playwright RUN apt-get update && \ apt-get install -y curl unzip && \ # Install Node.js v18.x curl -fsSL https://deb.nodesource.com/setup_18.x | bash - && \ apt-get install -y nodejs && \ # Install common Playwright browser dependencies apt-get install -y --no-install-recommends \ libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdbus-1-3 \ libdrm2 libgbm1 libgtk-3-0 libx11-6 libxcb1 libxcomposite1 libxdamage1 libxext6 \ libxfixes3 libxrandr2 libxtst6 libasound2 libpango-1.0-0 libcairo2 libatspi2.0-0 \ libxshmfence1 libxrandr2 && \ # Clean up apt-get clean && rm -rf /var/lib/apt/lists/* # Copy entrypoint script and make it executable # Note: At this point, /app is owned by root, but entrypoint.sh is copied in. COPY entrypoint.sh /app/ RUN chmod +x /app/entrypoint.sh # Switch to non-root user for Bun installation USER mcp # Install Bun RUN curl -fsSL https://bun.sh/install | bash # Add Bun to PATH for the mcp user ENV BUN_INSTALL="/home/mcp/.bun" ENV PATH="${BUN_INSTALL}/bin:${PATH}" # Switch back to root for global installations using pip USER root RUN pip install --no-cache-dir mcpo uv # --- Playwright Installation Section --- # Create the target Playwright cache directory (owned by root initially) RUN mkdir -p /app/.cache/ms-playwright # Set the environment variable to tell Playwright where to install/find browsers ENV PLAYWRIGHT_BROWSERS_PATH="/app/.cache/ms-playwright" # Install Playwright browsers using npx (as root) RUN npx playwright install chromium --with-deps # --- End of Playwright Section --- # Set general cache directory env var (directory created above) ENV XDG_CACHE_HOME="/app/.cache" # --- Change Ownership Section --- # NOW, change ownership of the entire /app directory and its contents to mcp # This includes /app/entrypoint.sh and /app/.cache and its contents (like playwright browsers) RUN chown -R mcp:mcp /app # --- End of Change Ownership Section --- # Switch back to non-root user for running the application # This user now owns /app and can write config.json into it. USER mcp # Expose the port mcpo will listen on EXPOSE 8000 # Set the entrypoint script (runs as mcp user) ENTRYPOINT ["/app/entrypoint.sh"]