Ansible Role linuxfabrik.lfops.chromium_headless¶
This role installs the headless Chromium shell together with the runtime libraries and fonts required for headless rendering, and sets up a socket-activated chromium-headless systemd service. Clients connect to a configurable TCP socket; Chromium is started on the first request via systemd-socket-proxyd and stopped again after a configurable idle timeout, so no RAM is wasted while the backend is unused.
The setup is used as a headless browser backend for tools such as the Icinga Web 2 PDF Export Module.
Available in the next LFOps release.
How the Role Behaves¶
- Three systemd units are deployed:
chromium-headless-proxy.socketlistens onlisten_address:listen_port(default127.0.0.1:9222).chromium-headless-proxy.servicerunssystemd-socket-proxyd, which bridges the activated socket to Chromium (Chromium itself does not implement the systemd socket-activation protocol), forwarding traffic tobackend_port(default9223). Onidle_timeoutseconds without traffic it exits. On EL8 (systemd 239) the underlying--exit-idle-timeoption does not exist, so the idle shutdown is skipped there and the backend stays resident once activated; on-demand start still works.chromium-headless.serviceruns the actual Chromium process under thechromiumsystem user. Its start job is held until Chromium's debugging port actually accepts connections, so the proxy (ordered after it) never races ahead and fails the first request. It is bound to the proxy viaBindsTo=, so when the proxy exits on idle, Chromium stops too; the SIGTERM-triggered exit is treated as clean so this does not mark the unit failed. It is not enabled on boot and must not be started directly. The proxy triggers it viaRequires=.
- On SELinux-enforcing hosts, two booleans are enabled:
systemd_socket_proxyd_bind_anyso thechromium-headless-proxy.socketunit may bind the listen port even when it carries an unexpected SELinux port type (on Rocky/RHEL 9 the default9222is registered ashplip_port_t), andsystemd_socket_proxyd_connect_anyso the proxy may connect to Chromium's non-standard backend port. - The service-lifecycle variables (
chromium_headless__service_enabled,__service_state) manage thechromium-headless-proxy.socketunit, not the Chromium service directly.
Dependent Roles¶
Any LFOps playbook that installs this role runs these for you. Optional ones can be disabled via the playbook's skip variables.
- On RHEL-compatible systems, the EPEL repository must be enabled (role: linuxfabrik.lfops.repo_epel). It provides the
chromium-headlesspackage. On Debian, thechromium-headless-shellpackage ships in the default repositories, so no extra repository is required.
Tags¶
chromium_headless
- Creates the
chromiumsystem user and group. - Installs Chromium along with the required runtime libraries and fonts.
- Sets the
systemd_socket_proxyd_bind_anyandsystemd_socket_proxyd_connect_anySELinux booleans. - Deploys all three systemd units (
chromium-headless-proxy.socket,chromium-headless-proxy.service,chromium-headless.service). - Ensures the
chromium-headless-proxy.socketis in the desired state. - Triggers: daemon-reload on any unit-file change; socket restart only on
chromium-headless-proxy.socketchanges. Changes to the proxy or Chromium service unit file take effect on the next socket-activation cycle.
chromium_headless:configure
- Deploys the three systemd units (
chromium-headless-proxy.socket,chromium-headless-proxy.service,chromium-headless.service). - Triggers: daemon-reload on any unit-file change; socket restart only on
chromium-headless-proxy.socketchanges. Changes to the proxy or Chromium service unit file take effect on the next socket-activation cycle.
chromium_headless:state
- Manages the
chromium-headless-proxy.socketstate (start, stop, enable, disable). - Triggers: none.
Optional Role Variables¶
chromium_headless__backend_port
- Internal port Chromium itself listens on. The proxy forwards traffic from
listen_portto this port. Only meaningful to change iflisten_portandbackend_portwould otherwise collide. - Type: Number.
- Default:
9223
chromium_headless__extra_args__host_var / chromium_headless__extra_args__group_var
- Additional Chromium CLI flags appended to the
ExecStartline ofchromium-headless.service, in the order listed. Useful for tuning behavior without overwriting the whole unit. - Type: List of dictionaries.
- Default:
[] -
Subkeys:
-
name:- Mandatory. The CLI flag, including any leading dashes and value (e.g.
--window-size=1920,1080). - Type: String.
- Mandatory. The CLI flag, including any leading dashes and value (e.g.
-
state:- Optional.
presentorabsent. - Type: String.
- Default:
'present'
- Optional.
-
chromium_headless__idle_timeout
- Seconds the
systemd-socket-proxydwaits without active connections before exiting. When it exits, the boundchromium-headless.servicestops automatically. The next inbound connection re-activates the whole chain, paying ~1-2 seconds of cold-start latency. Has no effect on EL8, whose systemd (239) lacks the--exit-idle-timeoption; the backend stays resident there. - Type: Number.
- Default:
300
chromium_headless__listen_address
- Address the
chromium-headless-proxy.socketbinds to. Chromium's own debugging port always stays on127.0.0.1regardless of this setting, so only the proxy is reachable here. Keep this on127.0.0.1unless you intentionally want to expose the proxy to other hosts; it enforces neither TLS nor authentication. - Type: String.
- Default:
'127.0.0.1'
chromium_headless__listen_port
- Port the proxy socket listens on. This is the endpoint clients connect to.
- Type: Number.
- Default:
9222
chromium_headless__service_enabled
- Enables or disables the
chromium-headless-proxy.socketat boot, analogous tosystemctl enable/disable --now. - Type: Bool.
- Default:
true
chromium_headless__service_state
- Changes the state of the
chromium-headless-proxy.socket, analogous tosystemctl start/stop/restart/reload. - Type: String. One of
reloaded,restarted,started,stopped. - Default:
'started'
chromium_headless__user_data_dir
- Home directory of the
chromiumsystem user and Chromium user data directory. Used both as the user'shome, as the--user-data-dirvalue for Chromium, and as the writable path exposed via systemdReadWritePaths=. - Type: String.
- Default:
'/var/lib/chromium-headless'
Example:
# optional
chromium_headless__backend_port: 9223
chromium_headless__extra_args__host_var:
- name: '--window-size=1920,1080'
- name: '--lang=de-CH'
chromium_headless__idle_timeout: 600
chromium_headless__listen_address: '127.0.0.1'
chromium_headless__listen_port: 9222
chromium_headless__service_enabled: true
chromium_headless__service_state: 'started'
chromium_headless__user_data_dir: '/var/lib/chromium-headless'