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
71 changes: 71 additions & 0 deletions Dockerfile.custom-registry
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# This image contains the package-registry binary AND a pre-warmed set of packages.

ARG GO_VERSION=1.25.7
ARG BUILDER_IMAGE=golang
ARG RUNNER_IMAGE=cgr.dev/chainguard/wolfi-base

# STAGE 1: Build the 'distribution' tool
FROM --platform=${BUILDPLATFORM:-linux} ${BUILDER_IMAGE}:${GO_VERSION} AS distribution-builder
WORKDIR /src
COPY . .
ARG TARGETPLATFORM
# Build the distribution binary inside its own directory
RUN make -C cmd/distribution release-${TARGETPLATFORM:-linux/amd64}


# STAGE 2: Run the 'distribution' tool to download packages
FROM distribution-builder AS packager
# Copy the custom configuration for the packages we want
COPY ./cmd/distribution/examples/custom-packages.yaml .
# Run the tool. It will create the packages in 'build/distribution/'
RUN ./cmd/distribution/distribution ./cmd/distribution/examples/custom-packages.yaml


# STAGE 3: Build the final 'package-registry' binary
FROM --platform=${BUILDPLATFORM:-linux} ${BUILDER_IMAGE}:${GO_VERSION} AS registry-builder
WORKDIR /src
COPY . .
ARG TARGETPLATFORM
# Build the main package-registry binary from the root directory
RUN make release-${TARGETPLATFORM:-linux/amd64}


# STAGE 4: Final image assembly
FROM ${RUNNER_IMAGE}

# Get dependencies (same as original Dockerfile)
# Mailcap is installed to get mime types information.
RUN if grep -q "Red Hat" /etc/os-release ; then \
microdnf install -y mailcap zip rsync && \
microdnf clean all ; \
else \
apk update && \
apk add mailcap zip rsync curl && \
rm -rf /var/cache/apk/* ; \
fi

WORKDIR /package-registry

# Copy the main binary from the 'registry-builder' stage
COPY --from=registry-builder /src/package-registry .

# --- THIS IS THE KEY STEP ---
# Copy the downloaded packages from the 'packager' stage into the final image
# The registry is configured to look for packages in '/packages/package-registry/'
COPY --from=packager /src/build/distribution/. /packages/package-registry/

# Get in config which expects packages in /packages
COPY config.docker.yml ./config.yml

# Run as non-root user
USER 1000

# Start registry when container is run an expose it on port 8080
EXPOSE 8080
ENTRYPOINT ["./package-registry"]

# Make sure it's accessible from outside the container
ENV EPR_ADDRESS=0.0.0.0:8080

HEALTHCHECK --interval=1s --retries=30 CMD curl --silent --fail localhost:8080/health || exit 1

Comment on lines +24 to +71
Copy link
Copy Markdown
Contributor

@mrodm mrodm Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was wondering if it could be possible to avoid duplicating the Dockerfile that builds the package-registry (stages 3 and 4 of this Dockerfile).

What about using in this Dockerfile the latest docker image of the Package Registry released or a known docker image? It could be set via a build argument so it can be set in the CLI while building the container too.

Given that, maybe this multi-stage Dockerfile could be updated to just 3 stages:

ARG GO_VERSION
ARG BUILDER_IMAGE=golang
# Example: docker.elastic.co/package-registry/package-registry:v1.36.0
ARG EPR_RUNNER_IMAGE

# STAGE 1: Build the 'distribution' tool
FROM --platform=${BUILDPLATFORM:-linux} ${BUILDER_IMAGE}:${GO_VERSION} AS distribution-builder
WORKDIR /src
COPY . .
ARG TARGETPLATFORM
# Build the distribution binary inside its own directory
RUN make -C cmd/distribution release-${TARGETPLATFORM:-linux/amd64}


# STAGE 2: Run the 'distribution' tool to download packages
FROM distribution-builder AS packager
# Copy the custom configuration for the packages we want
COPY ./cmd/distribution/examples/custom-packages.yaml .
# Run the tool. It will create the packages in 'build/distribution/'
RUN ./cmd/distribution/distribution ./cmd/distribution/examples/custom-packages.yaml


# STAGE 3: Final image assembly
FROM ${EPR_RUNNER_IMAGE}

COPY --from=packager /src/build/distribution/. /packages/package-registry/

And in the README, the instructions could be updated to be like:

# Ensure to pick the latest EPR docker image (tag) released as EPR_RUNNER_IMAGE build argument
# Or, it could be used another EPR docker image if needed
# Example using tags:
git fetch --tags
latest_version=$(git tag --sort=version:refname | tail -n 1)
epr_image="docker.elastic.co/package-registry/package-registry:$(latest_version)"

# Or, it could be used another EPR docker image if needed
# Example
epr_image="docker.elastic.co/package-registry/package-registry:v1.36.0"

docker build \
  --build-arg GO_VERSION="$(cat .go-version)" \
  --build-arg EPR_RUNNER_IMAGE="${epr_image}" \
  -f Dockerfile.custom-registry \
  -t custom-package-registry .

This is an example based on tags, but the user building this custom image could be setting directly a specific docker EPR image tag.

WDYT @fred-maussion ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be interesting to keep GO_VERSION and EPR_RUNNER_IMAGE to be without value to force setting those values as build arguments in the docker build command:

ARG GO_VERSION
ARG BUILDER_IMAGE=golang
# Example: docker.elastic.co/package-registry/package-registry:v1.36.0
ARG EPR_RUNNER_IMAGE

33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,39 @@ If you want to run the most recent registry for development, run the main tag.

These images contain only the package registry, they don't contain any package.

#### Build a Custom Docker Package Registry Image

The official Docker container for the Elastic Package Registry includes all available packages for every Kibana version. For development or specific deployments, you might want to build a custom, smaller container that only includes packages compatible with your target Kibana environment. This results in a much smaller image footprint.

To build your own custom Elastic Package Registry container image, follow these steps:

1. **Define Your Package Set**: Create or modify the `cmd/distribution/examples/custom-packages.yaml` file to specify the desired package versions. You can filter by `kibana.version`, `spec.max`, and other criteria. All the available settings are documented in the distribution [README](./cmd/distribution/README.md)

2. **Build the Image**: Run the following command from the root of the repository to build your custom image.

> **Note**: If you use a different configuration file than the default, remember to update the `Dockerfile.custom-registry` accordingly.

```bash
docker build --build-arg GO_VERSION="$(cat .go-version)" -f Dockerfile.custom-registry -t custom-package-registry .
```

**Example: Smaller Image Footprint**

Here is an example of a custom image built with packages compatible with Kibana `>8.18.0` & `>9.0.0`. The resulting image is significantly smaller than the default one.

```bash
docker images

IMAGE ID DISK USAGE CONTENT SIZE EXTRA
custom-package-registry:latest 193b9b282bf2 1.61GB 631MB
```

You can run your custom registry with the following command:

```bash
docker run --rm -it -p 8080:8080 custom-package-registry
```

### Testing with Kibana

The Docker image of Package Registry is just an empty distribution without any packages.
Expand Down
22 changes: 22 additions & 0 deletions cmd/distribution/examples/custom-packages.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Base address of the Package Registry
address: "https://epr.elastic.co"

# Queries are executed with each one of the parameters of the matrix.
matrix:
- spec.max: 3.5
- prerelease: true
spec.max: 3.5

# Queries to execute to discover packages >8.18.0 & >9.0.0.
queries:
- kibana.version: 8.18.0
spec.max: 3.4
- kibana.version: 9.0.0
spec.min: 2.3
spec.max: 3.4


actions:
- print:
- download:
destination: ./build/distribution