Search code examples
pythondockergoogle-chrome

Headless Chrome in docker doest not print text


I am writing bot that supposed to generate images using Chrome. My stack is Python and html2image. Everything works fine on my machine™, even on VPS.

There is code for initializing chrome:

hti = Html2Image(
    size=(781, 4000),
    custom_flags=[
        "--disable-gpu",
        "--no-sandbox",
        "--disable-setuid-sandbox",
        "--headless=new",
        "--hide-scrollbars",
        "--log-level=3",
    ],
)

...

hti.screenshot(html_str=html, css_str=css, save_as=name)

Part of css for fonts:

@font-face {
    font-family: "Noto Sans";
    src: url("$fontregular");
}

@font-face {
    font-family: "Noto Emoji";
    src: url("$fontemoji");
}

@font-face {
    font-family: "Noto Mono";
    src: url("$fontmono");
}

$vars are replaced in runtime with python's Template with full font path. I don't think it's problem with fonts b/c in that case text would be rendered with default font.

But in docker text does not render. Dockerfile:

FROM debian:bookworm-slim@sha256:6bdbd579ba71f6855deecf57e64524921aed6b97ff1e5195436f244d2cb42b12 as chrome

RUN sed -i 's/deb.debian.org/debian.anexia.at/g' /etc/apt/sources.list.d/debian.sources
RUN apt-get update && apt-get install -y wget gnupg
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
RUN echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list
RUN apt-get install -f -y curl fonts-liberation libasound2 libatk-bridge2.0-0 libatk1.0-0 libatspi2.0-0
RUN apt-get install -f -y libcairo2 libcups2 libdbus-1-3 libdrm2 libexpat1 libgbm1 libglib2.0-0 libgtk-3-0 libgtk-4-1
RUN apt-get install -f -y libpango-1.0-0 libu2f-udev libvulkan1 libx11-6 libxcb1 libxcomposite1 libxdamage1 libxext6
RUN apt-get install -f -y libxkbcommon0 libxrandr2 xdg-utils libglib2.0-dev libnspr4 libnss3 libxfixes3 libc-bin libc6
RUN apt-get install -f -y locales
RUN curl -O https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
RUN dpkg -i google-chrome-stable_current_amd64.deb

FROM bitnami/python:3.9.18-debian-12-r29@sha256:607688045123fb4d60d6894ab64f297e51624883b51c340da1842dc5c8585411

COPY --from=chrome /opt/google/chrome /opt/google/chrome
COPY --from=chrome /usr/lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu
COPY --from=chrome /etc/fonts /etc/fonts

RUN echo "export PATH=/opt/google/chrome:${PATH}" >> /root/.bashrc

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY bot ./bot
COPY files ./files
COPY main.py .

CMD ["python", "main.py"]

There is chrome logs:

bot-1  | [0228/135225.424577:WARNING:chrome_main_linux.cc(80)] Read channel stable from /opt/google/chrome/CHROME_VERSION_EXTRA
bot-1  | [0228/135225.449320:WARNING:chrome_main_linux.cc(80)] Read channel stable from /opt/google/chrome/CHROME_VERSION_EXTRA
bot-1  | [9:9:0228/135225.473287:ERROR:browser_dm_token_storage_linux.cc(100)] Error: /etc/machine-id contains 0 characters (32 were expected).
bot-1  | (process:9): GLib-GIO-CRITICAL **: 13:52:25.699: g_settings_schema_source_lookup: assertion 'source != NULL' failed
bot-1  | [0228/135226.330480:ERROR:file_io_posix.cc(145)] open /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq: No such file or directory (2)
bot-1  | [0228/135226.330512:ERROR:file_io_posix.cc(145)] open /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq: No such file or directory (2)
bot-1  | [167:167:0228/135226.308521:ERROR:check.cc(319)] Check failed: false. NOTREACHED log messages are omitted in official builds. Sorry!
bot-1  | [167:167:0228/135226.332990:ERROR:check.cc(319)] Check failed: false. NOTREACHED log messages are omitted in official builds. Sorry!

What output supposed to looks like: https://ibb.co/tbpmMzX

What Chrome renders: https://ibb.co/wQMnpRr


Solution

  • Copying /usr/share fixed the problem.

    Updated Dockerfile:

    FROM debian:bookworm-slim@sha256:6bdbd579ba71f6855deecf57e64524921aed6b97ff1e5195436f244d2cb42b12 as chrome
    
    RUN sed -i 's/deb.debian.org/debian.anexia.at/g' /etc/apt/sources.list.d/debian.sources
    RUN apt-get update && apt-get install -y wget
    RUN wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
    RUN dpkg -i ./google-chrome*.deb; exit 0  # fixing deps on next line
    RUN apt-get install -y -f
    
    FROM bitnami/python:3.9.18-debian-12-r29@sha256:607688045123fb4d60d6894ab64f297e51624883b51c340da1842dc5c8585411
    
    COPY --from=chrome /opt/google/chrome /opt/google/chrome
    COPY --from=chrome /usr/share /usr/share
    COPY --from=chrome /usr/lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu
    COPY --from=chrome /etc/fonts /etc/fonts
    
    WORKDIR /app
    
    COPY requirements.txt .
    RUN pip install --no-cache-dir -r requirements.txt
    
    COPY bot ./bot
    COPY files ./files
    COPY main.py .
    
    CMD ["python", "main.py", "/opt/google/chrome"]