# syntax=docker/dockerfile:1
# check=skip=SecretsUsedInArgOrEnv
FROM node:22.17.1-alpine3.21 AS builder

ARG MCPX_SERVER_PORT
ARG VITE_MCPX_SERVER_URL
ARG VITE_MCPX_SERVER_PORT
ARG VITE_ENABLE_LOGIN

ENV MCPX_SERVER_PORT=${MCPX_SERVER_PORT:-9000}
ENV VITE_MCPX_SERVER_URL=${VITE_MCPX_SERVER_URL:-""}
ENV VITE_WS_URL=${VITE_MCPX_SERVER_URL:-""}
ENV VITE_MCPX_SERVER_PORT=${VITE_MCPX_SERVER_PORT:-$MCPX_SERVER_PORT}
ENV VITE_ENABLE_LOGIN=${VITE_ENABLE_LOGIN:-false}

WORKDIR /mcpx

COPY ./packages ./packages
COPY ./package.json ./package.json
COPY ./package-lock.json ./package-lock.json
COPY ./deps.json ./deps.json
COPY ./build-deps.cjs ./build-deps.cjs
COPY ./.version ./.version

# Read version from .version file and set as build arg
RUN VERSION_VALUE=$(cat .version | tr -d '\n') && \
    echo "${VERSION_VALUE}" > /tmp/version.env

# Create cache directories and install dependencies
RUN npm run build:deps && npm install
RUN npm run install:mcpx-server && npm run build:mcpx-server

WORKDIR /mcpx/packages/ui

# Fix ARM64/x64 rollup platform dependencies issue for Alpine/musl
RUN ARCH=$(uname -m) && \
    if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then \
        npm install @rollup/rollup-linux-arm64-musl --save-dev --no-audit --no-fund 2>/dev/null || true; \
    else \
        npm install @rollup/rollup-linux-x64-musl --save-dev --no-audit --no-fund 2>/dev/null || true; \
    fi

WORKDIR /mcpx
RUN npm run install:ui && npm run build:ui

FROM docker:28.3.2-dind-alpine3.22 AS runner

ARG SERVE_METRICS_PORT
ARG MCPX_PORT
ARG UI_PORT
ARG VITE_MCPX_SERVER_URL
ARG VITE_MCPX_SERVER_PORT
ARG VITE_ENABLE_LOGIN
ARG TARGETPLATFORM
ARG BUILDPLATFORM
ARG LOKI_HOST="log-collector-dev.lunar.dev"
ARG LOKI_USER=""
ARG LOKI_PASSWORD=""


# Log build platform information for debugging
RUN echo "Building on: $BUILDPLATFORM for: $TARGETPLATFORM" && \
    echo "Architecture: $(uname -m)" && \
    echo "Kernel: $(uname -r)"

RUN apk add --no-cache \
    nodejs=22.16.0-r2 \
    npm=11.6.4-r0 \
    python3=3.12.12-r0 \
    py3-pip=25.1.1-r0 \
    uv=0.7.22-r0 \
    iptables=1.8.11-r1 \
    ipset=7.24-r0 \
    libcap=2.76-r0 \
    su-exec=0.2-r3 \
    ca-certificates=20250619-r0 \
    mitmproxy=11.0.0-r0 \
    gcc=14.2.0-r6 \
    musl-dev=1.2.5-r10 \
    python3-dev=3.12.12-r0 \
    linux-headers=6.14.2-r0 \
    rust=1.87.0-r1 \
    cargo=1.87.0-r1 

# Install supervisor with pinned setuptools to avoid pkg_resources warning
RUN pip3 install --no-cache-dir --break-system-packages 'setuptools<81' supervisor==4.2.5

# Copy version from builder stage and set environment variable
COPY --from=builder /tmp/version.env /tmp/version.env


# ---- Environment variables ----

# Public variables - can be overridden by the user
ENV BUILD_SCOPE="all"
ENV LOG_LEVEL="info"
ENV LUNAR_TELEMETRY=true
ENV LUNAR_CONSUMER_NAME="mcpx-anonymous"
ENV LUNAR_URL="https://hosted-gateway.lunar.dev"
ENV LUNAR_API_KEY=""
ENV EXCLUDED_DESTINATIONS="log-collector.lunar.dev,log-collector-stg.lunar.dev,log-collector-dev.lunar.dev,dl-cdn.alpinelinux.org,deb.debian.org,security.debian.org,registry.npmjs.org,auth.docker.io,registry-1.docker.io,production0.cloudflare.docker.com,mcpx-ui,pypi.org,files.pythonhosted.org,archive.ubuntu.com,security.ubuntu.com,mirrors.ubuntu.com,mirrorlist.centos.org,mirror.centos.org,vault.centos.org,cdn.redhat.com,access.redhat.com,mirrors.fedoraproject.org"
# Public variables - can be overridden by the user

# Protected variables - Validate with owner before changing
ENV SERVE_METRICS_PORT=${SERVE_METRICS_PORT:-3000}
ENV UI_PORT=${UI_PORT:-5173}
ENV MCPX_PORT=${MCPX_PORT:-9000}
ENV ENABLE_CONTROL_PLANE_STREAMING=true
ENV ENABLE_CONTROL_PLANE_REST=true
ENV MCPX_SERVER_URL=""
ENV VITE_MCPX_SERVER_URL=${VITE_MCPX_SERVER_URL:-""}
ENV VITE_MCPX_SERVER_PORT=${VITE_MCPX_SERVER_PORT:-$MCPX_PORT}
ENV VITE_WS_URL=${VITE_MCPX_SERVER_URL:-""}
ENV VITE_ENABLE_LOGIN=${VITE_ENABLE_LOGIN:-false}
# Protected variables - Validate with owner before changing

# Private variables - Do not change
ENV MITM_PROXY_LISTEN_PORT=8081
ENV MITM_PROXY_LISTEN_HOST=0.0.0.0
ENV VERSION=""
ENV INSTANCE_ID=""

ENV INTERCEPTION_USER=lunar_interception
ENV INTERCEPTION_USER_UID=1001
ENV INTERCEPTION_USER_GID=1001
ENV LUNAR_USER=lunar
ENV LUNAR_USER_UID=1002
ENV LUNAR_USER_GID=1002
ENV SHARED_GROUP_NAME=lunar_group
ENV SHARED_GROUP_GID=1050
ENV HOME=/${LUNAR_USER}

ENV LOKI_HOST=${LOKI_HOST}
ENV LOKI_USER=${LOKI_USER}
ENV LOKI_PASSWORD=${LOKI_PASSWORD}
ENV MITM_PROXY_CONF_DIR=${HOME}/${INTERCEPTION_USER}/.proxy

# Static OAuth configuration for known servers
ENV GITHUB_OAUTH_CLIENT_ID="Ov23liD20079SUBdPqvh"

# UV, npm, and Docker configuration for non-root users
# We suppress UserWarning from supervisor:
# The pkg_resources package is slated for removal as early as 2025-11-30.
# https://github.com/Supervisor/supervisor/issues/1500
# https://github.com/Supervisor/supervisor/issues/1635
ENV PYTHONWARNINGS="ignore::UserWarning"
ENV UV_CACHE_DIR=${HOME}/.cache/uv
ENV UV_DATA_DIR=${HOME}/.local/share/uv
ENV UV_TOOL_DIR=${HOME}/.local/bin
ENV UV_PYTHON_INSTALL_DIR=${HOME}/.local/share/uv/python
ENV NPM_CONFIG_USERCONFIG=${HOME}/.npm/
ENV NPM_CONFIG_CACHE=${NPM_CONFIG_USERCONFIG}
ENV DOCKER_CONFIG=${HOME}/.docker
ENV PIP_NO_CACHE_DIR=1
ENV PIP_USE_PEP517=1
ENV CARGO_HOME=/tmp/cargo
ENV RUSTUP_HOME=/tmp/rustup

ENV PATH="/tmp/cargo/bin:${UV_TOOL_DIR}:${PATH}"

ENV DIND_ENABLED=true
ENV INTERCEPTION_ENABLED=true
# Private variables - Do not change

# ---- Environment variables ----

# Prepare serve package for ui
RUN npm install -g serve

RUN \
    addgroup -g ${LUNAR_USER_GID} -S ${LUNAR_USER} && \
    addgroup -g ${INTERCEPTION_USER_GID} -S ${INTERCEPTION_USER} && \
    adduser -u ${LUNAR_USER_UID} -S -D -G ${LUNAR_USER} -h ${HOME}/ -s /sbin/nologin ${LUNAR_USER} && \
    adduser -u ${INTERCEPTION_USER_UID} -S -D -G ${INTERCEPTION_USER} -h ${HOME}/${INTERCEPTION_USER} -s /sbin/nologin ${INTERCEPTION_USER} && \
    addgroup -g ${SHARED_GROUP_GID} -S ${SHARED_GROUP_NAME} && \
    addgroup ${LUNAR_USER} ${SHARED_GROUP_NAME} && \
    addgroup ${INTERCEPTION_USER} ${SHARED_GROUP_NAME} && \
    addgroup ${LUNAR_USER} docker

RUN \
    mkdir -p ${UV_CACHE_DIR} ${UV_DATA_DIR} ${UV_TOOL_DIR} ${UV_PYTHON_INSTALL_DIR} ${NPM_CONFIG_USERCONFIG} ${MITM_PROXY_CONF_DIR} ${DOCKER_CONFIG} && \
    mkdir -p /var/log/${LUNAR_USER} ${HOME} ${HOME}/${INTERCEPTION_USER} && \
    chown -R root:${SHARED_GROUP_NAME} /var/log/${LUNAR_USER} && \
    chown -R ${LUNAR_USER}:${LUNAR_USER} ${HOME} && \
    chown -R ${INTERCEPTION_USER}:${INTERCEPTION_USER} ${HOME}/${INTERCEPTION_USER}

# Setup UV directories and permissions for non-root user
RUN mkdir -p ${UV_CACHE_DIR} ${UV_DATA_DIR} ${UV_TOOL_DIR} ${UV_PYTHON_INSTALL_DIR} && \
    mkdir -p ${HOME}/${INTERCEPTION_USER}/.lunar/mitmproxy_conf && \
    chown -R ${INTERCEPTION_USER}:${INTERCEPTION_USER} ${HOME}/${INTERCEPTION_USER}/.lunar && \
    chmod -R 755 ${NPM_CONFIG_USERCONFIG}

WORKDIR ${HOME}

COPY ./rootfs /

# Copy built shared packages
COPY --from=builder --chown=${LUNAR_USER}:${SHARED_GROUP_NAME} /mcpx/packages/shared-model/dist packages/shared-model/dist
COPY --from=builder --chown=${LUNAR_USER}:${SHARED_GROUP_NAME} /mcpx/packages/shared-model/package.json packages/shared-model/package.json

COPY --from=builder --chown=${LUNAR_USER}:${SHARED_GROUP_NAME} /mcpx/packages/toolkit-core/dist packages/toolkit-core/dist
COPY --from=builder --chown=${LUNAR_USER}:${SHARED_GROUP_NAME} /mcpx/packages/toolkit-core/package.json packages/toolkit-core/package.json

COPY --from=builder --chown=${LUNAR_USER}:${SHARED_GROUP_NAME} /mcpx/packages/webapp-protocol/dist packages/webapp-protocol/dist
COPY --from=builder --chown=${LUNAR_USER}:${SHARED_GROUP_NAME} /mcpx/packages/webapp-protocol/package.json packages/webapp-protocol/package.json

# Copy mcpx-server built files and dependencies
COPY --from=builder --chown=${LUNAR_USER}:${SHARED_GROUP_NAME} /mcpx/packages/mcpx-server/dist/src packages/mcpx-server/dist
COPY --from=builder --chown=${LUNAR_USER}:${SHARED_GROUP_NAME} /mcpx/packages/mcpx-server/package.json packages/mcpx-server/package.json


# Copy UI package
COPY --from=builder /mcpx/packages/ui/dist packages/ui
COPY --from=builder /mcpx/node_modules node_modules

# Copy the config generation script
COPY scripts/generate-config.sh /usr/local/bin/generate-config.sh
RUN chmod +x /usr/local/bin/generate-config.sh

RUN \
    chmod +x /usr/local/bin/entrypoint.sh && \
    chmod +x /usr/local/bin/startup.sh
    
# Expose all required ports
EXPOSE ${MCPX_PORT} ${SERVE_METRICS_PORT} ${UI_PORT}

ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
CMD ["/usr/local/bin/startup.sh"] 
