Skip to content

Instantly share code, notes, and snippets.

@varyonic
Created June 10, 2016 14:14
Show Gist options
  • Save varyonic/dea40abcf3dd891d204ef235c6e8dd79 to your computer and use it in GitHub Desktop.
Save varyonic/dea40abcf3dd891d204ef235c6e8dd79 to your computer and use it in GitHub Desktop.
Dockerfile with chromedriver
# See https://codeship.com/documentation/docker/browser-testing/
FROM myapp:base
# We need wget to set up the PPA and xvfb to have a virtual screen and unzip to install the Chromedriver
RUN apt-get install -y wget xvfb unzip
# Set up the Chrome PPA
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
RUN echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list
# Update the package list and install chrome
RUN apt-get update -y
RUN apt-get install -y google-chrome-stable
# Set up Chromedriver Environment variables
ENV CHROMEDRIVER_VERSION 2.19
ENV CHROMEDRIVER_DIR /chromedriver
RUN mkdir $CHROMEDRIVER_DIR
# Download and install Chromedriver
RUN wget -q --continue -P $CHROMEDRIVER_DIR "http://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip"
RUN unzip $CHROMEDRIVER_DIR/chromedriver* -d $CHROMEDRIVER_DIR
# Put Chromedriver into the PATH
ENV PATH $CHROMEDRIVER_DIR:$PATH
@lemmen6
Copy link

lemmen6 commented Oct 10, 2024

Here is my working version, a slight different take incase it helps:

FROM python:3.10.2-bullseye

# Install dependencies
RUN apt-get update -y && apt-get install -y wget xvfb unzip jq

# Install Google Chrome dependencies
RUN apt-get install -y libxss1 libappindicator1 libgconf-2-4 \
    fonts-liberation libasound2 libnspr4 libnss3 libx11-xcb1 libxtst6 lsb-release xdg-utils \
    libgbm1 libnss3 libatk-bridge2.0-0 libgtk-3-0 libx11-xcb1 libxcb-dri3-0


# Fetch the latest version numbers and URLs for Chrome and ChromeDriver
RUN curl -s https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json > /tmp/versions.json

RUN CHROME_URL=$(jq -r '.channels.Stable.downloads.chrome[] | select(.platform=="linux64") | .url' /tmp/versions.json) && \
    wget -q --continue -O /tmp/chrome-linux64.zip $CHROME_URL && \
    unzip /tmp/chrome-linux64.zip -d /opt/chrome

RUN chmod +x /opt/chrome/chrome-linux64/chrome


RUN CHROMEDRIVER_URL=$(jq -r '.channels.Stable.downloads.chromedriver[] | select(.platform=="linux64") | .url' /tmp/versions.json) && \
    wget -q --continue -O /tmp/chromedriver-linux64.zip $CHROMEDRIVER_URL && \
    unzip /tmp/chromedriver-linux64.zip -d /opt/chromedriver && \
    chmod +x /opt/chromedriver/chromedriver-linux64/chromedriver

# Set up Chromedriver Environment variables
ENV CHROMEDRIVER_DIR /opt/chromedriver
ENV PATH $CHROMEDRIVER_DIR:$PATH

# Clean upa
RUN rm /tmp/chrome-linux64.zip /tmp/chromedriver-linux64.zip /tmp/versions.json

# python dependencies
RUN pip install selenium

# Copy your Python script into the container
COPY test_chromedriver.py /opt/test_chromedriver.py

# Command to run the script
CMD ["python", "/opt/test_chromedriver.py"]
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service as ChromeService
import time

def test_chromedriver_installation():
    # Setup Chrome options
    chrome_options = Options()
    chrome_options.add_argument("--headless")
    chrome_options.add_argument("--no-sandbox")
    chrome_options.add_argument("--disable-dev-shm-usage")
    chrome_options.add_argument("--disable-gpu")  # This is important for some versions of Chrome
    chrome_options.add_argument("--remote-debugging-port=9222")  # This is recommended

    # Set path to Chrome binary
    chrome_options.binary_location = "/opt/chrome/chrome-linux64/chrome"

    # Set path to ChromeDriver
    chrome_service = ChromeService(executable_path="/opt/chromedriver/chromedriver-linux64/chromedriver")

    # Set up driver
    driver = webdriver.Chrome(service=chrome_service, options=chrome_options)

    try:
        # URL to test
        driver.get("http://example.com")

        # Give the browser time to load all content.
        time.sleep(2)

        # Find element by tag
        element = driver.find_element(By.TAG_NAME, "h1")

        # Print the text of the element
        print(element.text)

        # Check if the text is as expected
        assert "Example Domain" in element.text
        print("ChromeDriver is installed and working as expected.")

    except Exception as e:
        print(f"An error occurred: {e}")

    finally:
        # Close the browser
       # Close the browser
        driver.quit()

test_chromedriver_installation()

This is really good work, however update

Set up Chromedriver Environment variables

ENV CHROMEDRIVER_DIR /opt/chromedriver
ENV PATH $CHROMEDRIVER_DIR:$PATH

to:

Set up Chromedriver Environment variables

ENV CHROMEDRIVER_DIR=/opt/chromedriver
ENV PATH=$CHROMEDRIVER_DIR:$PATH

and it works.

Thank you so much @ankitarya1019

@Aditya23456
Copy link

I get this error do you really need so many dependencies, i am using python:3.11.2-slim-bullseye as base:
RUN apt-get install -y libxss1 libappindicator1 libgconf-2-4 fonts-liberation libasound2 libnspr4 libnss3 libx11-xcb1 libxtst6 lsb-release xdg-utils libgbm1 libnss3 libatk-bridge2.0-0 libgtk-3-0 libx11-xcb1 libxcb-dri3-0
---> Running in ef18a231d6fa
Reading package lists...
Building dependency tree...
Reading state information...
Package fonts-liberation is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source

Package libasound2 is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source

Package xdg-utils is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source

E: Unable to locate package libxss1
E: Unable to locate package libappindicator1
E: Unable to locate package libgconf-2-4
E: Package 'fonts-liberation' has no installation candidate
E: Package 'libasound2' has no installation candidate
E: Unable to locate package libnspr4
E: Unable to locate package libnss3
E: Unable to locate package libxtst6
E: Unable to locate package lsb-release
E: Package 'xdg-utils' has no installation candidate
E: Unable to locate package libgbm1
E: Unable to locate package libnss3
E: Unable to locate package libatk-bridge2.0-0
E: Couldn't find any package by glob 'libatk-bridge2.0-0'
E: Couldn't find any package by regex 'libatk-bridge2.0-0'
E: Unable to locate package libgtk-3-0

Here is my working version, a slight different take incase it helps:

FROM python:3.10.2-bullseye

# Install dependencies
RUN apt-get update -y && apt-get install -y wget xvfb unzip jq

# Install Google Chrome dependencies
RUN apt-get install -y libxss1 libappindicator1 libgconf-2-4 \
    fonts-liberation libasound2 libnspr4 libnss3 libx11-xcb1 libxtst6 lsb-release xdg-utils \
    libgbm1 libnss3 libatk-bridge2.0-0 libgtk-3-0 libx11-xcb1 libxcb-dri3-0


# Fetch the latest version numbers and URLs for Chrome and ChromeDriver
RUN curl -s https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json > /tmp/versions.json

RUN CHROME_URL=$(jq -r '.channels.Stable.downloads.chrome[] | select(.platform=="linux64") | .url' /tmp/versions.json) && \
    wget -q --continue -O /tmp/chrome-linux64.zip $CHROME_URL && \
    unzip /tmp/chrome-linux64.zip -d /opt/chrome

RUN chmod +x /opt/chrome/chrome-linux64/chrome


RUN CHROMEDRIVER_URL=$(jq -r '.channels.Stable.downloads.chromedriver[] | select(.platform=="linux64") | .url' /tmp/versions.json) && \
    wget -q --continue -O /tmp/chromedriver-linux64.zip $CHROMEDRIVER_URL && \
    unzip /tmp/chromedriver-linux64.zip -d /opt/chromedriver && \
    chmod +x /opt/chromedriver/chromedriver-linux64/chromedriver

# Set up Chromedriver Environment variables
ENV CHROMEDRIVER_DIR /opt/chromedriver
ENV PATH $CHROMEDRIVER_DIR:$PATH

# Clean upa
RUN rm /tmp/chrome-linux64.zip /tmp/chromedriver-linux64.zip /tmp/versions.json

# python dependencies
RUN pip install selenium

# Copy your Python script into the container
COPY test_chromedriver.py /opt/test_chromedriver.py

# Command to run the script
CMD ["python", "/opt/test_chromedriver.py"]
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service as ChromeService
import time

def test_chromedriver_installation():
    # Setup Chrome options
    chrome_options = Options()
    chrome_options.add_argument("--headless")
    chrome_options.add_argument("--no-sandbox")
    chrome_options.add_argument("--disable-dev-shm-usage")
    chrome_options.add_argument("--disable-gpu")  # This is important for some versions of Chrome
    chrome_options.add_argument("--remote-debugging-port=9222")  # This is recommended

    # Set path to Chrome binary
    chrome_options.binary_location = "/opt/chrome/chrome-linux64/chrome"

    # Set path to ChromeDriver
    chrome_service = ChromeService(executable_path="/opt/chromedriver/chromedriver-linux64/chromedriver")

    # Set up driver
    driver = webdriver.Chrome(service=chrome_service, options=chrome_options)

    try:
        # URL to test
        driver.get("http://example.com")

        # Give the browser time to load all content.
        time.sleep(2)

        # Find element by tag
        element = driver.find_element(By.TAG_NAME, "h1")

        # Print the text of the element
        print(element.text)

        # Check if the text is as expected
        assert "Example Domain" in element.text
        print("ChromeDriver is installed and working as expected.")

    except Exception as e:
        print(f"An error occurred: {e}")

    finally:
        # Close the browser
       # Close the browser
        driver.quit()

test_chromedriver_installation()

This is really good work, however update

Set up Chromedriver Environment variables

ENV CHROMEDRIVER_DIR /opt/chromedriver
ENV PATH $CHROMEDRIVER_DIR:$PATH

to:

Set up Chromedriver Environment variables

ENV CHROMEDRIVER_DIR=/opt/chromedriver
ENV PATH=$CHROMEDRIVER_DIR:$PATH

and it works.

Thank you so much @ankitarya1019

@mieubrisse
Copy link

mieubrisse commented Mar 8, 2025

For posterity: the Dockerfile in the comment above mine didn't work for me on a Mac M2 chip, so with the liberal help of ChatGPT I was able to find one that works by just apt-installing chromium and chromedriver:

# Debian-based Python image (multi-arch)
FROM python:3.10-slim-bullseye

ENV DEBIAN_FRONTEND=noninteractive

# Install Chromium, ChromeDriver, and any needed libs
RUN apt-get update && apt-get install -y \ 
    chromium chromium-driver \ 
    libgl1-mesa-glx \ 
    libglib2.0-0 libnss3 libx11-6 libxcb1 libxcomposite1 libxcursor1 libxdamage1 \ 
    libxext6 libxfixes3 libxi6 libxtst6 libatk1.0-0 libatk-bridge2.0-0 libcups2 \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /usr/src/app

COPY . .

# python dependencies
RUN pip install --no-cache-dir -r requirements.txt

# We expect the user to volume-mount the file into place and buffering can be a 
# problem, so use unbuffered mode for reading the input.csv
ENV PYTHONUNBUFFERED=1

# NOTE: depends on a /tmp/input.csv existing
# ENV CHROMEDRIVER_PATH=$CHROMEDRIVER_DIR
ENTRYPOINT [ "python", "./calculate.py" ]

@mieubrisse
Copy link

Attaching ChatGPT's reasoning in case it's useful:

Screenshot 2025-03-08 at 17 02 18 Screenshot 2025-03-08 at 17 02 26 Screenshot 2025-03-08 at 17 02 36 Screenshot 2025-03-08 at 17 02 43

@BaggioGiacomo
Copy link

Thanks @mieubrisse.

If you need to run chrome in headless mode, this config is enough:

# Install Chromium, ChromeDriver, and minimal dependencies for headless mode
RUN apt-get update && apt-get install -y \
    chromium chromium-driver \
    && rm -rf /var/lib/apt/lists/*

Also, I don't think you need to install all of that dependencies manually, they are downloaded and installed automatically:

Here's the log of my app deploy with the config above:

DEBUG [c77ebb45] 	#13 [base 4/4] RUN apt-get update && apt-get install -y     chromium chromium-driver     && rm -rf /var/lib/apt/lists/*
 DEBUG [c77ebb45] 	#13 0.089 Get:1 http://deb.debian.org/debian bookworm InRelease [151 kB]
 DEBUG [c77ebb45] 	#13 0.098 Get:2 http://deb.debian.org/debian bookworm-updates InRelease [55.4 kB]
 DEBUG [c77ebb45] 	#13 0.099 Get:3 http://deb.debian.org/debian-security bookworm-security InRelease [48.0 kB]
 DEBUG [c77ebb45] 	#13 0.155 Get:4 http://deb.debian.org/debian bookworm/main amd64 Packages [8792 kB]
 DEBUG [c77ebb45] 	#13 0.227 Get:5 http://deb.debian.org/debian bookworm-updates/main amd64 Packages [13.5 kB]
 DEBUG [c77ebb45] 	#13 0.287 Get:6 http://deb.debian.org/debian-security bookworm-security/main amd64 Packages [246 kB]
 DEBUG [c77ebb45] 	#13 0.975 Fetched 9306 kB in 1s (10.5 MB/s)
 DEBUG [c77ebb45] 	#13 0.975 Reading package lists...
 DEBUG [c77ebb45] 	#13 1.360 Reading package lists...
 DEBUG [c77ebb45] 	#13 1.739 Building dependency tree...
 DEBUG [c77ebb45] 	#13 1.813 Reading state information...
 DEBUG [c77ebb45] 	#13 1.908 The following additional packages will be installed:
 DEBUG [c77ebb45] 	#13 1.908   adwaita-icon-theme alsa-topology-conf alsa-ucm-conf at-spi2-common
 DEBUG [c77ebb45] 	#13 1.908   at-spi2-core avahi-daemon avahi-utils bsdutils chromium-common
 DEBUG [c77ebb45] 	#13 1.908   chromium-sandbox cpp cpp-12 cups-pk-helper dbus dbus-bin dbus-daemon
 DEBUG [c77ebb45] 	#13 1.908   dbus-session-bus-common dbus-system-bus-common dbus-user-session
 DEBUG [c77ebb45] 	#13 1.908   dconf-gsettings-backend dconf-service dmsetup fonts-liberation
 DEBUG [c77ebb45] 	#13 1.908   gir1.2-atk-1.0 gir1.2-freedesktop gir1.2-gdkpixbuf-2.0 gir1.2-glib-2.0
 DEBUG [c77ebb45] 	#13 1.908   gir1.2-gtk-3.0 gir1.2-handy-1 gir1.2-harfbuzz-0.0 gir1.2-notify-0.7
 DEBUG [c77ebb45] 	#13 1.908   gir1.2-packagekitglib-1.0 gir1.2-pango-1.0 gir1.2-polkit-1.0 gir1.2-secret-1
 DEBUG [c77ebb45] 	#13 1.908   gsettings-desktop-schemas gtk-update-icon-cache hicolor-icon-theme
 DEBUG [c77ebb45] 	#13 1.908   libapparmor1 libargon2-1 libasound2 libasound2-data libasyncns0
 DEBUG [c77ebb45] 	#13 1.908   libatk-bridge2.0-0 libatk1.0-0 libatspi2.0-0 libauthen-sasl-perl
 DEBUG [c77ebb45] 	#13 1.908   libavahi-client3 libavahi-common-data libavahi-common3 libavahi-core7
 DEBUG [c77ebb45] 	#13 1.908   libblkid1 libclone-perl libcolord2 libcryptsetup12 libcups2 libdaemon0
 DEBUG [c77ebb45] 	#13 1.908   libdata-dump-perl libdbus-1-3 libdconf1 libdevmapper1.02.1
 DEBUG [c77ebb45] 	#13 1.908   libdouble-conversion3 libdrm-amdgpu1 libdrm-common libdrm-intel1
 DEBUG [c77ebb45] 	#13 1.908   libdrm-nouveau2 libdrm-radeon1 libdrm2 libduktape207 libedit2 libegl-mesa0
 DEBUG [c77ebb45] 	#13 1.908   libegl1 libelf1 libencode-locale-perl libepoxy0 libfdisk1
 DEBUG [c77ebb45] 	#13 1.908   libfile-basedir-perl libfile-desktopentry-perl libfile-listing-perl
 DEBUG [c77ebb45] 	#13 1.908   libfile-mimeinfo-perl libflac12 libfont-afm-perl libfontenc1 libgbm1
 DEBUG [c77ebb45] 	#13 1.908   libgdbm-compat4 libgdbm6 libgirepository-1.0-1 libgl1 libgl1-mesa-dri
 DEBUG [c77ebb45] 	#13 1.908   libglapi-mesa libgles2 libglvnd0 libglx-mesa0 libglx0 libgtk-3-0
 DEBUG [c77ebb45] 	#13 1.908   libgtk-3-bin libgtk-3-common libgudev-1.0-0 libhandy-1-0 libharfbuzz-subset0
 DEBUG [c77ebb45] 	#13 1.908   libhtml-form-perl libhtml-format-perl libhtml-parser-perl
 DEBUG [c77ebb45] 	#13 1.908   libhtml-tagset-perl libhtml-tree-perl libhttp-cookies-perl
 DEBUG [c77ebb45] 	#13 1.908   libhttp-daemon-perl libhttp-date-perl libhttp-message-perl
 DEBUG [c77ebb45] 	#13 1.908   libhttp-negotiate-perl libice6 libio-html-perl libio-socket-ssl-perl
 DEBUG [c77ebb45] 	#13 1.908   libio-stringy-perl libip4tc2 libipc-system-simple-perl libisl23 libjansson4
 DEBUG [c77ebb45] 	#13 1.908   libjson-c5 libkmod2 libldb2 libllvm15 liblmdb0 liblwp-mediatypes-perl
 DEBUG [c77ebb45] 	#13 1.908   liblwp-protocol-https-perl libmailtools-perl libminizip1 libmount1
 DEBUG [c77ebb45] 	#13 1.908   libmp3lame0 libmpc3 libmpfr6 libmpg123-0 libnet-dbus-perl libnet-http-perl
 DEBUG [c77ebb45] 	#13 1.908   libnet-smtp-ssl-perl libnet-ssleay-perl libnotify4 libnss-mdns
 DEBUG [c77ebb45] 	#13 1.908   libnss-systemd libogg0 libopenh264-7 libopus0 libpackagekit-glib2-18
 DEBUG [c77ebb45] 	#13 1.908   libpam-systemd libpangoxft-1.0-0 libpciaccess0 libperl5.36
 DEBUG [c77ebb45] 	#13 1.908   libpolkit-agent-1-0 libpolkit-gobject-1-0 libpopt0 libpulse0
 DEBUG [c77ebb45] 	#13 1.908   libpython3-stdlib libpython3.11-minimal libpython3.11-stdlib
 DEBUG [c77ebb45] 	#13 1.909   libregexp-ipv6-perl librsvg2-common libsecret-1-0 libsecret-common
 DEBUG [c77ebb45] 	#13 1.909   libsensors-config libsensors5 libsm6 libsmartcols1 libsmbclient libsndfile1
 DEBUG [c77ebb45] 	#13 1.909   libsystemd-shared libsystemd0 libtalloc2 libtdb1 libtevent0
 DEBUG [c77ebb45] 	#13 1.909   libtext-iconv-perl libtie-ixhash-perl libtimedate-perl libtry-tiny-perl
 DEBUG [c77ebb45] 	#13 1.909   libudev1 libupower-glib3 liburi-perl libusb-1.0-0 libuuid1 libvorbis0a
 DEBUG [c77ebb45] 	#13 1.909   libvorbisenc2 libwayland-client0 libwayland-cursor0 libwayland-egl1
 DEBUG [c77ebb45] 	#13 1.909   libwayland-server0 libwbclient0 libwww-perl libwww-robotrules-perl
 DEBUG [c77ebb45] 	#13 1.909   libx11-protocol-perl libx11-xcb1 libxaw7 libxcb-dri2-0 libxcb-dri3-0
 DEBUG [c77ebb45] 	#13 1.909   libxcb-glx0 libxcb-present0 libxcb-randr0 libxcb-shape0 libxcb-sync1
 DEBUG [c77ebb45] 	#13 1.909   libxcb-xfixes0 libxcomposite1 libxcursor1 libxdamage1 libxfixes3 libxft2
 DEBUG [c77ebb45] 	#13 1.909   libxi6 libxinerama1 libxkbcommon0 libxkbfile1 libxml-parser-perl
 DEBUG [c77ebb45] 	#13 1.909   libxml-twig-perl libxml-xpathengine-perl libxmu6 libxmuu1 libxnvctrl0
 DEBUG [c77ebb45] 	#13 1.909   libxpm4 libxrandr2 libxshmfence1 libxslt1.1 libxt6 libxtst6 libxv1
 DEBUG [c77ebb45] 	#13 1.909   libxxf86dga1 libxxf86vm1 libz3-4 media-types mount netbase
 DEBUG [c77ebb45] 	#13 1.909   notification-daemon perl perl-modules-5.36 perl-openssl-defaults polkitd
 DEBUG [c77ebb45] 	#13 1.909   python3 python3-cairo python3-cups python3-cupshelpers python3-dbus
 DEBUG [c77ebb45] 	#13 1.909   python3-gi python3-minimal python3-smbc python3.11 python3.11-minimal
 DEBUG [c77ebb45] 	#13 1.909   samba-libs sgml-base system-config-printer system-config-printer-common
 DEBUG [c77ebb45] 	#13 1.909   system-config-printer-udev systemd systemd-sysv systemd-timesyncd udev
 DEBUG [c77ebb45] 	#13 1.909   upower util-linux util-linux-extra x11-common x11-utils x11-xserver-utils
 DEBUG [c77ebb45] 	#13 1.909   xdg-utils xkb-data xml-core zutty

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment