This is an automated email from the ASF dual-hosted git repository.
frankvicky pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/kafka.git
The following commit(s) were added to refs/heads/trunk by this push:
new b2c1a0fb9ff KAFKA-18841: Enable to test docker image locally (#19028)
b2c1a0fb9ff is described below
commit b2c1a0fb9ffbf19713362b7a5fba3d1a24e24338
Author: PoAn Yang <[email protected]>
AuthorDate: Tue Aug 26 10:30:14 2025 +0800
KAFKA-18841: Enable to test docker image locally (#19028)
### Case 1: no --kafka-url and --kafka-archive
Should fail. One of argument (--kafka-url/--kafka-archive) is required.
```
> python docker_build_test.py apache/kafka --image-tag KAFKA-18841
--image-type jvm --build
usage: docker_build_test.py [-h] [--image-tag TAG] [--image-type
{jvm,native}] [--build] [--test] (--kafka-url KAFKA_URL |
--kafka-archive KAFKA_ARCHIVE) image
docker_build_test.py: error: one of the arguments --kafka-url/-u
--kafka-archive/-a is required
```
### Case 2: --kafka-url with native
```
> python docker_build_test.py apache/kafka --image-tag KAFKA-18841
--image-type native --kafka-url
https://dist.apache.org/repos/dist/dev/kafka/4.0.0-rc0/kafka_2.13-4.0.0.tgz
--build
```
### Case 3: --karka-url with jvm
```
> python docker_build_test.py apache/kafka --image-tag KAFKA-18841
--image-type jvm --kafka-url
https://dist.apache.org/repos/dist/dev/kafka/4.0.0-rc0/kafka_2.13-4.0.0.tgz
--build
```
### Case 4: --kafka-archive with native
```
> ./gradlew clean releaseTarGz
> cd docker
> python docker_build_test.py apache/kafka --image-tag KAFKA-18841
--image-type native --kafka-archive
</absolute/path/to/core/build/distributions/kafka_2.13-4.1.0-SNAPSHOT.tgz>
--build
```
### Case 5: --kafka-archive with jvm
```
> ./gradlew clean releaseTarGz
> cd docker
> python docker_build_test.py apache/kafka --image-tag KAFKA-18841
--image-type jvm --kafka-archive
</absolute/path/to/core/build/distributions/kafka_2.13-4.1.0-SNAPSHOT.tgz>
--build
```
Reviewers: Vedarth Sharma <[email protected]>, Chia-Ping Tsai
<[email protected]>, TengYao Chi <[email protected]>
---------
Signed-off-by: PoAn Yang <[email protected]>
---
docker/README.md | 4 ++++
docker/common.py | 4 +++-
docker/docker_build_test.py | 18 +++++++++-------
docker/jvm/Dockerfile | 52 +++++++++++++++++++++++++++++----------------
docker/native/Dockerfile | 19 ++++++++++-------
5 files changed, 62 insertions(+), 35 deletions(-)
diff --git a/docker/README.md b/docker/README.md
index 9c2916d9293..c4b9d49d0ea 100644
--- a/docker/README.md
+++ b/docker/README.md
@@ -130,6 +130,10 @@ python docker_build_test.py kafka/test --image-tag=3.6.0
--image-type=jvm --kafk
```
python docker_build_test.py kafka/test --image-tag=3.8.0 --image-type=native
--kafka-url=https://archive.apache.org/dist/kafka/3.8.0/kafka_2.13-3.8.0.tgz
```
+- Example(local build archive with jvm or native image type) :- To build and
test an image named test with local build archive
+```
+python docker_build_test.py kafka/test --image-tag=local-build
--image-type=<jvm/native>
--kafka-archive=</absolute/path/to/core/build/distributions/kafka_2.13-4.1.0-SNAPSHOT.tgz>
+```
Creating a Release Candidate
----------------------------
diff --git a/docker/common.py b/docker/common.py
index 9c0f901823f..f04a484a187 100644
--- a/docker/common.py
+++ b/docker/common.py
@@ -33,12 +33,14 @@ def get_input(message):
raise ValueError("This field cannot be empty")
return value
-def build_docker_image_runner(command, image_type):
+def build_docker_image_runner(command, image_type, kafka_archive=None):
temp_dir_path = tempfile.mkdtemp()
current_dir = os.path.dirname(os.path.realpath(__file__))
copy_tree(f"{current_dir}/{image_type}", f"{temp_dir_path}/{image_type}")
copy_tree(f"{current_dir}/resources",
f"{temp_dir_path}/{image_type}/resources")
copy_file(f"{current_dir}/server.properties",
f"{temp_dir_path}/{image_type}")
+ if kafka_archive:
+ copy_file(kafka_archive, f"{temp_dir_path}/{image_type}/kafka.tgz")
command = command.replace("$DOCKER_FILE",
f"{temp_dir_path}/{image_type}/Dockerfile")
command = command.replace("$DOCKER_DIR", f"{temp_dir_path}/{image_type}")
try:
diff --git a/docker/docker_build_test.py b/docker/docker_build_test.py
index 793148573f3..fab6e65263d 100755
--- a/docker/docker_build_test.py
+++ b/docker/docker_build_test.py
@@ -25,9 +25,11 @@ Usage:
Example command:-
docker_build_test.py <image_name> --image-tag <image_tag> --image-type
<image_type> --kafka-url <kafka_url>
+ docker_build_test.py <image_name> --image-tag <image_tag> --image-type
<image_type> --kafka-archive <kafka_archive>
This command will build an image with <image_name> as image name,
<image_tag> as image_tag (it will be latest by default),
<image_type> as image type (jvm by default), <kafka_url> for the kafka
inside the image and run tests on the image.
+ <kafka_archive> can be passed as an alternative to <kafka_url> to use
a local kafka archive. The path of kafka_archive should be absolute.
-b can be passed as additional argument if you just want to build the
image.
-t can be passed if you just want to run tests on the image.
"""
@@ -41,10 +43,6 @@ from common import execute, build_docker_image_runner
import tempfile
import os
-def build_docker_image(image, tag, kafka_url, image_type):
- image = f'{image}:{tag}'
- build_docker_image_runner(f"docker build -f $DOCKER_FILE -t {image}
--build-arg kafka_url={kafka_url} --build-arg build_date={date.today()}
$DOCKER_DIR", image_type)
-
def run_docker_tests(image, tag, kafka_url, image_type):
temp_dir_path = tempfile.mkdtemp()
try:
@@ -69,16 +67,20 @@ if __name__ == '__main__':
parser.add_argument("image", help="Image name that you want to keep for
the Docker image")
parser.add_argument("--image-tag", "-tag", default="latest", dest="tag",
help="Image tag that you want to add to the image")
parser.add_argument("--image-type", "-type", choices=["jvm", "native"],
default="jvm", dest="image_type", help="Image type you want to build")
- parser.add_argument("--kafka-url", "-u", dest="kafka_url", help="Kafka url
to be used to download kafka binary tarball in the docker image")
parser.add_argument("--build", "-b", action="store_true",
dest="build_only", default=False, help="Only build the image, don't run tests")
parser.add_argument("--test", "-t", action="store_true", dest="test_only",
default=False, help="Only run the tests, don't build the image")
+
+ archive_group = parser.add_mutually_exclusive_group(required=True)
+ archive_group.add_argument("--kafka-url", "-u", dest="kafka_url",
help="Kafka url to be used to download kafka binary tarball in the docker
image")
+ archive_group.add_argument("--kafka-archive", "-a", dest="kafka_archive",
help="Kafka archive to be used to extract kafka binary tarball in the docker
image")
+
args = parser.parse_args()
if args.build_only or not (args.build_only or args.test_only):
if args.kafka_url:
- build_docker_image(args.image, args.tag, args.kafka_url,
args.image_type)
- else:
- raise ValueError("--kafka-url is a required argument for docker
image")
+ build_docker_image_runner(f"docker build -f $DOCKER_FILE -t
{args.image}:{args.tag} --build-arg kafka_url={args.kafka_url} --build-arg
build_date={date.today()} --no-cache --progress=plain $DOCKER_DIR",
args.image_type)
+ elif args.kafka_archive:
+ build_docker_image_runner(f"docker build -f $DOCKER_FILE -t
{args.image}:{args.tag} --build-arg build_date={date.today()} --no-cache
--progress=plain $DOCKER_DIR", args.image_type, args.kafka_archive)
if args.test_only or not (args.build_only or args.test_only):
run_docker_tests(args.image, args.tag, args.kafka_url, args.image_type)
diff --git a/docker/jvm/Dockerfile b/docker/jvm/Dockerfile
index f98f50a2e03..3d2f06820d4 100644
--- a/docker/jvm/Dockerfile
+++ b/docker/jvm/Dockerfile
@@ -23,20 +23,27 @@ USER root
# Get kafka from https://archive.apache.org/dist/kafka and pass the url
through build arguments
ARG kafka_url
+ENV KAFKA_URL=$kafka_url
+
COPY jsa_launch /etc/kafka/docker/jsa_launch
COPY server.properties /etc/kafka/docker/server.properties
+COPY *kafka.tgz kafka.tgz
+
RUN set -eux ; \
apk update ; \
apk upgrade ; \
- apk add --no-cache wget gcompat gpg gpg-agent procps bash; \
+ apk add --no-cache bash; \
+ if [ -n "$KAFKA_URL" ]; then \
+ apk add --no-cache wget gcompat gpg gpg-agent procps; \
+ wget -nv -O kafka.tgz "$KAFKA_URL"; \
+ wget -nv -O kafka.tgz.asc "$KAFKA_URL.asc"; \
+ wget -nv -O KEYS https://downloads.apache.org/kafka/KEYS; \
+ gpg --import KEYS; \
+ gpg --batch --verify kafka.tgz.asc kafka.tgz; \
+ fi; \
mkdir opt/kafka; \
- wget -nv -O kafka.tgz "$kafka_url"; \
- wget -nv -O kafka.tgz.asc "$kafka_url.asc"; \
- tar xfz kafka.tgz -C /opt/kafka --strip-components 1; \
- wget -nv -O KEYS https://downloads.apache.org/kafka/KEYS; \
- gpg --import KEYS; \
- gpg --batch --verify kafka.tgz.asc kafka.tgz
+ tar xfz kafka.tgz -C opt/kafka --strip-components 1;
# Generate jsa files using dynamic CDS for kafka server start command and
kafka storage format command
RUN /etc/kafka/docker/jsa_launch
@@ -53,6 +60,9 @@ USER root
ARG kafka_url
ARG build_date
+ENV KAFKA_URL=$kafka_url
+
+COPY *kafka.tgz kafka.tgz
LABEL org.label-schema.name="kafka" \
org.label-schema.description="Apache Kafka" \
@@ -60,17 +70,25 @@ LABEL org.label-schema.name="kafka" \
org.label-schema.vcs-url="https://github.com/apache/kafka" \
maintainer="Apache Kafka"
-RUN set -eux ; \
+RUN mkdir opt/kafka; \
+ set -eux ; \
apk update ; \
apk upgrade ; \
- apk add --no-cache wget gcompat gpg gpg-agent procps bash; \
- mkdir opt/kafka; \
- wget -nv -O kafka.tgz "$kafka_url"; \
- wget -nv -O kafka.tgz.asc "$kafka_url.asc"; \
- tar xfz kafka.tgz -C /opt/kafka --strip-components 1; \
- wget -nv -O KEYS https://downloads.apache.org/kafka/KEYS; \
- gpg --import KEYS; \
- gpg --batch --verify kafka.tgz.asc kafka.tgz; \
+ apk add --no-cache bash; \
+ if [ -n "$KAFKA_URL" ]; then \
+ apk add --no-cache wget gcompat gpg gpg-agent procps; \
+ wget -nv -O kafka.tgz "$KAFKA_URL"; \
+ wget -nv -O kafka.tgz.asc "$KAFKA_URL.asc"; \
+ tar xfz kafka.tgz -C /opt/kafka --strip-components 1; \
+ wget -nv -O KEYS https://downloads.apache.org/kafka/KEYS; \
+ gpg --import KEYS; \
+ gpg --batch --verify kafka.tgz.asc kafka.tgz; \
+ rm kafka.tgz kafka.tgz.asc KEYS; \
+ apk del wget gpg gpg-agent; \
+ else \
+ tar xfz kafka.tgz -C /opt/kafka --strip-components 1; \
+ rm kafka.tgz; \
+ fi; \
mkdir -p /var/lib/kafka/data /etc/kafka/secrets; \
mkdir -p /etc/kafka/docker /usr/logs /mnt/shared/config; \
adduser -h /home/appuser -D --shell /bin/bash appuser; \
@@ -79,8 +97,6 @@ RUN set -eux ; \
chmod -R ug+w /etc/kafka /var/lib/kafka /etc/kafka/secrets; \
cp /opt/kafka/config/log4j2.yaml /etc/kafka/docker/log4j2.yaml; \
cp /opt/kafka/config/tools-log4j2.yaml
/etc/kafka/docker/tools-log4j2.yaml; \
- rm kafka.tgz kafka.tgz.asc KEYS; \
- apk del wget gpg gpg-agent; \
apk cache clean;
COPY server.properties /etc/kafka/docker/server.properties
diff --git a/docker/native/Dockerfile b/docker/native/Dockerfile
index ca85f35562d..010edbcd51c 100644
--- a/docker/native/Dockerfile
+++ b/docker/native/Dockerfile
@@ -29,15 +29,18 @@ ENV TARGET_PATH="$KAFKA_DIR/kafka.Kafka"
COPY native-image-configs $NATIVE_CONFIGS_DIR
COPY native_command.sh native_command.sh
-RUN mkdir $KAFKA_DIR; \
- microdnf install wget; \
- wget -nv -O kafka.tgz "$KAFKA_URL"; \
- wget -nv -O kafka.tgz.asc "$KAFKA_URL.asc"; \
+COPY *kafka.tgz /app
+
+RUN if [ -n "$KAFKA_URL" ]; then \
+ microdnf install wget; \
+ wget -nv -O kafka.tgz "$KAFKA_URL"; \
+ wget -nv -O kafka.tgz.asc "$KAFKA_URL.asc"; \
+ wget -nv -O KEYS https://downloads.apache.org/kafka/KEYS; \
+ gpg --import KEYS; \
+ gpg --batch --verify kafka.tgz.asc kafka.tgz; \
+ fi; \
+ mkdir $KAFKA_DIR; \
tar xfz kafka.tgz -C $KAFKA_DIR --strip-components 1; \
- wget -nv -O KEYS https://downloads.apache.org/kafka/KEYS; \
- gpg --import KEYS; \
- gpg --batch --verify kafka.tgz.asc kafka.tgz; \
- rm kafka.tgz ; \
# Build the native-binary of the apache kafka using graalVM native-image.
/app/native_command.sh $NATIVE_IMAGE_PATH $NATIVE_CONFIGS_DIR
$KAFKA_LIBS_DIR $TARGET_PATH