Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,14 @@
wiki
.github

# Large, build-irrelevant paths. `make dgraph` only compiles Go + jemalloc, so
# none of these belong in the build context. dgraphtest/datafiles alone is ~24GB
# of LDBC/test fixtures and will fill the Docker VM disk if copied in.
dgraphtest/datafiles
dgraphtest/binaries

# Local build artifacts. NOTE: do NOT ignore `linux/` here -- both local-image
# and local-image-jemalloc stage the built binary there for contrib/Dockerfile's
# `ADD linux /usr/local/bin`, and ignoring it breaks that step.
dgraph/dgraph
test-results.xml
21 changes: 21 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,27 @@ endif
.PHONY: image-local
image-local: local-image ## Alias for local-image

# Overridable knobs for local-image-jemalloc. BUILD_PLATFORM defaults to the
# host arch so the build (and jemalloc compile) runs natively under Docker
# Desktop; override to linux/amd64 to match amd64 CI (emulated via qemu).
BUILD_PLATFORM ?= linux/$(GOHOSTARCH)
GO_VERSION ?= 1.26

.PHONY: local-image-jemalloc
local-image-jemalloc: ## Build jemalloc-enabled dgraph/dgraph:local by compiling natively in a Linux container (macOS-friendly; mirrors the CI/release build)
@echo "==> Compiling jemalloc-enabled dgraph binary in a Linux container ($(BUILD_PLATFORM), go $(GO_VERSION))"
@mkdir -p linux
@docker build \
--platform=$(BUILD_PLATFORM) \
--build-arg GO_VERSION=$(GO_VERSION) \
--target=artifact \
--output=type=local,dest=./linux \
-f contrib/Dockerfile.build .
@echo "==> Packaging dgraph/dgraph:local via contrib/Dockerfile (same runtime image as CI/CD)"
@docker build --platform=$(BUILD_PLATFORM) -f contrib/Dockerfile -t dgraph/dgraph:local .
@rm -rf linux
@echo "==> Done: dgraph/dgraph:local is in Docker Desktop ($(BUILD_PLATFORM), jemalloc enabled)"

.PHONY: clean
clean: ## Clean build artifacts
$(MAKE) -C dgraph clean
Expand Down
19 changes: 17 additions & 2 deletions contrib/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ RUN set -eu; \
curl \
iputils-ping \
jq \
libjemalloc-dev \
less \
sysstat \
gnupg \
Expand All @@ -44,5 +43,21 @@ ADD linux /usr/local/bin
RUN mkdir /dgraph
WORKDIR /dgraph

ENV GODEBUG=madvdontneed=1
# jemalloc tuning knob. The binary statically links jemalloc (built with
# --with-jemalloc-prefix=je_ and a compile-time
# --with-malloc-conf='background_thread:true,metadata_thp:auto'; see
# dgraph/Makefile), so no libjemalloc shared object is loaded at runtime.
# Because of the je_ prefix, the runtime override variable is JE_MALLOC_CONF,
# not the standard MALLOC_CONF. To tighten RSS return under a cgroup memory
# limit, run with e.g.
# -e JE_MALLOC_CONF=dirty_decay_ms:5000,muzzy_decay_ms:5000
# (background_thread stays on via the compile-time default).
# On a CPU-limited container also consider narenas:<GOMAXPROCS> or
# percpu_arena:percpu -- jemalloc sizes arenas from the CPUs it detects (cpuset,
# not the CFS quota), so it over-allocates arenas under a --cpus limit. Full
# option reference: https://jemalloc.net/jemalloc.3.html
#
# The former GODEBUG=madvdontneed=1 was removed: MADV_DONTNEED is the Go runtime
# default since Go 1.16, and it only ever governed the Go heap, never jemalloc's
# off-heap arenas where Dgraph's large allocations live. It was a no-op here.
CMD ["dgraph"]
45 changes: 45 additions & 0 deletions contrib/Dockerfile.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# syntax=docker/dockerfile:1
# Multi-stage builder for `make local-image-jemalloc`.
#
# Compiles a jemalloc-enabled, CGO, native-Linux dgraph binary the same way CI
# and the release build do -- natively inside a Linux container -- so no
# macOS->Linux cross-compilation is required. (That cross-compile is exactly why
# the plain `local-image` target ships a non-jemalloc binary on macOS: the
# jemalloc static archive would have to be cross-built for the Linux target.)
# BuildKit exports the compiled binary to ./linux via `--output=type=local`, and
# contrib/Dockerfile then packages it into the same runtime image CI/CD publishes.

ARG GO_VERSION=1.26

FROM golang:${GO_VERSION} AS builder
# dgraph/Makefile's `jemalloc` target downloads jemalloc 5.3.1 and builds it from
# source, statically linking /usr/local/lib/libjemalloc.a with the baked
# malloc_conf (background_thread:true,metadata_thp:auto). That needs a C/C++
# toolchain plus curl/bzip2 to fetch and unpack the release tarball.
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
bzip2 \
ca-certificates \
curl \
git \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /src
# Prime the module cache first so dependency downloads survive source-only edits.
COPY go.mod go.sum ./
RUN --mount=type=cache,target=/go/pkg/mod go mod download

COPY . .
# `make dgraph` builds jemalloc from source and compiles with the default
# BUILD_TAGS=jemalloc and CGO enabled: the exact CI/release build. USER_ID
# resolves to 0 (root) in the container, so the jemalloc `make install` step
# needs no sudo.
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
make dgraph

# Export-only stage. `docker build --target=artifact --output=type=local,dest=./linux`
# writes this stage's root filesystem to the host, producing ./linux/dgraph for
# contrib/Dockerfile's `ADD linux /usr/local/bin`.
FROM scratch AS artifact
COPY --from=builder /src/dgraph/dgraph /dgraph
2 changes: 1 addition & 1 deletion dgraph/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ jemalloc:
@if [ -z "$(HAS_JEMALLOC)" ] ; then \
mkdir -p /tmp/jemalloc-temp && cd /tmp/jemalloc-temp ; \
echo "Downloading jemalloc" ; \
curl -f -s -L ${JEMALLOC_URL} -o jemalloc.tar.bz2 ; \
curl -f -s -L ${JEMALLOC_URL} -o jemalloc.tar.bz2 && \
tar xjf ./jemalloc.tar.bz2 ; \
cd jemalloc-5.3.1 ; \
sed -i.bak 's|std::__throw_bad_alloc()|throw std::bad_alloc()|g' src/jemalloc_cpp.cpp ; \
Expand Down
Loading