# Multi-stage Dockerfile for sirius-engine # # No external GHCR base images: utility Go binaries and engine runtime tools # (Nmap from source, RustScan, PowerShell) are built in this file. # # Stages: utility-go-binaries, nmap-builder, engine-runtime-base, builder, # development, runtime. # ───────────────────────────────────────────────────────────────────────────── # Utility binaries: system-monitor + administrator # ───────────────────────────────────────────────────────────────────────────── FROM golang:1.24-alpine AS utility-go-binaries RUN apk add --no-cache git ca-certificates tzdata RUN git clone https://github.com/SiriusScan/app-system-monitor.git /tmp/system-monitor && \ cd /tmp/system-monitor && \ go mod download && \ CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o /usr/local/bin/system-monitor main.go && \ rm -rf /tmp/system-monitor RUN git clone https://github.com/SiriusScan/app-administrator.git /tmp/administrator && \ cd /tmp/administrator && \ go mod download && \ CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o /usr/local/bin/administrator main.go && \ rm -rf /tmp/administrator # ───────────────────────────────────────────────────────────────────────────── # Nmap compiled from source (build stage only; not shipped in final layers) # ───────────────────────────────────────────────────────────────────────────── FROM ubuntu:22.04 AS nmap-builder ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ apt-get install -y --no-install-recommends \ build-essential \ libpcap-dev \ libssl-dev \ libssh-dev \ libicu-dev \ automake \ autoconf \ libtool \ perl \ wget \ ca-certificates \ && rm -rf /var/lib/apt/lists/* RUN cd /tmp && \ wget -q https://nmap.org/dist/nmap-7.95.tar.bz2 && \ tar xjf nmap-7.95.tar.bz2 && \ cd nmap-7.95 && \ touch aclocal.m4 configure Makefile.in config.h.in && \ find . -name Makefile.in -exec touch {} \; && \ ./configure --without-zenmap --without-nmap-update --without-ndiff && \ make -j$(nproc) && \ make install && \ cd / && \ rm -rf /tmp/nmap-7.95 /tmp/nmap-7.95.tar.bz2 # ───────────────────────────────────────────────────────────────────────────── # Engine runtime base: Nmap binaries + RustScan + PowerShell + runtime packages # ───────────────────────────────────────────────────────────────────────────── FROM ubuntu:22.04 AS engine-runtime-base ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ apt-get install -y --no-install-recommends \ git \ ca-certificates \ tzdata \ libpcap0.8 \ libpcap-dev \ postgresql-client \ libicu70 \ libssl3 \ libssh-4 \ curl \ wget \ bash \ dos2unix \ unzip \ procps \ && rm -rf /var/lib/apt/lists/* COPY --from=nmap-builder /usr/local/bin/nmap /usr/local/bin/nmap COPY --from=nmap-builder /usr/local/share/nmap /usr/local/share/nmap RUN ARCH=$(uname -m) && \ case "$ARCH" in \ "aarch64") \ wget -q https://github.com/bee-san/RustScan/releases/latest/download/aarch64-linux-rustscan.zip && \ unzip aarch64-linux-rustscan.zip && \ mv rustscan /usr/local/bin/ && \ chmod +x /usr/local/bin/rustscan && \ rm aarch64-linux-rustscan.zip \ ;; \ "x86_64") \ wget -q https://github.com/bee-san/RustScan/releases/latest/download/x86_64-linux-rustscan.tar.gz.zip && \ unzip x86_64-linux-rustscan.tar.gz.zip && \ tar -xzf x86_64-linux-rustscan.tar.gz && \ mv rustscan /usr/local/bin/ && \ chmod +x /usr/local/bin/rustscan && \ rm x86_64-linux-rustscan.tar.gz.zip x86_64-linux-rustscan.tar.gz \ ;; \ *) echo "Unsupported architecture: $ARCH" && exit 1 ;; \ esac RUN mkdir -p /opt/microsoft/powershell && \ cd /opt/microsoft/powershell && \ ARCH=$(uname -m) && \ case "$ARCH" in \ "aarch64") \ wget -q https://github.com/PowerShell/PowerShell/releases/download/v7.4.6/powershell-7.4.6-linux-arm64.tar.gz && \ tar -xf powershell-7.4.6-linux-arm64.tar.gz && \ rm powershell-7.4.6-linux-arm64.tar.gz \ ;; \ "x86_64") \ wget -q https://github.com/PowerShell/PowerShell/releases/download/v7.4.6/powershell-7.4.6-linux-x64.tar.gz && \ tar -xf powershell-7.4.6-linux-x64.tar.gz && \ rm powershell-7.4.6-linux-x64.tar.gz \ ;; \ *) echo "Unsupported architecture: $ARCH" && exit 1 ;; \ esac && \ chmod +x /opt/microsoft/powershell/pwsh && \ ln -s /opt/microsoft/powershell/pwsh /usr/bin/pwsh ENV PATH="/usr/local/bin:${PATH}" RUN command -v bash >/dev/null && \ command -v curl >/dev/null && \ command -v nmap >/dev/null && \ command -v rustscan >/dev/null && \ command -v pwsh >/dev/null && \ command -v psql >/dev/null && \ command -v pkill >/dev/null # ───────────────────────────────────────────────────────────────────────────── # Builder: engine Go services (CGO + libpcap for app-scanner) # ───────────────────────────────────────────────────────────────────────────── FROM golang:1.24-bullseye AS builder WORKDIR /build RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y \ git \ ca-certificates \ tzdata \ build-essential \ libpcap-dev \ && rm -rf /var/lib/apt/lists/* # Build arguments for submodule commit SHAs. # # Pin policy (enforced by .github/workflows/check-pin-consistency.yml): # - These ARG defaults are the canonical pins. CI fallbacks in # .github/workflows/ci.yml (build-engine, build-api) MUST match. # - Floating refs (main/master) are forbidden; use a full SHA or a tag. # - When a minor-project is bumped, update the ARG default here, the # CI fallback, and SHA-AUDIT-2026-04.md (or its successor) in one PR. # # Audit doc: documentation/dev-notes/SHA-AUDIT-2026-04.md ARG GO_API_COMMIT_SHA=v0.0.18 ARG APP_SCANNER_COMMIT_SHA=a031480cc7e0dc4a1cb09bdcfafedd89fbc61dfd ARG APP_TERMINAL_COMMIT_SHA=5745e43ca1f2ad3936a02a51cc77bfcf33ee95c1 ARG SIRIUS_NSE_COMMIT_SHA=a58e8c5330b49bd8f4e93c27e340c43c1fa89fa9 ARG APP_AGENT_COMMIT_SHA=9311f3805db9cc08740f1b588b6f3bff9191c9dd ARG PINGPP_COMMIT_SHA=9508a16c40a49746feb7cab4b8c1c358246169b0 WORKDIR /repos # Clone go-api (needed as a dependency by other components) RUN git clone https://github.com/SiriusScan/go-api.git && \ cd go-api && \ git checkout ${GO_API_COMMIT_SHA} && \ go mod tidy # Clone ping++ (fingerprinting engine, needed by app-scanner) RUN git clone https://github.com/SiriusScan/pingpp.git "ping++" && \ cd "ping++" && \ git checkout ${PINGPP_COMMIT_SHA} # Clone and build app-scanner (CGO_ENABLED=1, requires libpcap). # All previous inline sed patches against internal/scan/manager.go have been # upstreamed in app-scanner@ca1ef2f. See documentation/dev-notes/SHA-AUDIT-2026-04.md. RUN git clone https://github.com/SiriusScan/app-scanner.git && \ cd app-scanner && \ git checkout ${APP_SCANNER_COMMIT_SHA} && \ go mod download && \ CGO_ENABLED=1 GOOS=linux go build -ldflags="-w -s" -o scanner main.go # Clone and build app-terminal RUN git clone https://github.com/SiriusScan/app-terminal.git && \ cd app-terminal && \ git checkout ${APP_TERMINAL_COMMIT_SHA} && \ go mod download && \ CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o terminal cmd/main.go # Clone and build app-agent RUN git clone https://github.com/SiriusScan/app-agent.git && \ cd app-agent && \ git checkout ${APP_AGENT_COMMIT_SHA} && \ go mod download && \ CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o agent cmd/agent/main.go && \ CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o server cmd/server/main.go # Clone sirius-nse (Nmap script library, no compilation needed) RUN git clone https://github.com/SiriusScan/sirius-nse.git && \ cd sirius-nse && \ git checkout ${SIRIUS_NSE_COMMIT_SHA} # ───────────────────────────────────────────────────────────────────────────── # Development: hot-reload on engine-runtime-base # ───────────────────────────────────────────────────────────────────────────── FROM engine-runtime-base AS development WORKDIR /engine # Install Go 1.24 for hot-reload development (air requires Go 1.20+) # Ubuntu 22.04's apt golang is 1.18; air's hugo dep needs 1.20+ RUN ARCH=$(uname -m) && \ case "$ARCH" in \ aarch64|arm64) GOARCH=arm64 ;; \ x86_64|amd64) GOARCH=amd64 ;; \ *) echo "Unsupported: $ARCH" && exit 1 ;; \ esac && \ wget -q "https://go.dev/dl/go1.24.0.linux-${GOARCH}.tar.gz" -O /tmp/go.tar.gz && \ rm -rf /usr/local/go && tar -C /usr/local -xzf /tmp/go.tar.gz && \ rm /tmp/go.tar.gz && \ ln -sf /usr/local/go/bin/go /usr/bin/go ENV PATH="/usr/local/go/bin:${PATH}" # Install a C toolchain so Air can rebuild app-scanner in-container. # app-scanner pulls libpcap via cgo (CGO_ENABLED=1 in app-scanner/.air.toml); # the runtime stage only ships libpcap.so, but the dev stage needs the # full compiler + headers so `go build` succeeds on every save. Keeping # this in the dev stage only avoids bloating the production runtime. RUN apt-get update && \ apt-get install -y --no-install-recommends \ build-essential \ libpcap-dev \ && rm -rf /var/lib/apt/lists/* # Install air for live reloading. go install drops the binary in # $GOPATH/bin (default /root/go/bin) which is not on PATH unless we add # it explicitly. Without this, start-enhanced.sh's `air &` invocations # silently fall back to broken behavior in dev mode. RUN go install github.com/air-verse/air@v1.52.3 ENV PATH="/root/go/bin:${PATH}" # Set up NSE directory structure RUN mkdir -p /opt/sirius/nse && chmod -R 755 /opt/sirius # Create application directories RUN mkdir -p /app-scanner /app-terminal /app-agent /go-api /sirius-nse /system-monitor /app-administrator COPY --from=utility-go-binaries /usr/local/bin/system-monitor /system-monitor/system-monitor COPY --from=utility-go-binaries /usr/local/bin/administrator /app-administrator/administrator RUN chmod +x /system-monitor/system-monitor /app-administrator/administrator # Copy built applications and repositories from builder stage (used as fallback sources) COPY --from=builder /repos/app-scanner /app-scanner-src/ COPY --from=builder /repos/app-terminal /app-terminal-src/ COPY --from=builder /repos/app-agent /app-agent-src/ COPY --from=builder /repos/go-api /go-api/ COPY --from=builder /repos/sirius-nse /sirius-nse/ # Ensure sirius-nse is readable RUN chmod -R 755 /sirius-nse # Remove default Nmap scripts and symlink to sirius-nse RUN rm -rf /usr/local/share/nmap/scripts && \ ln -sf /sirius-nse/scripts /usr/local/share/nmap/scripts # Copy startup scripts. Per-service .air.toml lives inside each minor- # project (app-agent, app-terminal, app-scanner) and is consumed via the # dev-mode bind mount; the engine no longer ships its own orphan copy. COPY start.sh /start.sh COPY start-enhanced.sh /start-enhanced.sh # Fix line endings and validate startup scripts RUN dos2unix /start.sh /start-enhanced.sh && \ chmod +x /start.sh /start-enhanced.sh && \ /bin/bash -n /start-enhanced.sh ENV GO_ENV=development ENV PATH="/root/.cargo/bin:/usr/local/bin:${PATH}" EXPOSE 5174 50051 ENTRYPOINT ["/start-enhanced.sh"] # ───────────────────────────────────────────────────────────────────────────── # Runtime (production) # ───────────────────────────────────────────────────────────────────────────── FROM engine-runtime-base AS runtime WORKDIR /engine # Set up NSE directory structure RUN mkdir -p /opt/sirius/nse && chmod -R 755 /opt/sirius # Create application directories RUN mkdir -p /app-scanner /app-terminal /app-agent /go-api /sirius-nse /system-monitor /app-administrator COPY --from=utility-go-binaries /usr/local/bin/system-monitor /system-monitor/system-monitor COPY --from=utility-go-binaries /usr/local/bin/administrator /app-administrator/administrator RUN chmod +x /system-monitor/system-monitor /app-administrator/administrator # Copy compiled binaries from builder stage COPY --from=builder /repos/app-scanner/scanner /app-scanner/ COPY --from=builder /repos/app-scanner /app-scanner-src/ COPY --from=builder /repos/app-terminal/terminal /app-terminal/ COPY --from=builder /repos/app-terminal /app-terminal-src/ COPY --from=builder /repos/app-agent/agent /app-agent/ COPY --from=builder /repos/app-agent/server /app-agent/ COPY --from=builder /repos/app-agent /app-agent-src/ COPY --from=builder /repos/go-api /go-api/ COPY --from=builder /repos/sirius-nse /sirius-nse/ # Ensure sirius-nse is readable RUN chmod -R 755 /sirius-nse # Remove default Nmap scripts and symlink to sirius-nse RUN rm -rf /usr/local/share/nmap/scripts && \ ln -sf /sirius-nse/scripts /usr/local/share/nmap/scripts # Enforce runtime startup contract RUN command -v bash >/dev/null && \ command -v curl >/dev/null && \ command -v psql >/dev/null && \ command -v pkill >/dev/null && \ command -v nmap >/dev/null && \ command -v rustscan >/dev/null && \ command -v pwsh >/dev/null # Copy startup scripts. The runtime image does not ship a top-level # .air.toml; production builds run pre-compiled binaries (see # start-enhanced.sh), and dev-mode hot reload uses the per-service # .air.toml provided by each bind-mounted minor-project. COPY start.sh /start.sh COPY start-enhanced.sh /start-enhanced.sh # Fix line endings and validate startup scripts RUN dos2unix /start.sh /start-enhanced.sh && \ chmod +x /start.sh /start-enhanced.sh && \ /bin/bash -n /start-enhanced.sh # Non-root user for security RUN groupadd -r sirius && useradd -r -g sirius sirius # Change ownership for non-root execution RUN chown -R sirius:sirius \ /engine /app-scanner /app-terminal /app-agent /go-api \ /sirius-nse /opt/sirius /system-monitor /app-administrator USER sirius EXPOSE 5174 50051 ENV GO_ENV=production ENV PATH="/usr/local/bin:${PATH}" ENTRYPOINT ["/start-enhanced.sh"]