Open sfcgeorge opened 1 year ago
Until the Chromium team fixes this issue upstream, and for those who need a hacky workaround, you can always use socat (or anything similar) to forward to the debugging port which is only exposed on localhost inside the container:
wrap.sh:
#!/bin/sh
chromium-browser --headless=new --remote-debugging-port=9221 "$@" &
socat TCP-LISTEN:9222,fork,reuseaddr TCP:127.0.0.1:9221
Dockerfile:
FROM zenika/alpine-chrome:112
USER root
RUN apk add --no-cache socat
USER chrome
COPY wrap.sh .
ENTRYPOINT ["sh", "wrap.sh"]
When running the container, I can reach http://localhost:9222/json/version
on my machine.
{
"Browser": "Chrome/112.0.5615.165",
"Protocol-Version": "1.3",
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
"V8-Version": "11.2.214.14",
"WebKit-Version": "537.36 (@c262f36e6b1d711ee42d4fbe1343b49960593f18)",
"webSocketDebuggerUrl": "ws://127.0.0.1:9222/devtools/browser/bb3e6520-fa06-48a3-a8cd-26ac02fcf2c4"
}
The good thing is that the field webSocketDebuggerUrl
seems to automatically get the right port from the request so that it doesn't break the integrations using this discovery mechanism.
It's an old issue, but I have found workaround with host header
const getBrowserWSEndpoint = async () => {
const cdpVersionUrl = `http://${process.env.CHROME_HEADLESS_HOST}:${process.env.CHROME_HEADLESS_PORT}/json/version`
const response = await axios.get(cdpVersionUrl, {
headers: { Host: "127.0.0.1:9222" }
});
const browserWSEndpoint = response.data.webSocketDebuggerUrl.replace(
/127.0.0.1/g,
process.env.CHROME_HEADLESS_HOST
);
return browserWSEndpoint
}
then connect with WebSocket
import { connect } from 'puppeteer';
const browserWSEndpoint = await getBrowserWSEndpoint();
const browser = await connect({
browserWSEndpoint
});
docker-compose service
alpine-chrome:
image: zenika/alpine-chrome:119
container_name: alpine-chrome
command:
- --remote-debugging-address=0.0.0.0
- --remote-debugging-port=9222
- --no-sandbox
- --disable-gpu
if you are using kubernetes
spec:
containers:
- name: headless-chrome-backend
image: zenika/alpine-chrome:119
command:
- /usr/bin/chromium-browser
- --headless
- --no-sandbox
- --remote-debugging-address=0.0.0.0
- --remote-debugging-port=9222
- --disable-gpu
ports:
- containerPort: 9222
livenessProbe:
httpGet:
path: /
port: 9222
httpHeaders:
- name: host
value: 127.0.0.1
@mrm-ot I am not quite able to follow what your solution does if the connection is failing from a remote host? Spoofing the host header doesn't seem to be something that's working. Are you running your script from within the same container? would love to understand your fix a bit more!
@sfcgeorge were you able to find an elegant solution in the end?
Describe the bug
Chrome has a new headless mode! https://developer.chrome.com/articles/new-headless/
The old mode is
--headless
, the new one is--headless=chrome
in v108 and below (current Zenika version) or--headless=new
in subsequent versions.From within the container it seems to work fine
docker compose exec chrome wget -O- http://localhost:9222/json/list
But from another container I get "Connection refused"
docker compose exec web wget -O- http://chrome:9222/json/list
To Reproduce
Based on this issue https://github.com/Zenika/alpine-chrome/issues/158 I think it's
--remote-debugging-address=0.0.0.0
not working, which would be a Chrome bug, so I've reported it there https://bugs.chromium.org/p/chromium/issues/detail?id=1427419I'm opening the issue here for others to find or in case I'm wrong and there's some other magic flag that would fix it.
The new mode will become default one day and eventually the old mode will be removed.
Possible solution
Tried various flag incantations with no change.
Logs
Chrome logs (setting
--user-data-dir
doesn't fix this):Versions
Additional context
This whitelisted-ips setting also sounded promising but I don't think that's it https://github.com/Zenika/alpine-chrome/pull/198