我的问题是如何在 docker 容器中运行 google chrome 进行 e2e 测试。 我从官方 Jenkins 映像创建了一个
Dockerfile
,但是当尝试运行 google chrome 时,它崩溃并显示错误:
Failed to move to new namespace: PID namespaces supported, Network namespace supported, but failed: errno = Operation not permitted
Trace/breakpoint trap (core dumped)
Jenkins Docker 镜像使用 Debian
jessie
。
我可以使用
--headless
标志运行 google chrome,并且不需要 X 服务器。
这是我的 docker 文件:
Jenkins 官方图片:
一个人使用 docker 的 GUI 运行 google chrome 的存储库:
我的第一个方法是使用
xvbf
,但是使用--headless
标志时过程更简单。
我可以在 Ubuntu 服务器中使用相同的安装命令运行 chrome,但在 docker 中却失败了。
在其他意图之后,我使用了
--no-sandbox
标志,但 docker images 显示了下一个错误。
[0427/180929.595479:WARNING:audio_manager.cc(295)] Multiple instances of AudioManager detected
[0427/180929.595537:WARNING:audio_manager.cc(254)] Multiple instances of AudioManager detected
libudev: udev_has_devtmpfs: name_to_handle_at on /dev: Operation not permitted
实际上我运行了这个命令:
google-chrome-stable --headless --disable-gpu --no-sandbox http://www.google.com
只需使用
--no-sandbox
启动 chrome 即可解决问题
使用这个图像
alpeware/chrome-headless-trunk
在ubuntu中为我工作!
该容器中用于启动 headless chrome 的命令是这样的:
/usr/bin/google-chrome-unstable \
--disable-gpu --headless --no-sandbox \
--remote-debugging-address=0.0.0.0 \
--remote-debugging-port=9222 --user-data-dir=/data
我使用以下命令在 Ubuntu 中启动了容器:
docker run -it --rm -p=0.0.0.0:9222:9222 \
--name=chrome-headless \
-v /tmp/chromedata/:/data alpeware/chrome-headless-trunk
然后使用Chrome连接到调试端口
localhost:9222
通过一些修改,您可能可以在 Jenkins 中运行它!
这篇文章正是我在 docker 中使用 Headless Chrome 运行 Karma 测试所需要的:
https://hackernoon.com/running-karma-tests-with-headless-chrome-inside-docker-ae4aceb06ed3
基本上,解决方案是使用
--no-sandbox
标志运行 Headless Chrome。
我们使用 Chrome 和 Chromedriver 构建了一个 Docker 映像,该映像以无头模式运行 Chrome 以进行自动化测试。我们在
docker-compose.yml
设置中使用它作为 PhantomJS 的直接替代品。该镜像基于 Alpine Linux,不需要也不包含 Selenium,因此它非常小。
来源: https://github.com/retreatguru/headless-chromedriver
Docker 中心: https://hub.docker.com/r/retreatguru/headless-chromedriver
我通过以下方式扩展了默认 Dockerfile Selenium Chrome Node
FROM selenium/standalone-chrome-debug:latest
MAINTAINER Serge Arbuzov <[email protected]>
USER root
### jenkins set up ###
RUN apt-get update && apt-get install -y openssh-server sudo
RUN mkdir /var/run/sshd
RUN adduser jenkins
RUN echo jenkins:jenkins | chpasswd
RUN echo "jenkins ALL=(ALL) NOPASSWD:ALL">>/etc/sudoers
USER root
RUN echo export DISPLAY=":1.5" >> /etc/environment
ADD run.sh /run.sh
RUN chmod +x /run.sh
EXPOSE 22
CMD ["/run.sh"]
我的 run.sh 是
#!/bin/bash
Xvfb :1 -screen 5 1024x768x8 &
/usr/sbin/sshd -D
所以我可以使用默认图像作为 Jenkins 节点
如果有人正在寻找如何在 docker 中运行 chrome 和 Bun:
注意: 此方法利用 docker 'watch' 模式,因为 Bun --watch 在 WSL/Docker 中不起作用
// Dockerfile
FROM oven/bun:1.1
ARG REFRESH=3
# install curl for healthchecks
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
# Installing required chrome dependencies manually
# goto https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#running-puppeteer-on-wsl-windows-subsystem-for-linux
RUN apt-get update && apt-get install -y libgtk-3-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2
# Set the working directory
RUN mkdir app
WORKDIR /app
COPY ./my_app ./
# Add user so we don't need --no-sandbox
# same layer as npm install to keep re-chowned files from using up several hundred MBs more space
RUN groupadd -r pptruser && useradd -r -g pptruser -G audio,video pptruser \
&& mkdir -p /home/pptruser/Downloads \
&& chown -R pptruser:pptruser /home/pptruser \
&& chown -R pptruser:pptruser /app
# Run everything after as non-privileged user.
USER pptruser
# install packages
RUN bun i
RUN bunx puppeteer browsers install chrome
EXPOSE 4010
CMD ["bun", "run", "dev"]
// .dockerignore
- 与 Dockerfile 放在同一目录中,这告诉 Docker 不要将 node_modules 复制到映像中以加快其创建速度。
my_app/node_modules
// docker-compose.yml
my_app:
container_name: my_app-my_image_name
image: my_image_name:my_app
build:
context: .
dockerfile: docker/my_app/Dockerfile
environment:
ENVIRONMENT: dev
develop:
watch:
- action: sync
path: ./my_app
target: /app
ignore:
- node_modules/
- action: sync+restart
path: ./my_app/package.json
target: /app/package.json
ports:
- "4010:4010"
healthcheck:
test: [ "CMD", "curl", "localhost:4010" ]
interval: 1s
timeout: 3s
retries: 30
// index.ts
const browser = await puppeteer.launch();
const page = await browser.newPage();