Aurimas Deimantas
Aurimas Deimantas

Reputation: 771

Docker + Google Cloud + chromedriver -> executable needs to be in PATH

I've spent last two days and I'm losing my hair. I run ubuntu on my Google Cloud machine. My Dockerfile looks like this


# Project files
ARG PROJECT_DIR=/srv/api
RUN mkdir -p $PROJECT_DIR
WORKDIR $PROJECT_DIR

# Install Python dependencies
COPY ./ ./
RUN mv /srv/api/app/chromedriver_linux /usr/bin/chromedriver_linux
RUN ls /usr/bin/

I write ls to check if chromedriver_linux exists in my path. It does exist in /usr/bin/chromedriver_linux

Then in my code I specify

chrome_options = webdriver.ChromeOptions()
    chrome_options.add_argument('--disable_infobars')
    chrome_options.add_experimental_option("mobileEmulation", mobile_emulation)
    driver = webdriver.Chrome('/usr/bin/chromedriver_linux', options=chrome_options)

And I receive

selenium.common.exceptions.WebDriverException: Message: 'chromedriver_linux' executable needs to be in PATH. Please see https://sites.google.com/a/chromium.org/chromedriver/home

Interesting enough, if I run Docker on my local machine and specify chromedriver for mac - it works. That I cannot figure out - why it works on local machine but doesn't on cloud.

Looking forward hearing you, smart people, what did I miss here!

Upvotes: 2

Views: 1728

Answers (1)

Aurimas Deimantas
Aurimas Deimantas

Reputation: 771

Finally after several non-sleep days I got it.

Firstly, I was running Alpine version of Ubuntu. It was the first problem. But I made it work. So if you guys are running Alpine too, this is the solution:

Dockerfile

FROM python:3.6.6-alpine3.8

# Project files
ARG PROJECT_DIR=/srv
RUN mkdir -p $PROJECT_DIR
WORKDIR $PROJECT_DIR

# Install Python dependencies
COPY ./ ./

RUN apk update
RUN apk add curl
RUN apk add unzip nano bash chromium chromium-chromedriver

RUN pip3 install -r requirements.txt

Whole magic was to install Chromium. Now our *.py looks like this:

mobile_emulation = {"deviceName": "iPhone X"}
    chrome_options = webdriver.ChromeOptions()
    chrome_options.add_argument('--headless')
    chrome_options.add_argument('--no-sandbox')
    chrome_options.add_argument('--disable-dev-shm-usage')

    #chrome_options.add_argument('--disable_infobars')
    chrome_options.add_experimental_option("mobileEmulation", mobile_emulation)
    driver = webdriver.Chrome(executable_path='/usr/bin/chromedriver', options=chrome_options)
    driver.get('https://google.com')

BONUS. I wanted to use different chromedriver and decided that Alpine really messes things up. Installed proper ubuntu with python and made chromedriver work. Here's how it looks: Dockerfile

FROM ubuntu:18.04

# Project files
ARG PROJECT_DIR=/srv
RUN mkdir -p $PROJECT_DIR
WORKDIR $PROJECT_DIR


# Update
RUN apt-get update
RUN apt-get -y upgrade


# Set the locale
RUN apt-get install -y locales && locale-gen "en_US.UTF-8" && dpkg-reconfigure -f noninteractive locales
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
ENV PYTHONIOENCODING utf-8

RUN echo \
    && echo 'LANG=en_US.UTF-8' >> /etc/environment \
    && echo 'LANGUAGE=en_US:en' >> /etc/environment \
    && echo 'LC_ALL=en_US.UTF-8' >> /etc/environment \
    && echo 'PYTHONIOENCODING=utf-8' >> /etc/environment


# Install Python dependencies
RUN apt-get install --upgrade -y python3-pip
RUN apt-get install -y build-essential libssl-dev libffi-dev python3-dev
RUN apt-get install -y curl
RUN apt-get install -y unzip


# Copy everything to Docker
COPY ./ ./

# Install chromium instead
RUN apt-get install -y chromium-browser

# Install chromedriver for Chromium
RUN curl https://chromedriver.storage.googleapis.com/75.0.3770.140/chromedriver_linux64.zip -o /usr/local/bin/chromedriver.zip
RUN unzip /usr/local/bin/chromedriver.zip -d /usr/local/bin/
RUN chmod +x /usr/local/bin/chromedriver || rm /usr/local/bin/chromedriver.zip

RUN pip3 install -r requirements.txt

And our code looks like this:

 mobile_emulation = {"deviceName": "iPhone X"}
    chrome_options = webdriver.ChromeOptions()
    chrome_options.add_argument('--headless')
    chrome_options.add_argument('--no-sandbox')
    chrome_options.add_argument('--disable-dev-shm-usage')

    #chrome_options.add_argument('--disable_infobars')
    chrome_options.add_experimental_option("mobileEmulation", mobile_emulation)
    driver = webdriver.Chrome(executable_path='/usr/local/bin/chromedriver', options=chrome_options)
    driver.get('https://google.com')
    driver.close()

I hope it can save you hours. Happy coding!

Upvotes: 5

Related Questions