Skip to content

Commit 0ed7dff

Browse files
authored
[8.19] Restructure docker files for docker distributions (#127960) (#128187)
* Restructure docker files for docker distributions (#127960) Restructures docker files for docker distributions - Put Dockerfiles in specific distro specific folders keeping "Dockerfile" naming convention - Allows better ide support - Allows easier renovate integration - Explicitly set base image in dockerfile - simplify renovate configuration - Cleanup DockerBase file to not contain ess fips base image information This lives now in the Dockerfile content directly * Workaround docker test issue * Fix labels for fips image (cherry picked from commit 38c90ca) # Conflicts: # build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/DockerBase.java # distribution/docker/src/docker/dockerfiles/default/Dockerfile # renovate.json * Fix ubuntu based default docker image; also remove muted test * Cleanup dockerfile * Fix merge in docker default * Fix merge issue * Fix exit code 100 on docker build apt-get run
1 parent f484c9f commit 0ed7dff

File tree

6 files changed

+338
-11
lines changed

6 files changed

+338
-11
lines changed

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/DockerBase.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* This class models the different Docker base images that are used to build Docker distributions of Elasticsearch.
1414
*/
1515
public enum DockerBase {
16-
DEFAULT("ubuntu:20.04", "", "apt-get", "Dockerfile"),
16+
DEFAULT("ubuntu:20.04", "", "apt-get", "dockerfiles/default/Dockerfile"),
1717

1818
// "latest" here is intentional, since the image name specifies "8"
1919
UBI("docker.elastic.co/ubi8/ubi-minimal:latest", "-ubi8", "microdnf", "Dockerfile"),
@@ -22,13 +22,11 @@ public enum DockerBase {
2222
IRON_BANK("${BASE_REGISTRY}/${BASE_IMAGE}:${BASE_TAG}", "-ironbank", "yum", "Dockerfile"),
2323

2424
// Chainguard based wolfi image with latest jdk
25-
// This is usually updated via renovatebot
26-
// spotless:off
2725
WOLFI(
28-
"docker.elastic.co/wolfi/chainguard-base:latest@sha256:1c7f5aa0e7997455b8500d095c7a90e617102d3941eb0757ac62cfea509e09b9",
26+
null,
2927
"-wolfi",
3028
"apk",
31-
"Dockerfile"
29+
"dockerfiles/wolfi/Dockerfile"
3230
),
3331
// spotless:on
3432

@@ -37,10 +35,10 @@ public enum DockerBase {
3735
CLOUD_ESS(null, "-cloud-ess", "apk", "Dockerfile.ess"),
3836

3937
CLOUD_ESS_FIPS(
40-
"docker.elastic.co/wolfi/chainguard-base-fips:sha256-ebfc3f1d7dba992231747a2e05ad1b859843e81b5e676ad342859d7cf9e425a7",
38+
null,
4139
"-cloud-ess-fips",
4240
"apk",
43-
"Dockerfile.ess-fips"
41+
"dockerfiles/cloud_ess_fips/Dockerfile"
4442
);
4543

4644
private final String image;

distribution/docker/build.gradle

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,8 +462,10 @@ void addBuildDockerImageTask(Architecture architecture, DockerBase base) {
462462

463463
baseImages = [baseImage]
464464
buildArgs = buildArgsMap
465-
} else {
465+
} else if(base.image != null) {
466466
baseImages = [base.image]
467+
} else {
468+
baseImages = []
467469
}
468470

469471
Provider<DockerSupportService> serviceProvider = GradleUtils.getBuildService(

distribution/docker/src/docker/Dockerfile.ess-fips renamed to distribution/docker/src/docker/dockerfiles/cloud_ess_fips/Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
# Extract Elasticsearch artifact
2525
################################################################################
2626
27-
FROM ${base_image} AS builder
27+
FROM docker.elastic.co/wolfi/chainguard-base-fips:latest@sha256:ebfc3f1d7dba992231747a2e05ad1b859843e81b5e676ad342859d7cf9e425a7 AS builder
2828
2929
# Install required packages to extract the Elasticsearch distribution
3030
RUN <%= retry.loop(package_manager, "export DEBIAN_FRONTEND=noninteractive && ${package_manager} update && ${package_manager} update && ${package_manager} add --no-cache curl") %>
@@ -103,7 +103,7 @@ WORKDIR /usr/share/elasticsearch/config
103103
# Add entrypoint
104104
################################################################################
105105

106-
FROM ${base_image}
106+
FROM docker.elastic.co/wolfi/chainguard-base-fips:latest@sha256:ebfc3f1d7dba992231747a2e05ad1b859843e81b5e676ad342859d7cf9e425a7
107107

108108
RUN <%= retry.loop(package_manager,
109109
"export DEBIAN_FRONTEND=noninteractive && \n" +
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
<% /*
2+
This file is passed through Groovy's SimpleTemplateEngine, so dollars and backslashes
3+
have to be escaped in order for them to appear in the final Dockerfile. You
4+
can also comment out blocks, like this one. See:
5+
6+
https://docs.groovy-lang.org/latest/html/api/groovy/text/SimpleTemplateEngine.html
7+
8+
We use control-flow tags in this file to conditionally render the content. The
9+
layout/presentation here has been adjusted so that it looks reasonable when rendered,
10+
at the slight expense of how it looks here.
11+
12+
Note that this file is also filtered to squash together newlines, so we can
13+
add as many newlines here as necessary to improve legibility.
14+
*/ %>
15+
16+
################################################################################
17+
# Build stage 1 `builder`:
18+
# Extract Elasticsearch artifact
19+
################################################################################
20+
21+
FROM ${base_image} AS builder
22+
23+
# Install required packages to extract the Elasticsearch distribution
24+
RUN apt-get update -y && DEBIAN_FRONTEND=noninteractive apt-get install -y curl
25+
26+
# `tini` is a tiny but valid init for containers. This is used to cleanly
27+
# control how ES and any child processes are shut down.
28+
#
29+
# The tini GitHub page gives instructions for verifying the binary using
30+
# gpg, but the keyservers are slow to return the key and this can fail the
31+
# build. Instead, we check the binary against the published checksum.
32+
RUN set -eux ; \\
33+
tini_bin="" ; \\
34+
case "\$(arch)" in \\
35+
aarch64) tini_bin='tini-arm64' ;; \\
36+
x86_64) tini_bin='tini-amd64' ;; \\
37+
*) echo >&2 ; echo >&2 "Unsupported architecture \$(arch)" ; echo >&2 ; exit 1 ;; \\
38+
esac ; \\
39+
curl --retry 10 -S -L -O https://github.com/krallin/tini/releases/download/v0.19.0/\${tini_bin} ; \\
40+
curl --retry 10 -S -L -O https://github.com/krallin/tini/releases/download/v0.19.0/\${tini_bin}.sha256sum ; \\
41+
sha256sum -c \${tini_bin}.sha256sum ; \\
42+
rm \${tini_bin}.sha256sum ; \\
43+
mv \${tini_bin} /bin/tini ; \\
44+
chmod 0555 /bin/tini
45+
46+
RUN mkdir /usr/share/elasticsearch
47+
WORKDIR /usr/share/elasticsearch
48+
49+
RUN curl --retry 10 -S -L --output /tmp/elasticsearch.tar.gz https://artifacts-no-kpi.elastic.co/downloads/elasticsearch/elasticsearch-${version}-linux-\$(arch).tar.gz
50+
51+
RUN tar -zxf /tmp/elasticsearch.tar.gz --strip-components=1
52+
53+
# The distribution includes a `config` directory, no need to create it
54+
COPY ${config_dir}/elasticsearch.yml config/
55+
COPY ${config_dir}/log4j2.properties config/log4j2.docker.properties
56+
57+
# 1. Configure the distribution for Docker
58+
# 2. Create required directory
59+
# 3. Move the distribution's default logging config aside
60+
# 4. Move the generated docker logging config so that it is the default
61+
# 5. Reset permissions on all directories
62+
# 6. Reset permissions on all files
63+
# 7. Make CLI tools executable
64+
# 8. Make some directories writable. `bin` must be writable because
65+
# plugins can install their own CLI utilities.
66+
# 9. Make some files writable
67+
RUN sed -i -e 's/ES_DISTRIBUTION_TYPE=tar/ES_DISTRIBUTION_TYPE=docker/' bin/elasticsearch-env && \\
68+
mkdir data && \\
69+
mv config/log4j2.properties config/log4j2.file.properties && \\
70+
mv config/log4j2.docker.properties config/log4j2.properties && \\
71+
find . -type d -exec chmod 0555 {} + && \\
72+
find . -type f -exec chmod 0444 {} + && \\
73+
chmod 0555 bin/* jdk/bin/* jdk/lib/jspawnhelper modules/x-pack-ml/platform/linux-*/bin/* && \\
74+
chmod 0775 bin config config/jvm.options.d data logs plugins && \\
75+
find config -type f -exec chmod 0664 {} +
76+
77+
78+
################################################################################
79+
# Build stage 2 (the actual Elasticsearch image):
80+
#
81+
# Copy elasticsearch from stage 1
82+
# Add entrypoint
83+
################################################################################
84+
85+
FROM ${base_image}
86+
87+
# Change default shell to bash, then install required packages with retries.
88+
RUN yes no | dpkg-reconfigure dash && \\
89+
<%= retry.loop(
90+
package_manager,
91+
"export DEBIAN_FRONTEND=noninteractive && \n" +
92+
" ${package_manager} update && \n" +
93+
" ${package_manager} upgrade -y && \n" +
94+
" ${package_manager} install -y --no-install-recommends \n" +
95+
" ca-certificates curl netcat p11-kit unzip zip ${docker_base == 'cloud' ? 'wget' : '' } && \n" +
96+
" ${package_manager} clean && \n" +
97+
" rm -rf /var/lib/apt/lists/*"
98+
) %>
99+
100+
RUN groupadd -g 1000 elasticsearch && \\
101+
adduser --uid 1000 --gid 1000 --home /usr/share/elasticsearch elasticsearch && \\
102+
adduser elasticsearch root && \\
103+
chown -R 0:0 /usr/share/elasticsearch
104+
105+
ENV ELASTIC_CONTAINER=true
106+
107+
WORKDIR /usr/share/elasticsearch
108+
109+
COPY --from=builder --chown=0:0 /usr/share/elasticsearch /usr/share/elasticsearch
110+
COPY --from=builder --chown=0:0 /bin/tini /bin/tini
111+
112+
ENV PATH=/usr/share/elasticsearch/bin:\$PATH
113+
ENV SHELL=/bin/bash
114+
COPY ${bin_dir}/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
115+
116+
# 1. Sync the user and group permissions of /etc/passwd
117+
# 2. Set correct permissions of the entrypoint
118+
# 3. Ensure that there are no files with setuid or setgid, in order to mitigate "stackclash" attacks.
119+
# We've already run this in previous layers so it ought to be a no-op.
120+
# 4. Replace OpenJDK's built-in CA certificate keystore with the one from the OS
121+
# vendor. The latter is superior in several ways.
122+
# REF: https://github.com/elastic/elasticsearch-docker/issues/171
123+
# 5. Tighten up permissions on the ES home dir (the permissions of the contents are handled earlier)
124+
# 6. You can't install plugins that include configuration when running as `elasticsearch` and the `config`
125+
# dir is owned by `root`, because the installed tries to manipulate the permissions on the plugin's
126+
# config directory.
127+
RUN chmod g=u /etc/passwd && \\
128+
chmod 0555 /usr/local/bin/docker-entrypoint.sh && \\
129+
find / -xdev -perm -4000 -exec chmod ug-s {} + && \\
130+
chmod 0775 /usr/share/elasticsearch && \\
131+
chown elasticsearch bin config config/jvm.options.d data logs plugins
132+
133+
# Update "cacerts" bundle to use Ubuntu's CA certificates (and make sure it
134+
# stays up-to-date with changes to Ubuntu's store)
135+
COPY bin/docker-openjdk /etc/ca-certificates/update.d/docker-openjdk
136+
RUN /etc/ca-certificates/update.d/docker-openjdk
137+
138+
EXPOSE 9200 9300
139+
140+
LABEL org.label-schema.build-date="${build_date}" \\
141+
org.label-schema.license="${license}" \\
142+
org.label-schema.name="Elasticsearch" \\
143+
org.label-schema.schema-version="1.0" \\
144+
org.label-schema.url="https://www.elastic.co/products/elasticsearch" \\
145+
org.label-schema.usage="https://www.elastic.co/guide/en/elasticsearch/reference/index.html" \\
146+
org.label-schema.vcs-ref="${git_revision}" \\
147+
org.label-schema.vcs-url="https://github.com/elastic/elasticsearch" \\
148+
org.label-schema.vendor="Elastic" \\
149+
org.label-schema.version="${version}" \\
150+
org.opencontainers.image.created="${build_date}" \\
151+
org.opencontainers.image.documentation="https://www.elastic.co/guide/en/elasticsearch/reference/index.html" \\
152+
org.opencontainers.image.licenses="${license}" \\
153+
org.opencontainers.image.revision="${git_revision}" \\
154+
org.opencontainers.image.source="https://github.com/elastic/elasticsearch" \\
155+
org.opencontainers.image.title="Elasticsearch" \\
156+
org.opencontainers.image.url="https://www.elastic.co/products/elasticsearch" \\
157+
org.opencontainers.image.vendor="Elastic" \\
158+
org.opencontainers.image.version="${version}"
159+
160+
# Our actual entrypoint is `tini`, a minimal but functional init program. It
161+
# calls the entrypoint we provide, while correctly forwarding signals.
162+
ENTRYPOINT ["/bin/tini", "--", "/usr/local/bin/docker-entrypoint.sh"]
163+
# Dummy overridable parameter parsed by entrypoint
164+
CMD ["eswrapper"]
165+
166+
USER 1000:0
167+
168+
################################################################################
169+
# End of multi-stage Dockerfile
170+
################################################################################
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
################################################################################
2+
# This Dockerfile was generated from the template at distribution/src/docker/Dockerfile
3+
#
4+
# Beginning of multi stage Dockerfile
5+
################################################################################
6+
7+
<% /*
8+
This file is passed through Groovy's SimpleTemplateEngine, so dollars and backslashes
9+
have to be escaped in order for them to appear in the final Dockerfile. You
10+
can also comment out blocks, like this one. See:
11+
12+
https://docs.groovy-lang.org/latest/html/api/groovy/text/SimpleTemplateEngine.html
13+
14+
We use control-flow tags in this file to conditionally render the content. The
15+
layout/presentation here has been adjusted so that it looks reasonable when rendered,
16+
at the slight expense of how it looks here.
17+
18+
Note that this file is also filtered to squash together newlines, so we can
19+
add as many newlines here as necessary to improve legibility.
20+
*/ %>
21+
22+
################################################################################
23+
# Build stage 1 `builder`:
24+
# Extract Elasticsearch artifact
25+
################################################################################
26+
27+
FROM docker.elastic.co/wolfi/chainguard-base:latest@sha256:29150cd940cc7f69407d978d5a19c86f4d9e67cf44e4d6ded787a497e8f27c9a AS builder
28+
29+
# Install required packages to extract the Elasticsearch distribution
30+
RUN <%= retry.loop(package_manager, "export DEBIAN_FRONTEND=noninteractive && ${package_manager} update && ${package_manager} update && ${package_manager} add --no-cache curl") %>
31+
32+
RUN mkdir /usr/share/elasticsearch
33+
WORKDIR /usr/share/elasticsearch
34+
35+
RUN curl --retry 10 -S -L --output /tmp/elasticsearch.tar.gz https://artifacts-no-kpi.elastic.co/downloads/elasticsearch/elasticsearch-${version}-linux-\${arch}.tar.gz
36+
37+
RUN tar -zxf /tmp/elasticsearch.tar.gz --strip-components=1
38+
39+
# The distribution includes a `config` directory, no need to create it
40+
COPY ${config_dir}/elasticsearch.yml config/
41+
COPY ${config_dir}/log4j2.properties config/log4j2.docker.properties
42+
43+
# 1. Configure the distribution for Docker
44+
# 2. Create required directory
45+
# 3. Move the distribution's default logging config aside
46+
# 4. Move the generated docker logging config so that it is the default
47+
# 5. Reset permissions on all directories
48+
# 6. Reset permissions on all files
49+
# 7. Make CLI tools executable
50+
# 8. Make some directories writable. `bin` must be writable because
51+
# plugins can install their own CLI utilities.
52+
# 9. Make some files writable
53+
RUN sed -i -e 's/ES_DISTRIBUTION_TYPE=tar/ES_DISTRIBUTION_TYPE=docker/' bin/elasticsearch-env && \\
54+
mkdir data && \\
55+
mv config/log4j2.properties config/log4j2.file.properties && \\
56+
mv config/log4j2.docker.properties config/log4j2.properties && \\
57+
find . -type d -exec chmod 0555 {} + && \\
58+
find . -type f -exec chmod 0444 {} + && \\
59+
chmod 0555 bin/* jdk/bin/* jdk/lib/jspawnhelper modules/x-pack-ml/platform/linux-*/bin/* && \\
60+
chmod 0775 bin config config/jvm.options.d data logs plugins && \\
61+
find config -type f -exec chmod 0664 {} +
62+
63+
################################################################################
64+
# Build stage 2 (the actual Elasticsearch image):
65+
#
66+
# Copy elasticsearch from stage 1
67+
# Add entrypoint
68+
################################################################################
69+
70+
FROM docker.elastic.co/wolfi/chainguard-base:latest@sha256:29150cd940cc7f69407d978d5a19c86f4d9e67cf44e4d6ded787a497e8f27c9a
71+
72+
RUN <%= retry.loop(package_manager,
73+
"export DEBIAN_FRONTEND=noninteractive && \n" +
74+
" ${package_manager} update && \n" +
75+
" ${package_manager} upgrade && \n" +
76+
" ${package_manager} add --no-cache \n" +
77+
" bash java-cacerts curl libstdc++ libsystemd netcat-openbsd p11-kit p11-kit-trust posix-libc-utils shadow tini unzip zip zstd && \n" +
78+
" rm -rf /var/cache/apk/* "
79+
) %>
80+
81+
# Set Bash as the default shell for future commands
82+
SHELL ["/bin/bash", "-c"]
83+
84+
# Optionally set Bash as the default shell in the container at runtime
85+
CMD ["/bin/bash"]
86+
87+
RUN groupadd -g 1000 elasticsearch && \
88+
adduser -G elasticsearch -u 1000 elasticsearch -D --home /usr/share/elasticsearch elasticsearch && \
89+
adduser elasticsearch root && \
90+
chown -R 0:0 /usr/share/elasticsearch
91+
92+
ENV ELASTIC_CONTAINER=true
93+
94+
WORKDIR /usr/share/elasticsearch
95+
96+
COPY --from=builder --chown=0:0 /usr/share/elasticsearch /usr/share/elasticsearch
97+
98+
ENV PATH=/usr/share/elasticsearch/bin:\$PATH
99+
ENV SHELL=/bin/bash
100+
COPY ${bin_dir}/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
101+
102+
# 1. Sync the user and group permissions of /etc/passwd
103+
# 2. Set correct permissions of the entrypoint
104+
# 3. Ensure that there are no files with setuid or setgid, in order to mitigate "stackclash" attacks.
105+
# We've already run this in previous layers so it ought to be a no-op.
106+
# 4. Replace OpenJDK's built-in CA certificate keystore with the one from the OS
107+
# vendor. The latter is superior in several ways.
108+
# REF: https://github.com/elastic/elasticsearch-docker/issues/171
109+
# 5. Tighten up permissions on the ES home dir (the permissions of the contents are handled earlier)
110+
# 6. You can't install plugins that include configuration when running as `elasticsearch` and the `config`
111+
# dir is owned by `root`, because the installed tries to manipulate the permissions on the plugin's
112+
# config directory.
113+
RUN chmod g=u /etc/passwd && \\
114+
chmod 0555 /usr/local/bin/docker-entrypoint.sh && \\
115+
find / -xdev -perm -4000 -exec chmod ug-s {} + && \\
116+
chmod 0775 /usr/share/elasticsearch && \\
117+
chown elasticsearch bin config config/jvm.options.d data logs plugins
118+
119+
RUN ln -sf /etc/ssl/certs/java/cacerts /usr/share/elasticsearch/jdk/lib/security/cacerts
120+
121+
EXPOSE 9200 9300
122+
123+
124+
LABEL org.label-schema.build-date="${build_date}" \\
125+
org.label-schema.license="${license}" \\
126+
org.label-schema.name="Elasticsearch" \\
127+
org.label-schema.schema-version="1.0" \\
128+
org.label-schema.url="https://www.elastic.co/products/elasticsearch" \\
129+
org.label-schema.usage="https://www.elastic.co/guide/en/elasticsearch/reference/index.html" \\
130+
org.label-schema.vcs-ref="${git_revision}" \\
131+
org.label-schema.vcs-url="https://github.com/elastic/elasticsearch" \\
132+
org.label-schema.vendor="Elastic" \\
133+
org.label-schema.version="${version}" \\
134+
org.opencontainers.image.created="${build_date}" \\
135+
org.opencontainers.image.documentation="https://www.elastic.co/guide/en/elasticsearch/reference/index.html" \\
136+
org.opencontainers.image.licenses="${license}" \\
137+
org.opencontainers.image.revision="${git_revision}" \\
138+
org.opencontainers.image.source="https://github.com/elastic/elasticsearch" \\
139+
org.opencontainers.image.title="Elasticsearch" \\
140+
org.opencontainers.image.url="https://www.elastic.co/products/elasticsearch" \\
141+
org.opencontainers.image.vendor="Elastic" \\
142+
org.opencontainers.image.version="${version}"
143+
144+
# Our actual entrypoint is `tini`, a minimal but functional init program. It
145+
# calls the entrypoint we provide, while correctly forwarding signals.
146+
ENTRYPOINT ["/sbin/tini", "--", "/usr/local/bin/docker-entrypoint.sh"]
147+
# Dummy overridable parameter parsed by entrypoint
148+
CMD ["eswrapper"]
149+
150+
USER 1000:0
151+
152+
################################################################################
153+
# End of multi-stage Dockerfile
154+
################################################################################

0 commit comments

Comments
 (0)