# GhydraMCP Docker Image # Ghidra + GhydraMCP Plugin pre-installed for headless binary analysis # # Build: docker build -t ghydramcp:latest -f docker/Dockerfile . # Run: docker run -p 8192:8192 -v /path/to/binaries:/binaries ghydramcp:latest ARG GHIDRA_VERSION=11.4.2 ARG GHIDRA_DATE=20250826 # ============================================================================= # Stage 1: Build the GhydraMCP plugin # ============================================================================= FROM eclipse-temurin:21-jdk-jammy AS builder ARG GHIDRA_VERSION ARG GHIDRA_DATE # Install build dependencies RUN apt-get update && apt-get install -y --no-install-recommends \ curl \ unzip \ maven \ git \ && rm -rf /var/lib/apt/lists/* # Download and extract Ghidra WORKDIR /opt RUN curl -fsSL "https://github.com/NationalSecurityAgency/ghidra/releases/download/Ghidra_${GHIDRA_VERSION}_build/ghidra_${GHIDRA_VERSION}_PUBLIC_${GHIDRA_DATE}.zip" \ -o ghidra.zip \ && unzip -q ghidra.zip \ && rm ghidra.zip \ && mv ghidra_${GHIDRA_VERSION}_PUBLIC ghidra ENV GHIDRA_HOME=/opt/ghidra # Copy GhydraMCP source and build WORKDIR /build COPY pom.xml . COPY src ./src # Build the plugin (skip git-commit-id plugin since .git isn't in Docker context) RUN mvn clean package -P plugin-only -DskipTests \ -Dmaven.gitcommitid.skip=true \ -Dghidra.generic.jar=${GHIDRA_HOME}/Ghidra/Framework/Generic/lib/Generic.jar \ -Dghidra.softwaremodeling.jar=${GHIDRA_HOME}/Ghidra/Framework/SoftwareModeling/lib/SoftwareModeling.jar \ -Dghidra.project.jar=${GHIDRA_HOME}/Ghidra/Framework/Project/lib/Project.jar \ -Dghidra.docking.jar=${GHIDRA_HOME}/Ghidra/Framework/Docking/lib/Docking.jar \ -Dghidra.decompiler.jar=${GHIDRA_HOME}/Ghidra/Features/Decompiler/lib/Decompiler.jar \ -Dghidra.utility.jar=${GHIDRA_HOME}/Ghidra/Framework/Utility/lib/Utility.jar \ -Dghidra.base.jar=${GHIDRA_HOME}/Ghidra/Features/Base/lib/Base.jar # ============================================================================= # Stage 2: Runtime image with Ghidra + GhydraMCP # ============================================================================= # NOTE: Ghidra requires JDK (not JRE) - it checks for javac in LaunchSupport FROM eclipse-temurin:21-jdk-jammy AS runtime ARG GHIDRA_VERSION ARG GHIDRA_DATE LABEL org.opencontainers.image.title="ghydramcp" \ org.opencontainers.image.description="Ghidra + GhydraMCP Plugin for AI-assisted reverse engineering" \ org.opencontainers.image.source="https://github.com/starsong-consulting/GhydraMCP" \ org.opencontainers.image.licenses="Apache-2.0" # Install runtime dependencies RUN apt-get update && apt-get install -y --no-install-recommends \ curl \ unzip \ fontconfig \ libfreetype6 \ && rm -rf /var/lib/apt/lists/* # Create non-root user RUN groupadd -g 1001 ghidra && useradd -u 1001 -g ghidra -m -s /bin/bash ghidra # Download and extract Ghidra (in runtime stage for cleaner image) WORKDIR /opt RUN curl -fsSL "https://github.com/NationalSecurityAgency/ghidra/releases/download/Ghidra_${GHIDRA_VERSION}_build/ghidra_${GHIDRA_VERSION}_PUBLIC_${GHIDRA_DATE}.zip" \ -o ghidra.zip \ && unzip -q ghidra.zip \ && rm ghidra.zip \ && mv ghidra_${GHIDRA_VERSION}_PUBLIC ghidra \ && chown -R ghidra:ghidra /opt/ghidra ENV GHIDRA_HOME=/opt/ghidra ENV PATH="${GHIDRA_HOME}:${PATH}" # Install the GhydraMCP plugin COPY --from=builder /build/target/GhydraMCP-*.zip /tmp/ RUN mkdir -p /opt/ghidra/Ghidra/Extensions \ && unzip -q /tmp/GhydraMCP-*.zip -d /opt/ghidra/Ghidra/Extensions/ \ && rm /tmp/GhydraMCP-*.zip \ && chown -R ghidra:ghidra /opt/ghidra/Ghidra/Extensions/ # Create directories for projects, binaries, and scripts RUN mkdir -p /projects /binaries /home/ghidra/.ghidra /opt/ghidra/scripts \ && chown -R ghidra:ghidra /projects /binaries /home/ghidra /opt/ghidra/scripts # Download Gson JAR for headless script support # (GhydraMCPServer.java requires Gson but headless scripts can't access extension libs) RUN curl -fsSL "https://repo1.maven.org/maven2/com/google/code/gson/gson/2.13.1/gson-2.13.1.jar" \ -o /opt/ghidra/Ghidra/Framework/Generic/lib/gson-2.13.1.jar \ && chown ghidra:ghidra /opt/ghidra/Ghidra/Framework/Generic/lib/gson-2.13.1.jar # Copy the GhydraMCP scripts COPY docker/GhydraMCPServer.java /opt/ghidra/scripts/ COPY docker/ImportRawARM.java /opt/ghidra/scripts/ RUN chown -R ghidra:ghidra /opt/ghidra/scripts/ && chmod 644 /opt/ghidra/scripts/*.java # Copy entrypoint script (755 so ghidra user can read and execute) COPY docker/entrypoint.sh /entrypoint.sh RUN chmod 755 /entrypoint.sh # Switch to non-root user USER ghidra WORKDIR /home/ghidra # Expose the GhydraMCP HTTP API port (and additional ports for multiple instances) EXPOSE 8192 8193 8194 8195 # Default environment ENV GHYDRA_MODE=headless ENV GHYDRA_PORT=8192 ENV GHYDRA_MAXMEM=2G # Healthcheck HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ CMD curl -f http://localhost:${GHYDRA_PORT}/ || exit 1 ENTRYPOINT ["/entrypoint.sh"]