bahmutov / cypress-image

Full Docker image for running Cypress CI test in your own container
5 stars 4 forks source link

Add Chrome #4

Open bahmutov opened 7 years ago

bahmutov commented 7 years ago

Install Chrome browser for extra browser for testing (if needed)

bahmutov commented 7 years ago

Seems the Chrome install is not working. See images/node-6-xvfb-chrome which is installing Chrome, but it does not start correctly.

Investigation locally to get Chrome to make successful request, finally to it to work

Working

on Mac first map a random IP so that from inside Docker we can reach "localhost".

sudo ifconfig lo0 alias 123.123.123.123/24

Server on the local host should listen to all IP addresses

const http = require("http")
http.createServer((req, res) => {
  console.log("GOT A REQUEST")
  process.exit()
}).listen(2345, '0.0.0.0')

This is working: starting the container in privileged mode, Chrome in headless mode. The server gets the request.

docker run --privileged --net=host \
  -it bahmutov/cypress-image:node-6-xvfb-chrome \
  chrome --headless --disable-gpu http://123.123.123.123:2345

--net=host is necessary to give Docker on Mac access to all local network information from the host.

--disable-gpu is necessary to limit warnings from Chrome

--headless is necessary to run without Xvfb

Similarly, we can add all capabilities when running container and it also works

docker run --cap-add=ALL --net=host \
  -it bahmutov/cypress-image:node-6-xvfb-chrome \
  chrome --headless --disable-gpu http://123.123.123.123:2345

Instead of ALL we only need --cap-add=SYS_ADMIN - it works.

Dropping capabilities

This prevents Chrome from working

$ docker run --cap-add=SYS_ADMIN --cap-drop=SYS_CHROOT --net=host \
  -it bahmutov/cypress-image:node-6-xvfb-chrome \
  chrome --headless --disable-gpu http://123.123.123.123:2345
Check failed: sys_chroot("/proc/self/fdinfo/") == 0
bahmutov commented 7 years ago

Found CircleCI Docker image repo https://github.com/circleci/image-builder

which has each browser setup script, for example

For Chrome, it does the following trick

#!/bin/bash

function install_chrome_browser() {
    echo '>>> Installing Chrome'

    local url="https://s3.amazonaws.com/circle-downloads/google-chrome-stable_54.0.2840.100-1_amd64.deb"
    local deb_path="/tmp/google-chrome.deb"

    curl --output $deb_path $url

    dpkg -i $deb_path || apt-get -f install

    # Disable sandboxing - it conflicts with unprivileged lxc containers
    sed -i 's|HERE/chrome"|HERE/chrome" --disable-setuid-sandbox --enable-logging --no-sandbox|g' \
               "/opt/google/chrome/google-chrome"
}
bahmutov commented 7 years ago

The way CircleCI runs XVFB is also interesting https://github.com/circleci/image-builder/blob/271bbe4ecf6bde1054bcd53da508bda9750fb864/circleci-provision-scripts/circleci-specific.sh#L46

bahmutov commented 7 years ago

Got successful Chrome install finally using the following Docker file and install script

FROM node:6

ENV VERBOSE true

RUN apt-get update
RUN apt-get install -y xvfb
# try installing just Chrome file and it tells you the missing dependencies
# install them here
RUN apt-get install -y \
  gconf-service \
  libasound2 \
  libatk1.0-0 \
  libcups2 \
  libdbus-1-3 \
  libgconf-2-4 \
  libgtk2.0-0 \
  libnspr4 \
  libnss3 \
  libpango1.0-0 \
  libxss1 \
  libxtst6 \
  fonts-liberation \
  libappindicator1 \
  xdg-utils

WORKDIR .
ADD chrome.sh chrome.sh
RUN ./chrome.sh

# RUN \
#   wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \
#   echo "deb http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google.list && \
#   apt-get update && \
#   apt-get install -y xvfb google-chrome-stable && \
#   rm -rf /var/lib/apt/lists/*

# RUN chrome --version
RUN google-chrome --version

RUN ln -s google-chrome /usr/bin/chrome

chrome install script

#!/bin/bash

# from https://github.com/circleci/image-builder

function install_chrome_browser() {
    echo '>>> Installing Chrome'

    local url="https://s3.amazonaws.com/circle-downloads/google-chrome-stable_54.0.2840.100-1_amd64.deb"
    local deb_path="/tmp/google-chrome.deb"

    curl --output $deb_path $url

    dpkg -i $deb_path || apt-get -f install -y

    # Disable sandboxing - it conflicts with unprivileged lxc containers
    sed -i 's|HERE/chrome"|HERE/chrome" --disable-setuid-sandbox --enable-logging --no-sandbox|g' \
               "/opt/google/chrome/google-chrome"
}

install_chrome_browser

run command from the Docker requires user data folder

chrome --user-data-dir=/chrome-data http://123.123.123.123:2345
bahmutov commented 7 years ago

Tried command to install latest Chrome, but it does not run at all (but does not report an error) https://discuss.circleci.com/t/installing-chrome-inside-of-your-docker-container/9067

# Install Chrome
RUN wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
RUN dpkg -i google-chrome-stable_current_amd64.deb; apt-get -fy install

start container

docker run -it bahmutov/cypress-image:node-6-xvfb-chrome /bin/bash
xvfb-run -e -a chrome --user-data-dir=/chrome-data http://123.123.123.123:2345
Failed to move to new namespace: PID namespaces supported, Network namespace supported, but failed: errno = Operation not permitted
Trace/breakpoint trap

Need to run in the privileged mode

docker run --privileged -it bahmutov/cypress-image:node-6-xvfb-chrome /bin/bash

Even then, cannot connect to the dbus error?

root@9b47c67d8a9f:/# xvfb-run -e -a chrome --disable-gpu http://123.123.123.123:2345
Xlib:  extension "RANDR" missing on display ":99".
[351:367:0521/141813.496675:ERROR:bus.cc(427)] Failed to connect to the bus: Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory
Xlib:  extension "RANDR" missing on display ":99".
[351:351:0521/141813.573448:ERROR:desktop_window_tree_host_x11.cc(1147)] Not implemented reached in virtual void views::DesktopWindowTreeHostX11::InitModalType(ui::ModalType)

So the only consistent way of running was to run in headless mode

xvfb-run -e -a chrome --headless --disable-gpu http://123.123.123.123:2345
bahmutov commented 7 years ago

Hmm, trying circleci/build-image:ubuntu-14.04-enterprise-1063-92d3662 image which has Chrome installed, but it always crashes with an error

[87:98:0521/145534:ERROR:bus.cc(434)] Failed to connect to the bus: 
Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory
bahmutov commented 7 years ago

Hmm, tried running circleci/build-image:ubuntu-14.04-XXL-1167-271bbe4 but my Mac docker has a problem starting it - too large!

bahmutov commented 7 years ago

Chromium inside docker https://github.com/ConSol/docker-headless-vnc-container/issues/2

Based on Ubuntu in https://github.com/ConSol/docker-headless-vnc-container/blob/master/Dockerfile.ubuntu.xfce.vnc

#!/usr/bin/env bash
### every exit != 0 fails the script
set -e

echo "Install Chromium Browser"
apt-get update 
apt-get install -y chromium-browser chromium-browser-l10n chromium-codecs-ffmpeg
apt-get clean -y
ln -s /usr/bin/chromium-browser /usr/bin/google-chrome
### fix to start chromium in a Docker container, see https://github.com/ConSol/docker-headless-vnc-container/issues/2
echo "CHROMIUM_FLAGS='--no-sandbox --start-maximized --user-data-dir'" > $HOME/.chromium-browser.init