Skip to content

build: optimize image layers in base images #2212

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 17, 2024
Merged
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
4 changes: 2 additions & 2 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ jobs:
echo "BUILD_DATE=$(date '+%Y%m%d')" >> $GITHUB_ENV
make set_nightly_env
cat .env | xargs -I {} echo {} >> $GITHUB_ENV
echo "GH_ORG=${GH_ORG}" >> $GITHUB_ENV
echo "AUTHORS=${AUTHORS}" >> $GITHUB_ENV
env:
GH_ORG: ${{ vars.GH_ORG || 'SeleniumHQ' }}
AUTHORS: ${{ vars.AUTHORS || 'SeleniumHQ' }}
- name: Build Docker images
run: VERSION=${BRANCH} BUILD_DATE=${BUILD_DATE} make build
- name: Count image layers
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
echo "NAME=${NAMESPACE}" >> $GITHUB_ENV
env:
NAMESPACE: ${{ vars.DOCKER_NAMESPACE || 'selenium' }}
GH_ORG: ${{ vars.GH_ORG || 'SeleniumHQ' }}
AUTHORS: ${{ vars.AUTHORS || 'SeleniumHQ' }}
- name: Sets prerelease to false by default
run: echo "PRERELEASE=false" >> $GITHUB_ENV
- name: Build base image to get Grid version
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/helm-chart-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ jobs:
echo "IMAGE_REGISTRY=artifactory/selenium" >> $GITHUB_ENV
make set_nightly_env
cat .env | xargs -I {} echo {} >> $GITHUB_ENV
echo "GH_ORG=${GH_ORG}" >> $GITHUB_ENV
echo "AUTHORS=${AUTHORS}" >> $GITHUB_ENV
env:
GH_ORG: ${{ vars.GH_ORG || 'SeleniumHQ' }}
AUTHORS: ${{ vars.AUTHORS || 'SeleniumHQ' }}
- name: Setup Kubernetes environment
uses: nick-invision/retry@master
with:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/nightly.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ jobs:
run: |
echo "PRERELEASE=true" >> $GITHUB_ENV
echo "NAME=${NAMESPACE}" >> $GITHUB_ENV
echo "GH_ORG=${GH_ORG}" >> $GITHUB_ENV
echo "AUTHORS=${AUTHORS}" >> $GITHUB_ENV
env:
NAMESPACE: ${{ vars.DOCKER_NAMESPACE || 'selenium' }}
GH_ORG: ${{ vars.GH_ORG || 'SeleniumHQ' }}
AUTHORS: ${{ vars.AUTHORS || 'SeleniumHQ' }}
- name: Build base image to get Grid version
run: VERSION="local" BUILD_DATE=${BUILD_DATE} make base_nightly
- name: Get Grid version
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test-video.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ jobs:
echo "BUILD_DATE=$(date '+%Y%m%d')" >> $GITHUB_ENV
make set_nightly_env
cat .env | xargs -I {} echo {} >> $GITHUB_ENV
echo "GH_ORG=${GH_ORG}" >> $GITHUB_ENV
echo "AUTHORS=${AUTHORS}" >> $GITHUB_ENV
env:
GH_ORG: ${{ vars.GH_ORG || 'SeleniumHQ' }}
AUTHORS: ${{ vars.AUTHORS || 'SeleniumHQ' }}
- name: Pre-build to reduce logs in test phase
run: |
VERSION=${BRANCH} BUILD_DATE=${BUILD_DATE} make hub
Expand Down
140 changes: 58 additions & 82 deletions Base/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ LABEL authors="Selenium <selenium-developers@googlegroups.com>"
# Arguments to define the version of dependencies to download
ARG VERSION
ARG RELEASE=selenium-${VERSION}
ARG GH_ORG=SeleniumHQ
ARG AUTHORS=SeleniumHQ
# Default value should be aligned with upstream Selenium (https://github.com/SeleniumHQ/selenium/blob/trunk/java/maven_deps.bzl)
ARG OPENTELEMETRY_VERSION=1.36.0
ARG GRPC_VERSION=1.62.2
Expand All @@ -15,27 +15,31 @@ ARG SEL_GROUP=${SEL_USER}
ARG SEL_PASSWD=secret
ARG UID=1200
ARG GID=1201

USER root
#================================================
# Customize sources for apt-get
#================================================
RUN echo "deb http://archive.ubuntu.com/ubuntu jammy main universe\n" > /etc/apt/sources.list \
&& echo "deb http://archive.ubuntu.com/ubuntu jammy-updates main universe\n" >> /etc/apt/sources.list \
&& echo "deb http://security.ubuntu.com/ubuntu jammy-security main universe\n" >> /etc/apt/sources.list
ARG TZ="UTC"
ARG JRE_VERSION=17
ARG TARGETARCH=amd64
ARG TARGETVARIANT

# No interactive frontend during docker build
USER root

ENV DEBIAN_FRONTEND=noninteractive \
DEBCONF_NONINTERACTIVE_SEEN=true
# No interactive frontend during docker build
DEBCONF_NONINTERACTIVE_SEEN=true \
SEL_USER=${SEL_USER} \
SEL_UID=${UID} \
SEL_GID=${GID} \
HOME=/home/${SEL_USER} \
TZ=${TZ} \
SEL_DOWNLOAD_DIR=${HOME}/Downloads

#========================
# Miscellaneous packages
# Includes minimal runtime used for executing non GUI Java programs
#========================
ARG JRE_VERSION=17
RUN apt-get -qqy update \
RUN echo "deb http://archive.ubuntu.com/ubuntu jammy main universe\n" > /etc/apt/sources.list \
&& echo "deb http://archive.ubuntu.com/ubuntu jammy-updates main universe\n" >> /etc/apt/sources.list \
&& echo "deb http://security.ubuntu.com/ubuntu jammy-security main universe\n" >> /etc/apt/sources.list \
&& apt-get -qqy update \
&& apt-get upgrade -yq \
&& apt-get -qqy --no-install-recommends install \
acl \
Expand All @@ -56,40 +60,24 @@ RUN apt-get -qqy update \
&& echo "deb [signed-by=/etc/apt/keyrings/adoptium.asc] https://packages.adoptium.net/artifactory/deb $(awk -F= '/^VERSION_CODENAME/{print$2}' /etc/os-release) main" | tee /etc/apt/sources.list.d/adoptium.list >dev/null \
&& apt-get -qqy update \
&& apt-get -qqy --no-install-recommends install temurin-${JRE_VERSION}-jre -y \
&& rm -rf /var/lib/apt/lists/* /var/cache/apt/*

#===================

RUN if [ $TARGETARCH = "arm" ] && [ $TARGETVARIANT = "v7" ]; then \
&& if [ "${TARGETARCH}" = "arm" ] && [ "${TARGETVARIANT}" = "v7" ]; then \
export ARCH=armhf ; \
else \
export ARCH=$TARGETARCH ; \
export ARCH=${TARGETARCH} ; \
fi \
&& sed -i 's/securerandom\.source=file:\/dev\/random/securerandom\.source=file:\/dev\/urandom/' ./usr/lib/jvm/temurin-${JRE_VERSION}-jre-$ARCH/conf/security/java.security


&& sed -i 's/securerandom\.source=file:\/dev\/random/securerandom\.source=file:\/dev\/urandom/' ./usr/lib/jvm/temurin-${JRE_VERSION}-jre-${ARCH}/conf/security/java.security \
&& rm -rf /var/lib/apt/lists/* /var/cache/apt/* \
#===================
# Timezone settings
# Possible alternative: https://github.com/docker/docker/issues/3359#issuecomment-32150214
#===================
ENV TZ "UTC"
RUN ln -fs /usr/share/zoneinfo/${TZ} /etc/localtime && \
&& ln -fs /usr/share/zoneinfo/${TZ} /etc/localtime && \
dpkg-reconfigure -f noninteractive tzdata && \
cat /etc/timezone

#======================================
# Configure environement
#======================================
ENV SEL_USER=${SEL_USER}
ENV SEL_UID=${UID}
ENV SEL_GID=${GID}
ENV HOME=/home/${SEL_USER}
ENV SEL_DOWNLOAD_DIR=${HOME}/Downloads

cat /etc/timezone \
#========================================
# Add normal user and group with passwordless sudo
# Add normal user and group without password sudo
#========================================
RUN groupadd ${SEL_GROUP} \
&& groupadd ${SEL_GROUP} \
--gid ${SEL_GID} \
&& useradd ${SEL_USER} \
--create-home \
Expand All @@ -98,75 +86,63 @@ RUN groupadd ${SEL_GROUP} \
--uid ${SEL_UID} \
&& usermod -a -G sudo ${SEL_USER} \
&& echo 'ALL ALL = (ALL) NOPASSWD: ALL' >> /etc/sudoers \
&& echo "${SEL_USER}:${SEL_PASSWD}" | chpasswd

#======================================
# Add Grid check script
#======================================
COPY --chown="${SEL_UID}:${SEL_GID}" check-grid.sh entry_point.sh /opt/bin/

#======================================
# Add Supervisor configuration file
#======================================
COPY supervisord.conf /etc

&& echo "${SEL_USER}:${SEL_PASSWD}" | chpasswd \
#==========
# Selenium & relaxing permissions for OpenShift and other non-sudo environments
#==========
RUN mkdir -p /opt/selenium /opt/selenium/assets /var/run/supervisor /var/log/supervisor ${SEL_DOWNLOAD_DIR} \
&& mkdir -p /opt/selenium /opt/selenium/assets /var/run/supervisor /var/log/supervisor ${SEL_DOWNLOAD_DIR} \
${HOME}/.mozilla ${HOME}/.vnc $HOME/.pki/nssdb \
# NSSDB initialization with an empty password
&& certutil -d sql:$HOME/.pki/nssdb -N --empty-password \
&& touch /opt/selenium/config.toml \
&& chown -R ${SEL_USER}:${SEL_GROUP} /opt/selenium /var/run/supervisor /var/log/supervisor /etc/passwd ${HOME} \
&& chmod -R 775 /opt/selenium /var/run/supervisor /var/log/supervisor /etc/passwd ${HOME} \
&& wget --no-verbose https://github.com/${GH_ORG}/selenium/releases/download/${RELEASE}/selenium-server-${VERSION}.jar \
&& wget --no-verbose https://github.com/${AUTHORS}/selenium/releases/download/${RELEASE}/selenium-server-${VERSION}.jar \
-O /opt/selenium/selenium-server.jar \
&& echo "${SEL_PASSWD}" > /opt/selenium/initialPasswd \
&& chgrp -R 0 /opt/selenium ${HOME} /opt/selenium/assets /var/run/supervisor /var/log/supervisor \
&& chmod -R g=u /opt/selenium ${HOME} /opt/selenium/assets /var/run/supervisor /var/log/supervisor \
&& setfacl -Rm u:${SEL_USER}:rwx /opt /opt/selenium ${HOME} /opt/selenium/assets /var/run/supervisor /var/log/supervisor \
&& setfacl -Rm g:${SEL_GROUP}:rwx /opt /opt/selenium ${HOME} /opt/selenium/assets /var/run/supervisor /var/log/supervisor

&& setfacl -Rm g:${SEL_GROUP}:rwx /opt /opt/selenium ${HOME} /opt/selenium/assets /var/run/supervisor /var/log/supervisor \
#=====
# Download observability related jaegar jars and make them available in a separate directory
# Download observability related OpenTelemetry jars and make them available in a separate directory
# so that the container can skip downloading them everytime it comes up
#=====
RUN curl -fLo /tmp/cs https://github.com/coursier/launchers/raw/master/coursier \
&& curl -fLo /tmp/cs https://github.com/coursier/launchers/raw/master/coursier \
&& chmod +x /tmp/cs \
&& mkdir -p /external_jars \
&& chmod -R 775 /external_jars

RUN /tmp/cs fetch --classpath --cache /external_jars \
&& chmod -R 775 /external_jars \
&& /tmp/cs fetch --classpath --cache /external_jars \
io.opentelemetry:opentelemetry-exporter-otlp:${OPENTELEMETRY_VERSION} \
io.grpc:grpc-netty:${GRPC_VERSION} > /external_jars/.classpath.txt
io.grpc:grpc-netty:${GRPC_VERSION} > /external_jars/.classpath.txt \
&& chmod 664 /external_jars/.classpath.txt \
&& rm -fr /root/.cache/* \
# (Note that .bashrc is only executed in interactive bash shells.)
&& echo 'if [[ $(ulimit -n) -gt 200000 ]]; then echo "WARNING: Very high value reported by \"ulimit -n\". Consider passing \"--ulimit nofile=32768\" to \"docker run\"."; fi' >> ${HOME}/.bashrc

RUN chmod 664 /external_jars/.classpath.txt
RUN rm -fr /root/.cache/*
#======================================
# Add Grid check script
#======================================
COPY --chown="${SEL_UID}:${SEL_GID}" check-grid.sh entry_point.sh /opt/bin/

#======================================
# Add Supervisor configuration file
#======================================
COPY supervisord.conf /etc

#===================================================
# Run the following commands as non-privileged user
#===================================================
USER ${SEL_UID}:${SEL_GID}

#==========
# NSSDB initialization with an empty password
#==========
RUN certutil -d sql:$HOME/.pki/nssdb -N --empty-password

# Boolean value, maps "--bind-host"
ENV SE_BIND_HOST false
# Boolean value, maps "--reject-unsupported-caps"
ENV SE_REJECT_UNSUPPORTED_CAPS false

ENV SE_OTEL_JAVA_GLOBAL_AUTOCONFIGURE_ENABLED true
ENV SE_OTEL_TRACES_EXPORTER "otlp"

# A too high maximum number of file descriptors (with the default value
# inherited from the docker host) can cause issues with some of our tools:
# - sanitizers hanging: https://github.com/google/sanitizers/issues/1662
# - valgrind crashing: https://stackoverflow.com/a/75293014
# This is not be a problem on our CI hosts, but developers who run the image
# on their machines may run into this (e.g., on Arch Linux), so warn them.
# (Note that .bashrc is only executed in interactive bash shells.)
RUN echo 'if [[ $(ulimit -n) -gt 200000 ]]; then echo "WARNING: Very high value reported by \"ulimit -n\". Consider passing \"--ulimit nofile=32768\" to \"docker run\"."; fi' >> ${HOME}/.bashrc
#======================================
# Configure environement
#======================================
# Boolean value, maps "--bind-host"
ENV SE_BIND_HOST=false \
# Boolean value, maps "--reject-unsupported-caps"
SE_REJECT_UNSUPPORTED_CAPS=false \
SE_OTEL_JAVA_GLOBAL_AUTOCONFIGURE_ENABLED=true \
SE_OTEL_TRACES_EXPORTER="otlp"

CMD ["/opt/bin/entry_point.sh"]
5 changes: 2 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
NAME := $(or $(NAME),$(NAME),selenium)
CURRENT_DATE := $(shell date '+%Y%m%d')
BUILD_DATE := $(or $(BUILD_DATE),$(BUILD_DATE),$(CURRENT_DATE))
GH_ORG := $(or $(GH_ORG),$(GH_ORG),SeleniumHQ)
BASE_RELEASE := $(or $(BASE_RELEASE),$(BASE_RELEASE),selenium-4.19.0)
BASE_VERSION := $(or $(BASE_VERSION),$(BASE_VERSION),4.19.1)
BINDING_VERSION := $(or $(BINDING_VERSION),$(BINDING_VERSION),4.19.0)
Expand Down Expand Up @@ -50,10 +49,10 @@ build: all
ci: build test

base:
cd ./Base && docker build $(BUILD_ARGS) --build-arg VERSION=$(BASE_VERSION) --build-arg RELEASE=$(BASE_RELEASE) --build-arg GH_ORG=$(GH_ORG) -t $(NAME)/base:$(TAG_VERSION) .
cd ./Base && docker build $(BUILD_ARGS) --build-arg VERSION=$(BASE_VERSION) --build-arg RELEASE=$(BASE_RELEASE) --build-arg AUTHORS=$(AUTHORS) -t $(NAME)/base:$(TAG_VERSION) .

base_nightly:
cd ./Base && docker build $(BUILD_ARGS) --build-arg VERSION=$(BASE_VERSION_NIGHTLY) --build-arg RELEASE=$(BASE_RELEASE_NIGHTLY) --build-arg GH_ORG=$(GH_ORG) -t $(NAME)/base:$(TAG_VERSION) .
cd ./Base && docker build $(BUILD_ARGS) --build-arg VERSION=$(BASE_VERSION_NIGHTLY) --build-arg RELEASE=$(BASE_RELEASE_NIGHTLY) --build-arg AUTHORS=$(AUTHORS) -t $(NAME)/base:$(TAG_VERSION) .

hub: base
cd ./Hub && docker build $(BUILD_ARGS) $(FROM_IMAGE_ARGS) -t $(NAME)/hub:$(TAG_VERSION) .
Expand Down
Loading
Loading