# Build the wheel with uv, install it into a clean runtime image.
FROM python:3.12-slim AS builder

COPY --from=ghcr.io/astral-sh/uv:0.9.7 /uv /usr/local/bin/uv

# Version is stamped into pyproject.toml at build time (the git tag drives it
# in CI); the default keeps plain `docker build` working locally.
ARG VERSION=0.0.0

WORKDIR /src
COPY pyproject.toml uv.lock README.md ./
COPY persona ./persona
RUN sed -i "s/^version = .*/version = \"${VERSION}\"/" pyproject.toml \
    && uv build --wheel --out-dir /dist


FROM python:3.12-slim AS runtime

# `bash` runs whatever the agent asks for, so the image ships the basics an
# agent expects to find on a machine — git, curl, CA certificates.
RUN apt-get update \
    && apt-get install -y --no-install-recommends ca-certificates curl git \
    && rm -rf /var/lib/apt/lists/*

COPY --from=builder /dist /tmp/dist
RUN pip install --no-cache-dir /tmp/dist/*.whl && rm -rf /tmp/dist

# Default workspace the server chdirs into; mount a volume here to keep files.
ENV WORKSPACE_CWD=/workspace
RUN mkdir -p /workspace
WORKDIR /workspace

EXPOSE 9100

ENTRYPOINT ["persona-mcp-workspace"]
CMD ["--host", "0.0.0.0", "--port", "9100"]


# ---------------------------------------------------------------------------
# The `playwright` target: the same server plus browser automation. Built as a
# stage rather than a separate file so it never has to pull the base image
# from a registry — buildx's container driver cannot see locally built tags.
# Select it with `--target playwright`.
FROM runtime AS playwright

ARG NODE_MAJOR=22
ARG PLAYWRIGHT_CLI_VERSION=0.1.19

RUN curl -fsSL https://deb.nodesource.com/setup_${NODE_MAJOR}.x | bash - \
    && apt-get install -y --no-install-recommends nodejs \
    && rm -rf /var/lib/apt/lists/*

RUN npm install -g @playwright/cli@${PLAYWRIGHT_CLI_VERSION} \
    && npm cache clean --force

# Google Chrome rather than bundled Chromium: it is the branded build real
# users run, so sites that sniff the browser behave the same. Playwright
# installs it as a system package from Google's repo (amd64 only, which is why
# this target is amd64 only). PLAYWRIGHT_BROWSERS_PATH still matters for any
# bundled browser added later: outside $HOME and the workspace volume, so a
# mount can never hide it.
ENV PLAYWRIGHT_BROWSERS_PATH=/opt/ms-playwright
RUN playwright-cli install-browser chrome --with-deps \
    && rm -rf /var/lib/apt/lists/*

# /workspace is a volume mount point: anything written there at build time
# disappears the moment a volume is mounted over it. So the initialized
# workspace is baked somewhere else and copied in at startup if absent.
ENV PERSONA_SEED_DIR=/opt/persona/seed
RUN mkdir -p "${PERSONA_SEED_DIR}" \
    && cd "${PERSONA_SEED_DIR}" \
    && playwright-cli install --skills agents

# Pin the browser choice rather than leaving it to autodetection, and disable
# Chrome's sandbox: branded Chrome refuses to start as root without it
# ("Running as root without --no-sandbox is not supported"), where Playwright's
# own Chromium build tolerates it. Consistent with the rest of this server —
# the container, not the browser, is the boundary.
RUN printf '%s\n' \
    '{' \
    '  "browser": {' \
    '    "browserName": "chromium",' \
    '    "launchOptions": {' \
    '      "channel": "chrome",' \
    '      "chromiumSandbox": false' \
    '    }' \
    '  }' \
    '}' > "${PERSONA_SEED_DIR}/.playwright/cli.config.json"

COPY docker/entrypoint-playwright.sh /usr/local/bin/persona-entrypoint
RUN chmod +x /usr/local/bin/persona-entrypoint

ENTRYPOINT ["/usr/local/bin/persona-entrypoint"]
CMD ["--host", "0.0.0.0", "--port", "9100"]


# Last stage wins when no --target is given, so this alias keeps a plain
# `docker build .` producing the base image rather than the playwright one.
FROM runtime AS default
