Docker + Selenium + arm64

When I tried to use Selenium on RaspberryPi whose OS is Ubuntu, I couldn't do it because any image of SeleniumHQ/docker-selenium doesn't support arm64. I tried another way, which is downloading chromedriver from https://chromedriver.chromium.org/downloads, but it didn't work. I was completely exhausted. That's why I'm writing how to manage to do Selenium on the device .

Seleniarm

This repository is becoming mature. It could help you.

github.com (accessed on 2022/09/09)

Run a container

Start up a docker container.

docker run -it --rm python:3.9 /bin/bash

The following tasks should be done in the container.

Install chromium-browser and chromium-chromedriver

launchpad.net

Download .deb files of chromium-browser(depedencies also needed) and chromium-chromedriver from the above URL.

#! /bin/bash
# Update on 2021/12/30


# dependencies
wget https://launchpad.net/~canonical-chromium-builds/+archive/ubuntu/stage/+files/chromium-codecs-ffmpeg_96.0.4664.110-0ubuntu0.18.04.1_arm64.deb
wget https://launchpad.net/~canonical-chromium-builds/+archive/ubuntu/stage/+files/chromium-codecs-ffmpeg-extra_96.0.4664.110-0ubuntu0.18.04.1_arm64.deb

# chromium-browser
wget https://launchpad.net/~canonical-chromium-builds/+archive/ubuntu/stage/+files/chromium-browser_96.0.4664.110-0ubuntu0.18.04.1_arm64.deb

# chromium-chromedriver
wget https://launchpad.net/~canonical-chromium-builds/+archive/ubuntu/stage/+files/chromium-chromedriver_96.0.4664.110-0ubuntu0.18.04.1_arm64.deb

# Install all
apt-get update
apt-get install -y ./chromium-codecs-ffmpeg_96.0.4664.110-0ubuntu0.18.04.1_arm64.deb 
apt-get install -y. /chromium-codecs-ffmpeg-extra_96.0.4664.110-0ubuntu0.18.04.1_arm64.deb 
apt-get install -y ./chromium-browser_96.0.4664.110-0ubuntu0.18.04.1_arm64.deb 
apt-get install -y ./chromium-chromedriver_96.0.4664.110-0ubuntu0.18.04.1_arm64.deb

# Install selenium
pip install -U pip
pip install selenium

Sample Script

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time

def main():
    options = webdriver.ChromeOptions()
    options.add_argument('--headless')
    options.add_argument('--no-sandbox') # An error will occur without this line
    driver = webdriver.Chrome(options=options)
    try:
        driver.get('https://www.google.co.jp/')
        search = driver.find_element(By.NAME, 'q')
        search.send_keys('Python')
        search.send_keys(Keys.RETURN)

        time.sleep(3)
        driver.save_screenshot('search.png')
    finally:
        driver.close()
        driver.quit()

if __name__ == '__main__':
    main()

Result

I will fix the grabling someday...

Dockerfile

Here is an example of Dockerfile.

FROM python:3.9

# bullseye:  worked
# buster:    got an error "lsb_release: command not found"
# I don't know the reason


ARG VERSION=96.0.4664.110-0ubuntu0.18.04.1
ARG ARCH=arm64
ARG URLBASE=https://launchpad.net/~canonical-chromium-builds/+archive/ubuntu/stage/+files
WORKDIR /opt/chromium
RUN wget ${URLBASE}/chromium-codecs-ffmpeg_${VERSION}_${ARCH}.deb \
 && wget ${URLBASE}/chromium-codecs-ffmpeg-extra_${VERSION}_${ARCH}.deb \
 && wget ${URLBASE}/chromium-browser_${VERSION}_${ARCH}.deb \
 && wget ${URLBASE}/chromium-chromedriver_${VERSION}_${ARCH}.deb \
 && apt-get update \
 && apt-get install -y ./chromium-codecs-ffmpeg_${VERSION}_${ARCH}.deb \
 && apt-get install -y ./chromium-codecs-ffmpeg-extra_${VERSION}_${ARCH}.deb \
 && apt-get install -y ./chromium-browser_${VERSION}_${ARCH}.deb \
 && apt-get install -y ./chromium-chromedriver_${VERSION}_${ARCH}.deb \
 && rm -rf /var/lib/apt/lists/*

# Install selenium
RUN pip install --upgrade pip \
 && pip install selenium

Build for amd64

docker build --build-arg ARCH=amd64 .

Docker Buildx

Create install_chromium.sh with the following content.

# Command line arguments
PLATFORM=$1

# Constants
VERSION="96.0.4664.110-0ubuntu0.18.04.1"
ARCH=`echo ${PLATFORM} | cut -d '/' -f 2` 
URLBASE="https://launchpad.net/~canonical-chromium-builds/+archive/ubuntu/stage/+files"

# Download
wget ${URLBASE}/chromium-codecs-ffmpeg_${VERSION}_${ARCH}.deb
wget ${URLBASE}/chromium-codecs-ffmpeg-extra_${VERSION}_${ARCH}.deb
wget ${URLBASE}/chromium-browser_${VERSION}_{ARCH}.deb
wget ${URLBASE}/chromium-chromedriver_${VERSION}_${ARCH}.deb

# Install
apt-get update
apt-get install -y ./chromium-codecs-ffmpeg_${VERSION}_${ARCH}.deb 
apt-get install -y ./chromium-codecs-ffmpeg-extra_${VERSION}_${ARCH}.deb 
apt-get install -y ./chromium-browser_${VERSION}_${ARCH}.deb 
apt-get install -y ./chromium-chromedriver_${VERSION}_${ARCH}.deb
rm -rf /var/lib/apt/lists/*

Dockerfile is as follows.

FROM python:3.9

ARG TARGETPLATFORM

WORKDIR /opt/chromium
COPY install_chromium.sh /opt/chromium
RUN bash -e install_chromium.sh ${TARGETPLATFORM}

# Install Selenium
RUN pip install --upgrade pip \
 && pip install selenium

Build it for multiplatform.

docker buildx build --platform linux/amd64,linux/arm64 --push -t yourname/yourtag .

https://docs.docker.com/build/buildx/docs.docker.com (accessed on 2022/07/27)

Selenium Server ※ NOT work

The official images of docker-selenium don't support linux/arm64 architecture. Then why don't you build your own image from its Dockerfile?
Here is the repository.

github.com

First, clone the repo to your arm64 device.
According to Building the images section of the README, you can build everything by running:

make build VERSION=local

However, you need some extra actions to build for arm64 before you run the line.

Comment out "Customize sources for apt-get" section

When I manually built selenium/base image to investigate the reason why my build failed, I found it is because apt-get update failed. Then I commented out Customize sources for apt-get section in ./Base/Dockerfile.

Replace "amd64" to "arm64"

Replace string amd64 to arm64. (I remember it was just one in ./Base/Dockerfile)

sed -i 's/amd64/arm64/g' ./Base/Dockerfile

Build

VERSION=local make <rule>
# e.g. VERSION=local make standalone_firefox 

(For now, I don't succeed in building standalone_edge and standalone_chrome.)

You don't get <rule> if you are not used to make command. Just google it!

Build on linux/amd64 device

Some people (most of Windows10 users, for example) may want to build images on your amd64 device. docker buildx build command is suitable for it. It's an experimental feature of Docker. Now buildx has been a standard feature of Docker(2021/11/12). Just type docker buildx build instead of docker build.

https://docs.docker.com/build/buildx/docs.docker.com

I'm sorry but I won't write the detail here, because it is too much information to do here. I can make another article about it.

Brief Instruction:

  1. Enable Docker experimental features.
  2. Create a new builder by running docker buildx create --use.
  3. Replace docker build to docker buildx build in Makefile.
  4. Run VERSION=local NAME=yourname BUILD_ARGS="--platform linux/arm64 --push" make <rule>.