From 4d8047f3e130a1e0057f3618f11e48dd77bee75c Mon Sep 17 00:00:00 2001 From: Viet Nguyen Duc Date: Thu, 12 Dec 2024 00:15:17 +0700 Subject: [PATCH] Docker: build minimal FFmpeg binary and optimize recorder Signed-off-by: Viet Nguyen Duc --- .ffmpeg/Dockerfile | 81 +++++++++++++ Base/Dockerfile | 28 ++--- Makefile | 27 +++-- NodeBase/Dockerfile | 18 +-- NodeChrome/Dockerfile | 3 +- NodeChromium/Dockerfile | 3 +- NodeEdge/Dockerfile | 3 +- NodeFirefox/Dockerfile | 58 +++++++--- NodeFirefox/install-firefox-apt.sh | 17 +++ Video/Dockerfile | 133 ++++++---------------- Video/recorder.conf | 28 +++++ Video/supervisord.conf | 56 --------- Video/upload.conf | 0 Video/upload.sh | 5 +- Video/uploader.conf | 14 +++ charts/selenium-grid/CONFIGURATION.md | 2 +- charts/selenium-grid/values.yaml | 2 +- tests/charts/templates/test.py | 2 +- tests/docker-compose-v3-test-parallel.yml | 47 +++----- 19 files changed, 284 insertions(+), 243 deletions(-) create mode 100644 .ffmpeg/Dockerfile create mode 100644 NodeFirefox/install-firefox-apt.sh mode change 100755 => 100644 Video/Dockerfile create mode 100755 Video/recorder.conf delete mode 100755 Video/supervisord.conf delete mode 100755 Video/upload.conf create mode 100644 Video/uploader.conf diff --git a/.ffmpeg/Dockerfile b/.ffmpeg/Dockerfile new file mode 100644 index 0000000000..55bcad9291 --- /dev/null +++ b/.ffmpeg/Dockerfile @@ -0,0 +1,81 @@ +FROM ubuntu:noble AS builder +ARG VERSION_FFMPEG="7.1" +ARG VERSION_RCLONE="v1.68.2" +ARG VERSION_GO="latest" + +USER root + +#====================================== +# Install build tools +#====================================== +ARG TOOLS_DEPS="autoconf automake cmake libfreetype6 gcc build-essential libtool make nasm pkg-config zlib1g-dev numactl \ +libnuma-dev libx11-6 libxcb1 libxcb1-dev yasm git curl jq wget ca-certificates" + +RUN apt-get update -qqy \ + && apt-get upgrade -yq \ + && apt-get -qqy --no-install-recommends install ${TOOLS_DEPS} \ + && apt-get -qyy clean \ + && mkdir -p /usr/local/src + +RUN if [ "${VERSION_GO}" = "latest" ]; then \ + VERSION_GO=$(curl -sk https://go.dev/dl/?mode=json | jq -r '.[0].version'); \ + fi \ + && curl -skLO https://go.dev/dl/$VERSION_GO.linux-$(dpkg --print-architecture).tar.gz \ + && tar -xf $VERSION_GO.linux-$(dpkg --print-architecture).tar.gz -C /usr/local \ + && rm -rf $VERSION_GO.linux-$(dpkg --print-architecture).tar.gz* \ + && ln -sf /usr/local/go/bin/go /usr/bin/go \ + && go version + +RUN cd /usr/local/src \ + && git clone https://github.com/rclone/rclone.git \ + && cd rclone \ + && git checkout $VERSION_RCLONE \ + && make \ + && mv ~/go/bin/rclone /usr/local/bin/ \ + && rclone version + +#====================================== +# Install x264 from source +#====================================== +RUN cd /usr/local/src \ + && git clone https://code.videolan.org/videolan/x264.git \ + && cd x264 \ + && ./configure --prefix="/usr/local" --enable-static \ + && make \ + && make install + +#====================================== +# Install FFmpeg from source +#====================================== +RUN cd /usr/local/src \ + && git clone https://github.com/FFmpeg/FFmpeg.git \ + && cd FFmpeg \ + && git checkout release/$VERSION_FFMPEG \ + && PKG_CONFIG_PATH="/usr/local/lib/pkgconfig" ./configure \ + --prefix="/usr/local" \ + --extra-cflags="-I/usr/local/include" \ + --extra-ldflags="-L/usr/local/lib" \ + --pkg-config-flags="--static" \ + --enable-gpl \ + --enable-nonfree \ + --enable-libx264 \ + --enable-libxcb \ + --enable-static \ + && make \ + && make install + +# Final stage +FROM ubuntu:noble + +USER root + +COPY --from=builder /usr/local/bin/ffmpeg /usr/local/bin/ffmpeg +COPY --from=builder /usr/local/bin/rclone /usr/local/bin/rclone + +RUN apt-get -qqy update \ + && apt-get -qqy --no-install-recommends install \ + libx11-dev libxcb1 libxcb-shm0 \ + && rm -rf /var/lib/apt/lists/* /var/cache/apt/* + +RUN ffmpeg -version \ + && rclone --version diff --git a/Base/Dockerfile b/Base/Dockerfile index fb55ed5b7a..eb0d5f277d 100644 --- a/Base/Dockerfile +++ b/Base/Dockerfile @@ -35,14 +35,14 @@ ENV DEBIAN_FRONTEND=noninteractive \ SEL_GID=${GID} \ HOME=${HOME} \ TZ=${TZ} \ - SEL_DOWNLOAD_DIR=${HOME}/Downloads + SEL_DOWNLOAD_DIR=${HOME}/Downloads \ + VIDEO_FOLDER="/videos" #======================== # Miscellaneous packages # Includes minimal runtime used for executing non GUI Java programs #======================== -RUN --mount=type=secret,id=SEL_PASSWD \ - if [ "$(dpkg --print-architecture)" = "amd64" ]; then \ +RUN if [ "$(dpkg --print-architecture)" = "amd64" ]; then \ echo "deb http://archive.ubuntu.com/ubuntu noble main universe\n" > /etc/apt/sources.list \ && echo "deb http://archive.ubuntu.com/ubuntu noble-updates main universe\n" >> /etc/apt/sources.list \ && echo "deb http://security.ubuntu.com/ubuntu noble-security main universe\n" >> /etc/apt/sources.list ; \ @@ -52,6 +52,7 @@ RUN --mount=type=secret,id=SEL_PASSWD \ && apt-get -qqy --no-install-recommends install \ acl \ bzip2 \ + xz-utils \ ca-certificates \ tzdata \ sudo \ @@ -62,15 +63,16 @@ RUN --mount=type=secret,id=SEL_PASSWD \ supervisor \ gnupg2 \ libnss3-tools \ - python3-pip \ openjdk-${JRE_VERSION}-jre-headless \ - && if [ "${TARGETARCH}" = "arm" ] && [ "${TARGETVARIANT}" = "v7" ]; then \ + && rm -rf /var/lib/apt/lists/* /var/cache/apt/* + +RUN --mount=type=secret,id=SEL_PASSWD \ + if [ "${TARGETARCH}" = "arm" ] && [ "${TARGETVARIANT}" = "v7" ]; then \ export ARCH=armhf ; \ else \ export ARCH=$(dpkg --print-architecture) ; \ fi \ && sed -i 's/securerandom\.source=file:\/dev\/random/securerandom\.source=file:\/dev\/urandom/' /usr/lib/jvm/java-${JRE_VERSION}-openjdk-${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 @@ -95,18 +97,18 @@ RUN --mount=type=secret,id=SEL_PASSWD \ # Selenium & relaxing permissions for OpenShift and other non-sudo environments #========== && mkdir -p /opt/selenium /opt/selenium/assets /opt/selenium/secrets /var/run/supervisor /var/log/supervisor ${SEL_DOWNLOAD_DIR} \ - ${HOME}/.mozilla ${HOME}/.vnc ${HOME}/.pki/nssdb \ + ${HOME}/.mozilla ${HOME}/.vnc ${HOME}/.pki/nssdb ${VIDEO_FOLDER} \ # 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} \ + && chown -R ${SEL_USER}:${SEL_GROUP} /opt/selenium /var/run/supervisor /var/log/supervisor /etc/passwd ${HOME} ${VIDEO_FOLDER} \ + && chmod -R 775 /opt/selenium /var/run/supervisor /var/log/supervisor /etc/passwd ${HOME} ${VIDEO_FOLDER} \ && wget --no-verbose https://github.com/${AUTHORS}/selenium/releases/download/${RELEASE}/selenium-server-${VERSION}.jar \ -O /opt/selenium/selenium-server.jar \ - && 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 \ + && chgrp -R 0 /opt/selenium ${HOME} ${VIDEO_FOLDER} /opt/selenium/assets /var/run/supervisor /var/log/supervisor \ + && chmod -R g=u /opt/selenium ${HOME} ${VIDEO_FOLDER} /opt/selenium/assets /var/run/supervisor /var/log/supervisor \ + && setfacl -Rm u:${SEL_USER}:rwx /opt /opt/selenium ${HOME} ${VIDEO_FOLDER} /opt/selenium/assets /var/run/supervisor /var/log/supervisor \ + && setfacl -Rm g:${SEL_GROUP}:rwx /opt /opt/selenium ${HOME} ${VIDEO_FOLDER} /opt/selenium/assets /var/run/supervisor /var/log/supervisor \ #===== # 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 diff --git a/Makefile b/Makefile index 8b33a498d4..3c4fd0fb8e 100644 --- a/Makefile +++ b/Makefile @@ -17,10 +17,11 @@ BUILD_ARGS := $(BUILD_ARGS) --progress plain MAJOR := $(word 1,$(subst ., ,$(TAG_VERSION))) MINOR := $(word 2,$(subst ., ,$(TAG_VERSION))) MAJOR_MINOR_PATCH := $(word 1,$(subst -, ,$(TAG_VERSION))) +FFMPEG_VERSION := $(or $(FFMPEG_VERSION),$(FFMPEG_VERSION),7.1) FFMPEG_TAG_PREV_VERSION := $(or $(FFMPEG_TAG_PREV_VERSION),$(FFMPEG_TAG_PREV_VERSION),ffmpeg-7.1) FFMPEG_TAG_VERSION := $(or $(FFMPEG_TAG_VERSION),$(FFMPEG_TAG_VERSION),ffmpeg-7.1) -FFMPEG_BASED_NAME := $(or $(FFMPEG_BASED_NAME),$(FFMPEG_BASED_NAME),linuxserver) -FFMPEG_BASED_TAG := $(or $(FFMPEG_BASED_TAG),$(FFMPEG_BASED_TAG),version-7.1-cli) +FFMPEG_BASED_NAME := $(or $(FFMPEG_BASED_NAME),$(FFMPEG_BASED_NAME),selenium) +FFMPEG_BASED_TAG := $(or $(FFMPEG_BASED_TAG),$(FFMPEG_BASED_TAG),latest) CURRENT_PLATFORM := $(shell if [ `arch` = "aarch64" ] || [ `arch` = "arm64" ]; then echo "linux/arm64"; else echo "linux/amd64"; fi) PLATFORMS := $(or $(PLATFORMS),$(shell echo $$PLATFORMS),$(CURRENT_PLATFORM)) SEL_PASSWD := $(or $(SEL_PASSWD),$(SEL_PASSWD),secret) @@ -143,8 +144,8 @@ sessionqueue: base event_bus: base cd ./EventBus && docker buildx build --platform $(PLATFORMS) $(BUILD_ARGS) $(FROM_IMAGE_ARGS) -t $(NAME)/event-bus:$(TAG_VERSION) . -node_base: base - cd ./NodeBase && SEL_PASSWD=$(SEL_PASSWD) docker buildx build --platform $(PLATFORMS) $(BUILD_ARGS) $(FROM_IMAGE_ARGS) --secret id=SEL_PASSWD -t $(NAME)/node-base:$(TAG_VERSION) . +node_base: base video + cd ./NodeBase && SEL_PASSWD=$(SEL_PASSWD) docker buildx build --platform $(PLATFORMS) $(BUILD_ARGS) $(FROM_IMAGE_ARGS) --build-arg BASE=video --build-arg VERSION=$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) --secret id=SEL_PASSWD -t $(NAME)/node-base:$(TAG_VERSION) . chrome: node_base case "$(PLATFORMS)" in \ @@ -187,7 +188,7 @@ firefox: node_base cd ./NodeFirefox && docker buildx build --platform $(PLATFORMS) $(BUILD_ARGS) $(FROM_IMAGE_ARGS) --build-arg FIREFOX_DOWNLOAD_URL=$(FIREFOX_DOWNLOAD_URL) -t $(NAME)/node-firefox:$(TAG_VERSION) . firefox_dev: - cd ./NodeFirefox && docker buildx build --platform $(PLATFORMS) $(BUILD_ARGS) $(FROM_IMAGE_ARGS) --build-arg FIREFOX_VERSION=nightly-latest -t $(NAME)/node-firefox:dev . + cd ./NodeFirefox && docker buildx build --platform $(PLATFORMS) $(BUILD_ARGS) $(FROM_IMAGE_ARGS) --build-arg FIREFOX_VERSION=devedition-latest -t $(NAME)/node-firefox:dev . firefox_beta: cd ./NodeFirefox && docker buildx build --platform $(PLATFORMS) $(BUILD_ARGS) $(FROM_IMAGE_ARGS) --build-arg FIREFOX_VERSION=beta-latest -t $(NAME)/node-firefox:beta . @@ -244,8 +245,11 @@ standalone_edge_dev: edge_dev standalone_edge_beta: edge_beta cd ./Standalone && docker buildx build --platform $(PLATFORMS) $(BUILD_ARGS) --build-arg NAMESPACE=$(NAME) --build-arg VERSION=beta --build-arg BASE=node-edge -t $(NAME)/standalone-edge:beta . -video: - cd ./Video && SEL_PASSWD=$(SEL_PASSWD) docker buildx build --platform $(PLATFORMS) $(BUILD_ARGS) --build-arg NAMESPACE=$(FFMPEG_BASED_NAME) --build-arg BASED_TAG=$(FFMPEG_BASED_TAG) --secret id=SEL_PASSWD --sbom=true --attest type=provenance,mode=max -t $(NAME)/video:$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) . +video: base + cd ./Video && docker buildx build --platform $(PLATFORMS) $(BUILD_ARGS) --build-arg FFMPEG_BASED_NAME=$(FFMPEG_BASED_NAME) --build-arg FFMPEG_BASED_TAG=$(FFMPEG_BASED_TAG) $(FROM_IMAGE_ARGS) -t $(NAME)/video:$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) . + +ffmpeg: + cd ./.ffmpeg && docker buildx build --platform $(PLATFORMS) $(BUILD_ARGS) --build-arg VERSION_FFMPEG=$(FFMPEG_VERSION) $(FROM_IMAGE_ARGS) -t $(NAME)/ffmpeg:$(FFMPEG_VERSION)-$(BUILD_DATE) . fetch_grid_scaler_resources: mkdir -p ./.keda/scalers \ @@ -332,6 +336,10 @@ tag_and_push_edge_images: tag_and_push_firefox_images: ./tag_and_push_browser_images.sh $(VERSION) $(BUILD_DATE) $(NAMESPACE) $(PUSH_IMAGE) firefox +tag_ffmpeg_latest: + docker tag $(NAME)/ffmpeg:$(FFMPEG_VERSION)-$(BUILD_DATE) $(NAME)/ffmpeg:latest + docker tag $(NAME)/ffmpeg:$(FFMPEG_VERSION)-$(BUILD_DATE) $(NAME)/ffmpeg:$(FFMPEG_VERSION) + tag_latest: docker tag $(NAME)/base:$(TAG_VERSION) $(NAME)/base:latest docker tag $(NAME)/hub:$(TAG_VERSION) $(NAME)/hub:latest @@ -353,6 +361,11 @@ tag_latest: docker tag $(NAME)/standalone-docker:$(TAG_VERSION) $(NAME)/standalone-docker:latest docker tag $(NAME)/video:$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) $(NAME)/video:latest +release_ffmpeg_latest: + docker push $(NAME)/ffmpeg:latest + docker push $(NAME)/ffmpeg:$(FFMPEG_VERSION) + docker push $(NAME)/ffmpeg:$(FFMPEG_VERSION)-$(BUILD_DATE) + release_latest: release_grid_scaler_latest docker push $(NAME)/base:latest docker push $(NAME)/hub:latest diff --git a/NodeBase/Dockerfile b/NodeBase/Dockerfile index 7229a4ce5f..9691e13f14 100644 --- a/NodeBase/Dockerfile +++ b/NodeBase/Dockerfile @@ -1,6 +1,7 @@ ARG NAMESPACE=selenium ARG VERSION=latest -FROM ${NAMESPACE}/base:${VERSION} +ARG BASE=base +FROM ${NAMESPACE}/${BASE}:${VERSION} ARG AUTHORS LABEL authors=${AUTHORS} @@ -49,6 +50,8 @@ ENV LANG_WHICH=${LANG_WHICH} \ #============================ # Some configuration options #============================ + SE_RECORD_VIDEO=false \ + DISPLAY_CONTAINER_NAME="localhost" \ SE_SCREEN_WIDTH=1920 \ SE_SCREEN_HEIGHT=1080 \ SE_SCREEN_DEPTH=24 \ @@ -66,8 +69,7 @@ ENV LANG_WHICH=${LANG_WHICH} \ # Following line fixes https://github.com/SeleniumHQ/docker-selenium/issues/87 DBUS_SESSION_BUS_ADDRESS=/dev/null -RUN --mount=type=secret,id=SEL_PASSWD \ - apt-get update -qqy \ +RUN apt-get update -qqy \ && apt-get -qqy --no-install-recommends install \ #============== # Xvfb @@ -102,13 +104,13 @@ RUN --mount=type=secret,id=SEL_PASSWD \ && locale-gen ${LANGUAGE} \ && dpkg-reconfigure --frontend noninteractive locales \ && apt-get -qyy autoremove \ - && rm -rf /var/lib/apt/lists/* \ - && apt-get -qyy clean \ - && pip install --no-cache-dir --upgrade --break-system-packages setuptools \ + && rm -rf /var/lib/apt/lists/* /var/cache/apt/* \ + && apt-get -qyy clean ######################################## # noVNC exposes VNC through a web page # ######################################## - && wget -nv -O noVNC.zip \ +RUN --mount=type=secret,id=SEL_PASSWD \ + wget -nv -O noVNC.zip \ "https://github.com/novnc/noVNC/archive/refs/${NOVNC_SOURCE}/${NOVNC_VERSION}.zip" \ && unzip -x noVNC.zip \ && mv noVNC-${NOVNC_VERSION#v} /opt/bin/noVNC \ @@ -120,7 +122,7 @@ RUN --mount=type=secret,id=SEL_PASSWD \ && rm websockify.zip \ # Setup dependencies && cd websockify-${WEBSOCKIFY_VERSION#v} \ - && python3 setup.py install \ + && python3 -m pip install --break-system-packages . \ # Move websockify and run to the noVNC directory && mv websockify /opt/bin/noVNC/utils/websockify \ && mv run /opt/bin/noVNC/utils/websockify \ diff --git a/NodeChrome/Dockerfile b/NodeChrome/Dockerfile index f91981e49c..e2b9b413d0 100644 --- a/NodeChrome/Dockerfile +++ b/NodeChrome/Dockerfile @@ -1,6 +1,7 @@ ARG NAMESPACE=selenium ARG VERSION=latest -FROM ${NAMESPACE}/node-base:${VERSION} +ARG BASE=node-base +FROM ${NAMESPACE}/${BASE}:${VERSION} ARG AUTHORS LABEL authors=${AUTHORS} diff --git a/NodeChromium/Dockerfile b/NodeChromium/Dockerfile index dbdd0edd20..94f8bd8eea 100644 --- a/NodeChromium/Dockerfile +++ b/NodeChromium/Dockerfile @@ -1,6 +1,7 @@ ARG NAMESPACE=selenium ARG VERSION=latest -FROM ${NAMESPACE}/node-base:${VERSION} +ARG BASE=node-base +FROM ${NAMESPACE}/${BASE}:${VERSION} ARG AUTHORS LABEL authors=${AUTHORS} diff --git a/NodeEdge/Dockerfile b/NodeEdge/Dockerfile index 177b6b4814..0428a5cf64 100644 --- a/NodeEdge/Dockerfile +++ b/NodeEdge/Dockerfile @@ -1,6 +1,7 @@ ARG NAMESPACE=selenium ARG VERSION=latest -FROM ${NAMESPACE}/node-base:${VERSION} +ARG BASE=node-base +FROM ${NAMESPACE}/${BASE}:${VERSION} ARG AUTHORS LABEL authors=${AUTHORS} diff --git a/NodeFirefox/Dockerfile b/NodeFirefox/Dockerfile index 6cedeaad91..63d5264fe0 100644 --- a/NodeFirefox/Dockerfile +++ b/NodeFirefox/Dockerfile @@ -1,6 +1,7 @@ ARG NAMESPACE=selenium ARG VERSION=latest -FROM ${NAMESPACE}/node-base:${VERSION} +ARG BASE=node-base +FROM ${NAMESPACE}/${BASE}:${VERSION} ARG AUTHORS LABEL authors=${AUTHORS} @@ -9,32 +10,55 @@ USER root #============================================ # Firefox cleanup script and supervisord file #============================================ -COPY --chown="${SEL_UID}:${SEL_GID}" firefox-cleanup.sh get_lang_package.sh /opt/bin/ +COPY --chown="${SEL_UID}:${SEL_GID}" firefox-cleanup.sh get_lang_package.sh install-firefox-apt.sh /opt/bin/ COPY --chown="${SEL_UID}:${SEL_GID}" firefox-cleanup.conf /etc/supervisor/conf.d/firefox-cleanup.conf -RUN chmod +x /opt/bin/firefox-cleanup.sh /opt/bin/get_lang_package.sh +RUN chmod +x /opt/bin/firefox-cleanup.sh /opt/bin/get_lang_package.sh /opt/bin/install-firefox-apt.sh #========= # Firefox #========= ARG FIREFOX_VERSION=latest ARG FIREFOX_DOWNLOAD_URL="https://download.mozilla.org/?product=firefox-nightly-latest-ssl&os=linux64-aarch64&lang=en-US" -RUN if [ "$(dpkg --print-architecture)" = "amd64" ]; then \ - FIREFOX_DOWNLOAD_URL=$(if [ $FIREFOX_VERSION = "latest" ] || [ $FIREFOX_VERSION = "beta-latest" ] || [ $FIREFOX_VERSION = "nightly-latest" ] || [ $FIREFOX_VERSION = "devedition-latest" ] || [ $FIREFOX_VERSION = "esr-latest" ]; then echo "https://download.mozilla.org/?product=firefox-$FIREFOX_VERSION-ssl&os=linux64&lang=en-US"; else echo "https://download-installer.cdn.mozilla.net/pub/firefox/releases/$FIREFOX_VERSION/linux-x86_64/en-US/firefox-$FIREFOX_VERSION.tar.bz2"; fi) ; \ +RUN apt-get update -qqy && \ + if [ "$(dpkg --print-architecture)" = "amd64" ]; then \ + if [ $FIREFOX_VERSION = "latest" ] || [ $FIREFOX_VERSION = "beta-latest" ] || [ $FIREFOX_VERSION = "nightly-latest" ] || [ $FIREFOX_VERSION = "devedition-latest" ] || [ $FIREFOX_VERSION = "esr-latest" ]; then \ + FIREFOX_DOWNLOAD_URL="https://download.mozilla.org/?product=firefox-$FIREFOX_VERSION-ssl&os=linux64&lang=en-US"; \ + /opt/bin/install-firefox-apt.sh \ + && FIREFOX_VERSION=$(echo "-$FIREFOX_VERSION" | sed 's/-latest//') \ + && apt install -y firefox$FIREFOX_VERSION \ + && INSTALL_VIA_APT=true \ + && if [ $FIREFOX_VERSION = "-beta" ] || [ $FIREFOX_VERSION = "-nightly" ] || [ $FIREFOX_VERSION = "-devedition" ] || [ $FIREFOX_VERSION = "-esr" ]; then \ + ln -fs $(which firefox$FIREFOX_VERSION) /usr/bin/firefox ; \ + fi ; \ else \ - FIREFOX_DOWNLOAD_URL="${FIREFOX_DOWNLOAD_URL}" ; \ + FIREFOX_DOWNLOAD_URL="https://download-installer.cdn.mozilla.net/pub/firefox/releases/$FIREFOX_VERSION/linux-x86_64/en-US/firefox-$FIREFOX_VERSION.tar.bz2" ; \ fi \ - && apt-get update -qqy \ - && apt-get -qqy --no-install-recommends install libavcodec-extra libgtk-3-dev libdbus-glib-1-dev xz-utils \ - && rm -rf /var/lib/apt/lists/* /var/cache/apt/* \ - && wget --no-verbose -O /tmp/firefox.tar.bz2 $FIREFOX_DOWNLOAD_URL \ - && rm -rf /opt/firefox \ - && tar -C /opt -xjf /tmp/firefox.tar.bz2 || (mv /tmp/firefox.tar.bz2 /tmp/firefox.tar.xz && tar -C /opt -xJf /tmp/firefox.tar.xz) \ - && rm -rf /tmp/firefox.tar.bz2 /tmp/firefox.tar.xz \ - && mv /opt/firefox /opt/firefox-$FIREFOX_VERSION \ - && mkdir -p /opt/firefox-$FIREFOX_VERSION/distribution/extensions \ - && ln -fs /opt/firefox-$FIREFOX_VERSION/firefox /usr/bin/firefox \ + else \ + if [ $FIREFOX_VERSION = "nightly-latest" ]; then \ + /opt/bin/install-firefox-apt.sh \ + && FIREFOX_VERSION=$(echo "-$FIREFOX_VERSION" | sed 's/-latest//') \ + && apt install -y firefox$FIREFOX_VERSION \ + && INSTALL_VIA_APT=true \ + && if [ $FIREFOX_VERSION = "-nightly" ]; then \ + ln -fs $(which firefox$FIREFOX_VERSION) /usr/bin/firefox ; \ + fi ; \ + else \ + FIREFOX_DOWNLOAD_URL="${FIREFOX_DOWNLOAD_URL}" ; \ + fi ; \ + fi && \ + if [ "$INSTALL_VIA_APT" != "true" ]; then \ + apt-get -qqy --no-install-recommends install libavcodec-extra libgtk-3-dev libdbus-glib-1-dev xz-utils \ + && wget --no-verbose -O /tmp/firefox.tar.bz2 $FIREFOX_DOWNLOAD_URL \ + && rm -rf /opt/firefox \ + && tar -C /opt -xjf /tmp/firefox.tar.bz2 || (mv /tmp/firefox.tar.bz2 /tmp/firefox.tar.xz && tar -C /opt -xJf /tmp/firefox.tar.xz) \ + && rm -rf /tmp/firefox.tar.bz2 /tmp/firefox.tar.xz \ + && mv /opt/firefox /opt/firefox-$FIREFOX_VERSION \ + && mkdir -p /opt/firefox-$FIREFOX_VERSION/distribution/extensions \ + && ln -fs /opt/firefox-$FIREFOX_VERSION/firefox /usr/bin/firefox ; \ + fi \ # Download the language pack for Firefox - && /opt/bin/get_lang_package.sh + && /opt/bin/get_lang_package.sh \ + && rm -rf /var/lib/apt/lists/* /var/cache/apt/* #============ # GeckoDriver diff --git a/NodeFirefox/install-firefox-apt.sh b/NodeFirefox/install-firefox-apt.sh new file mode 100644 index 0000000000..c85febd024 --- /dev/null +++ b/NodeFirefox/install-firefox-apt.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +install -d -m 0755 /etc/apt/keyrings + +wget -q https://packages.mozilla.org/apt/repo-signing-key.gpg -O- | sudo tee /etc/apt/keyrings/packages.mozilla.org.asc >/dev/null + +gpg -n -q --import --import-options import-show /etc/apt/keyrings/packages.mozilla.org.asc | awk '/pub/{getline; gsub(/^ +| +$/,""); if($0 == "35BAA0B33E9EB396F59CA838C0BA5CE6DC6315A3") print "\nThe key fingerprint matches ("$0").\n"; else print "\nVerification failed: the fingerprint ("$0") does not match the expected one.\n"}' + +echo "deb [signed-by=/etc/apt/keyrings/packages.mozilla.org.asc] https://packages.mozilla.org/apt mozilla main" | sudo tee -a /etc/apt/sources.list.d/mozilla.list >/dev/null + +echo ' +Package: * +Pin: origin packages.mozilla.org +Pin-Priority: 1000 +' | sudo tee /etc/apt/preferences.d/mozilla + +sudo apt-get update diff --git a/Video/Dockerfile b/Video/Dockerfile old mode 100755 new mode 100644 index f223d10383..18a8f0e916 --- a/Video/Dockerfile +++ b/Video/Dockerfile @@ -1,121 +1,54 @@ -ARG NAMESPACE=linuxserver -ARG BASED_TAG=latest -FROM $NAMESPACE/ffmpeg:$BASED_TAG -ARG AUTHORS=SeleniumHQ -LABEL authors="${AUTHORS} " -LABEL org.opencontainers.image.source="https://github.com/${AUTHORS}/docker-selenium" - -ARG RCLONE_VERSION=current -#Arguments to define the user running the container -ARG SEL_USER=seluser -ARG SEL_GROUP=${SEL_USER} -ARG HOME=/home/${SEL_USER} -ARG UID=1200 -ARG GID=1201 -ARG VIDEO_FOLDER=/videos +ARG NAMESPACE=selenium +ARG BASE=base +ARG VERSION=latest +ARG FFMPEG_BASED_NAME=selenium +ARG FFMPEG_BASED_TAG=latest +FROM ${FFMPEG_BASED_NAME}/ffmpeg:${FFMPEG_BASED_TAG} AS source + +# Final stage +FROM ${NAMESPACE}/${BASE}:${VERSION} +ARG AUTHORS +LABEL authors=${AUTHORS} USER root -#================================================ -# Customize sources for apt-get -#================================================ -RUN if [ "$(dpkg --print-architecture)" = "amd64" ]; then \ - echo "deb http://archive.ubuntu.com/ubuntu noble main universe\n" > /etc/apt/sources.list \ - && echo "deb http://archive.ubuntu.com/ubuntu noble-updates main universe\n" >> /etc/apt/sources.list \ - && echo "deb http://security.ubuntu.com/ubuntu noble-security main universe\n" >> /etc/apt/sources.list ; \ - fi -# No interactive frontend during docker build -ENV DEBIAN_FRONTEND=noninteractive \ - DEBCONF_NONINTERACTIVE_SEEN=true \ - PIP_ROOT_USER_ACTION=ignore +COPY --from=source /usr/local/bin/ffmpeg /usr/local/bin/ffmpeg +COPY --from=source /usr/local/bin/rclone /usr/local/bin/rclone -#======================== -# Supervisor -#======================== RUN apt-get -qqy update \ - && apt-get upgrade -yq \ - && apt-get -qqy --no-install-recommends install \ - supervisor x11-xserver-utils x11-utils libxcb1-dev curl jq python3-pip tzdata acl unzip python3-psutil \ - && pip install --no-cache-dir --upgrade --break-system-packages setuptools \ - && 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 && \ - dpkg-reconfigure -f noninteractive tzdata && \ - cat /etc/timezone - -#====================================== -# Configure environement -#====================================== -ENV SEL_USER=${SEL_USER} \ - SEL_UID=${UID} \ - SEL_GID=${GID} \ - HOME=${HOME} - -#======================================== -# Add normal user and group with passwordless sudo -#======================================== -RUN --mount=type=secret,id=SEL_PASSWD \ - groupadd ${SEL_GROUP} \ - --gid ${SEL_GID} \ - && useradd ${SEL_USER} \ - --create-home \ - --gid ${SEL_GID} \ - --shell /bin/bash \ - --uid ${SEL_UID} \ - && usermod -a -G sudo ${SEL_USER} \ - && echo 'ALL ALL = (ALL) NOPASSWD: ALL' >> /etc/sudoers \ - && echo "${SEL_USER}:$(cat /run/secrets/SEL_PASSWD)" | chpasswd - -#====================================== -# Add Supervisor configuration files -#====================================== -COPY supervisord.conf /etc -COPY --chown="${SEL_UID}:${SEL_GID}" entry_point.sh validate_endpoint.sh video.sh video_ready.py video_graphQLQuery.sh video_gridUrl.sh /opt/bin/ + && apt-get -qqy --no-install-recommends install \ + libx11-6 libxcb1 libxcb-shm0 \ + x11-xserver-utils x11-utils \ + python3-pip \ + && pip install --break-system-packages --no-cache-dir setuptools psutil \ + && rm -rf /var/lib/apt/lists/* /var/cache/apt/* -#====================================== -# Add RCLONE for uploading videos -#====================================== -RUN curl -fLo /tmp/rclone.zip https://downloads.rclone.org/rclone-${RCLONE_VERSION}-linux-$(dpkg --print-architecture).zip \ - && unzip -a /tmp/rclone.zip -d /tmp \ - && mv /tmp/rclone-*-linux-*/rclone /usr/local/bin/ \ - && rm -rf /tmp/rclone-* -COPY --chown="${SEL_UID}:${SEL_GID}" upload.sh upload.conf /opt/bin/ -ENV SE_VIDEO_UPLOAD_ENABLED=false \ - SE_VIDEO_INTERNAL_UPLOAD=true \ - SE_UPLOAD_DESTINATION_PREFIX="" - -RUN mkdir -p /var/run/supervisor /var/log/supervisor ${VIDEO_FOLDER} \ - && chown -R ${SEL_USER}:${SEL_GROUP} /var/run/supervisor /var/log/supervisor ${VIDEO_FOLDER} ${HOME} \ - && chmod -R 775 /var/run/supervisor /var/log/supervisor ${VIDEO_FOLDER} ${HOME} \ - && chgrp -R 0 /var/run/supervisor /var/log/supervisor ${VIDEO_FOLDER} ${HOME} \ - && chmod -R g=u /var/run/supervisor /var/log/supervisor ${VIDEO_FOLDER} ${HOME} \ - && setfacl -Rdm u:${SEL_USER}:rwx,g:${SEL_GROUP}:rwx /var/run/supervisor /var/log/supervisor ${VIDEO_FOLDER} ${HOME} +COPY *.conf /etc/supervisor/conf.d/ +COPY --chown="${SEL_UID}:${SEL_GID}" *.sh video_ready.py /opt/bin/ USER ${SEL_UID} -ENTRYPOINT ["/opt/bin/entry_point.sh"] -CMD ["/opt/bin/entry_point.sh"] +RUN ffmpeg -version \ + && rclone --version \ + && touch /opt/selenium/upload.conf ENV DISPLAY_NUM=99 \ - DISPLAY_CONTAINER_NAME=selenium \ + DISPLAY_CONTAINER_NAME="selenium" \ + SE_RECORD_VIDEO=true \ SE_SERVER_PROTOCOL="http" \ SE_VIDEO_POLL_INTERVAL=1 \ SE_SCREEN_WIDTH=1920 \ SE_SCREEN_HEIGHT=1080 \ SE_FRAME_RATE=15 \ - SE_CODEC=libx264 \ + SE_CODEC="libx264" \ SE_PRESET="-preset ultrafast" \ - VIDEO_FOLDER=${VIDEO_FOLDER} \ + VIDEO_FOLDER="/videos" \ SE_VIDEO_FILE_NAME=video.mp4 \ SE_VIDEO_FILE_NAME_TRIM_REGEX="[:alnum:]-_" \ - SE_SUPERVISORD_LOG_LEVEL="info" \ - SE_SUPERVISORD_CHILD_LOG_DIR="/tmp" \ - SE_SUPERVISORD_LOG_FILE="/tmp/supervisord.log" \ - SE_SUPERVISORD_PID_FILE="/tmp/supervisord.pid" + # Environment variables for the uploader + RCLONE_CONFIG="/opt/selenium/upload.conf" \ + SE_VIDEO_UPLOAD_ENABLED=false \ + SE_VIDEO_INTERNAL_UPLOAD=true \ + SE_UPLOAD_DESTINATION_PREFIX="" EXPOSE 9000 diff --git a/Video/recorder.conf b/Video/recorder.conf new file mode 100755 index 0000000000..9bbef29f68 --- /dev/null +++ b/Video/recorder.conf @@ -0,0 +1,28 @@ +[program:video-recording] +priority=10 +command=/opt/bin/video.sh +killasgroup=true +autostart=%(ENV_SE_RECORD_VIDEO)s +startsecs=0 +autorestart=%(ENV_SE_RECORD_VIDEO)s +stopsignal=TERM +stopwaitsecs=30 + +;Logs (all activity redirected to stdout so it can be seen through "docker logs" +redirect_stderr=true +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 + +[program:video-ready] +priority=0 +command=python3 /opt/bin/video_ready.py +killasgroup=true +autostart=%(ENV_SE_RECORD_VIDEO)s +startsecs=0 +autorestart=%(ENV_SE_RECORD_VIDEO)s +stopsignal=KILL + +;Logs (all activity redirected to stdout so it can be seen through "docker logs" +redirect_stderr=true +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 diff --git a/Video/supervisord.conf b/Video/supervisord.conf deleted file mode 100755 index fa9c4596ac..0000000000 --- a/Video/supervisord.conf +++ /dev/null @@ -1,56 +0,0 @@ -; Documentation of this file format -> http://supervisord.org/configuration.html - -[supervisord] -childlogdir=%(ENV_SE_SUPERVISORD_CHILD_LOG_DIR)s ; ('AUTO' child log dir, default $TEMP) -logfile=%(ENV_SE_SUPERVISORD_LOG_FILE)s ; (main log file;default $CWD/supervisord.log) -logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB) -logfile_backups=10 ; (num of main logfile rotation backups;default 10) -loglevel=%(ENV_SE_SUPERVISORD_LOG_LEVEL)s ; (log level;default info; others: debug,warn,trace) http://supervisord.org/logging.html -pidfile=%(ENV_SE_SUPERVISORD_PID_FILE)s ; (supervisord pidfile;default supervisord.pid) -nodaemon=true ; (start in foreground if true;default false) -minfds=1024 ; (min. avail startup file descriptors;default 1024) -minprocs=200 ; (min. avail process descriptors;default 200) - -[program:video-recording] -priority=10 -command=/opt/bin/video.sh -killasgroup=true -autostart=true -startsecs=0 -autorestart=true -stopsignal=TERM -stopwaitsecs=30 - -;Logs (all activity redirected to stdout so it can be seen through "docker logs" -redirect_stderr=true -stdout_logfile=/dev/stdout -stdout_logfile_maxbytes=0 - -[program:video-ready] -priority=0 -command=python3 /opt/bin/video_ready.py -killasgroup=true -autostart=true -startsecs=0 -autorestart=true -stopsignal=KILL - -;Logs (all activity redirected to stdout so it can be seen through "docker logs" -redirect_stderr=true -stdout_logfile=/dev/stdout -stdout_logfile_maxbytes=0 - -[program:video-upload] -priority=5 -command=/opt/bin/upload.sh -killasgroup=true -autostart=%(ENV_SE_VIDEO_INTERNAL_UPLOAD)s -startsecs=0 -autorestart=%(ENV_SE_VIDEO_INTERNAL_UPLOAD)s -stopsignal=TERM -stopwaitsecs=30 - -;Logs (all activity redirected to stdout so it can be seen through "docker logs" -redirect_stderr=true -stdout_logfile=/dev/stdout -stdout_logfile_maxbytes=0 diff --git a/Video/upload.conf b/Video/upload.conf deleted file mode 100755 index e69de29bb2..0000000000 diff --git a/Video/upload.sh b/Video/upload.sh index 3d5c7adde6..1ea39dddbc 100755 --- a/Video/upload.sh +++ b/Video/upload.sh @@ -1,8 +1,7 @@ #!/usr/bin/env bash VIDEO_FOLDER=${VIDEO_FOLDER} -UPLOAD_CONFIG_DIRECTORY=${SE_UPLOAD_CONFIG_DIRECTORY:-"/opt/bin"} -UPLOAD_CONFIG_FILE_NAME=${SE_UPLOAD_CONFIG_FILE_NAME:-"upload.conf"} +RCLONE_CONFIG=${RCLONE_CONFIG:-${SE_RCLONE_CONFIG}} UPLOAD_COMMAND=${SE_UPLOAD_COMMAND:-"copy"} UPLOAD_OPTS=${SE_UPLOAD_OPTS:-"-P --cutoff-mode SOFT --metadata --inplace"} UPLOAD_RETAIN_LOCAL_FILE=${SE_UPLOAD_RETAIN_LOCAL_FILE:-"false"} @@ -57,7 +56,7 @@ function rclone_upload() { local source=$1 local target=$2 echo "$(date -u +"${ts_format}") [${process_name}] - Uploading ${source} to ${target}" - rclone --config ${UPLOAD_CONFIG_DIRECTORY}/${UPLOAD_CONFIG_FILE_NAME} ${UPLOAD_COMMAND} ${UPLOAD_OPTS} "${source}" "${target}" & + rclone --config ${RCLONE_CONFIG} ${UPLOAD_COMMAND} ${UPLOAD_OPTS} "${source}" "${target}" & list_rclone_pid+=($!) check_and_clear_background } diff --git a/Video/uploader.conf b/Video/uploader.conf new file mode 100644 index 0000000000..f92969be42 --- /dev/null +++ b/Video/uploader.conf @@ -0,0 +1,14 @@ +[program:video-upload] +priority=5 +command=/opt/bin/upload.sh +killasgroup=true +autostart=%(ENV_SE_VIDEO_INTERNAL_UPLOAD)s +startsecs=0 +autorestart=%(ENV_SE_VIDEO_INTERNAL_UPLOAD)s +stopsignal=TERM +stopwaitsecs=30 + +;Logs (all activity redirected to stdout so it can be seen through "docker logs" +redirect_stderr=true +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 diff --git a/charts/selenium-grid/CONFIGURATION.md b/charts/selenium-grid/CONFIGURATION.md index f20b633cee..10bc226766 100644 --- a/charts/selenium-grid/CONFIGURATION.md +++ b/charts/selenium-grid/CONFIGURATION.md @@ -152,7 +152,7 @@ A Helm chart for creating a Selenium Grid Server in Kubernetes | uploaderConfigMap.nameOverride | string | `nil` | Override the name of the uploader configMap | | uploaderConfigMap.defaultMode | int | `493` | Default mode for ConfigMap is mounted as file | | uploaderConfigMap.extraScriptsImportFrom | string | `"configs/uploader/**"` | Directory where the extra scripts are imported to ConfigMap by default (if given a relative path, it should be in chart's directory) | -| uploaderConfigMap.extraScriptsDirectory | string | `"/opt/bin"` | Directory where the extra scripts are mounted to | +| uploaderConfigMap.extraScriptsDirectory | string | `"/opt/selenium"` | Directory where the extra scripts are mounted to | | uploaderConfigMap.extraScripts | object | `{"upload.sh":""}` | List of extra scripts to be mounted to the container. Format as `filename: content` | | uploaderConfigMap.secretFiles | object | `{"upload.conf":"[sample]"}` | Extra files stored in Secret to be mounted to the container. | | uploaderConfigMap.scriptVolumeMountName | string | `nil` | Name of volume mount is used to mount scripts in the ConfigMap | diff --git a/charts/selenium-grid/values.yaml b/charts/selenium-grid/values.yaml index ff14b162b9..92c1434f9e 100644 --- a/charts/selenium-grid/values.yaml +++ b/charts/selenium-grid/values.yaml @@ -337,7 +337,7 @@ uploaderConfigMap: # -- Directory where the extra scripts are imported to ConfigMap by default (if given a relative path, it should be in chart's directory) extraScriptsImportFrom: "configs/uploader/**" # -- Directory where the extra scripts are mounted to - extraScriptsDirectory: "/opt/bin" + extraScriptsDirectory: "/opt/selenium" # -- List of extra scripts to be mounted to the container. Format as `filename: content` extraScripts: upload.sh: "" diff --git a/tests/charts/templates/test.py b/tests/charts/templates/test.py index 31f75744b0..7365c15a8b 100644 --- a/tests/charts/templates/test.py +++ b/tests/charts/templates/test.py @@ -217,7 +217,7 @@ def test_upload_conf_mount_to_video_container(self): else: list_volume_mounts = video_container['volumeMounts'] for volume in list_volume_mounts: - if volume['mountPath'] == '/opt/bin/upload.conf': + if volume['mountPath'] == '/opt/selenium/upload.conf': is_present = True self.assertTrue(is_present, "Volume mount for upload config is not present in the container") diff --git a/tests/docker-compose-v3-test-parallel.yml b/tests/docker-compose-v3-test-parallel.yml index 4cab9b64cc..77f016d6e3 100644 --- a/tests/docker-compose-v3-test-parallel.yml +++ b/tests/docker-compose-v3-test-parallel.yml @@ -16,6 +16,7 @@ services: - selenium-hub volumes: - ./videos/certs:/opt/selenium/secrets + - ./videos:/videos environment: - SE_ENABLE_TRACING=false - SE_EVENT_BUS_HOST=selenium-hub @@ -25,23 +26,16 @@ services: - SE_BROWSER_ARGS_DISABLE_DSHM=--disable-dev-shm-usage - SE_BROWSER_ARGS_INCOGNITO=--incognito --incognito - SE_LOG_LEVEL=${LOG_LEVEL} - - SE_SUPERVISORD_LOG_LEVEL=error + - SE_SUPERVISORD_LOG_LEVEL=info - SE_NODE_GRACEFUL_SHUTDOWN=true - SE_DRAIN_AFTER_SESSION_COUNT=1 - SE_ENABLE_TLS=true - SE_JAVA_OPTS=-Dwebdriver.httpclient.readTimeout=${REQUEST_TIMEOUT} - restart: always - - chrome_video: - image: selenium/video:${VIDEO_TAG} - user: ${UID} - volumes: - - ./videos:/videos - environment: - - DISPLAY_CONTAINER_NAME=chrome + - SE_RECORD_VIDEO=true - SE_VIDEO_FILE_NAME=auto - SE_SERVER_PROTOCOL=https - stop_grace_period: 30s + - SE_NODE_GRID_URL=https://selenium-hub:4444 + restart: always firefox: profiles: @@ -57,6 +51,7 @@ services: - selenium-hub volumes: - ./videos/certs:/opt/selenium/secrets + - ./videos:/videos environment: - SE_ENABLE_TRACING=false - SE_EVENT_BUS_HOST=selenium-hub @@ -64,23 +59,16 @@ services: - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 - SE_NODE_ENABLE_MANAGED_DOWNLOADS=true - SE_LOG_LEVEL=${LOG_LEVEL} - - SE_SUPERVISORD_LOG_LEVEL=error + - SE_SUPERVISORD_LOG_LEVEL=info - SE_NODE_GRACEFUL_SHUTDOWN=true - SE_DRAIN_AFTER_SESSION_COUNT=3 - SE_ENABLE_TLS=true - SE_JAVA_OPTS=-Dwebdriver.httpclient.readTimeout=${REQUEST_TIMEOUT} - restart: always - - firefox_video: - image: selenium/video:${VIDEO_TAG} - user: ${UID} - volumes: - - ./videos:/videos - environment: - - DISPLAY_CONTAINER_NAME=firefox + - SE_RECORD_VIDEO=true - SE_VIDEO_FILE_NAME=auto - SE_SERVER_PROTOCOL=https - stop_grace_period: 30s + - SE_NODE_GRID_URL=https://selenium-hub:4444 + restart: always edge: profiles: @@ -102,23 +90,16 @@ services: - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 - SE_NODE_ENABLE_MANAGED_DOWNLOADS=true - SE_LOG_LEVEL=${LOG_LEVEL} - - SE_SUPERVISORD_LOG_LEVEL=error + - SE_SUPERVISORD_LOG_LEVEL=info - SE_NODE_GRACEFUL_SHUTDOWN=true - SE_DRAIN_AFTER_SESSION_COUNT=2 - SE_ENABLE_TLS=true - SE_JAVA_OPTS=-Dwebdriver.httpclient.readTimeout=${REQUEST_TIMEOUT} - restart: always - - edge_video: - image: selenium/video:${VIDEO_TAG} - user: ${UID} - volumes: - - ./videos:/videos - environment: - - DISPLAY_CONTAINER_NAME=edge + - SE_RECORD_VIDEO=true - SE_VIDEO_FILE_NAME=auto - SE_SERVER_PROTOCOL=https - stop_grace_period: 30s + - SE_NODE_GRID_URL=https://selenium-hub:4444 + restart: always selenium-hub: image: selenium/hub:${TAG}