FROM registry.redhat.io/rhel9/rhel-bootc:9.7 # Must be 9.7. Because the podman is super old on 9.4 and throws confusing error. # --- RHSM (only if you need it during build; otherwise remove) --- RUN subscription-manager register --activationkey=xxxxxxx --org=xxxxxx && \ subscription-manager status # --- Enable EPEL (Chromium on EL9 is typically from EPEL) --- RUN dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm && \ dnf -y makecache && \ dnf clean all # --- Packages: httpd + kiosk stack (Xorg + startx + Chromium) + SELinux tooling --- RUN dnf -y install --setopt=install_weak_deps=False \ httpd \ chromium \ xorg-x11-server-Xorg \ xorg-x11-xinit \ xorg-x11-xauth \ xorg-x11-server-utils \ dbus-daemon \ curl \ cloud-init \ open-vm-tools \ policycoreutils \ policycoreutils-python-utils \ selinux-policy-targeted \ && dnf clean all # --- Flightctl agent repo + install --- RUN dnf -y install dnf-plugins-core && dnf clean all RUN dnf config-manager --add-repo https://rpm.flightctl.io/flightctl-epel.repo RUN dnf -y install flightctl-agent && dnf clean all RUN mkdir -p /etc/flightctl/ ADD config.yaml /etc/flightctl/config.yaml # --- Cloud-init: stop EC2 probing on QEMU --- RUN mkdir -p /etc/cloud/cloud.cfg.d && \ cat > /etc/cloud/cloud.cfg.d/99-datasource.cfg <<'EOF' datasource_list: [ NoCloud, None ] EOF # --- Apache: content --- RUN mkdir -p /var/lib/kiosk/html/ && \ cat > /var/lib/kiosk/html/index.html <<'EOF' Kiosk

Initial BootC RHEL

EOF # Symlink the standard Apache path to our persistent location # This ensures /var/www/html (read-only) points to /var/lib/kiosk/html (writable) RUN rm -rf /var/www/html RUN chmod 777 -R /var/lib/kiosk/html/ RUN ln -s /var/lib/kiosk/html /var/www # --- Apache: log files in /var/log/httpd --- RUN mkdir -p /var/log/httpd && \ sed -ri \ -e 's|^ErrorLog .*|ErrorLog /var/log/httpd/error_log|' \ -e 's|^CustomLog .*|CustomLog /var/log/httpd/access_log combined|' \ /etc/httpd/conf/httpd.conf # --- SELinux: correct contexts --- # We target the actual path in /var/lib/kiosk/html RUN semanage fcontext -a -t httpd_sys_content_t '/var/lib/kiosk/html(/.*)?' && \ semanage fcontext -a -t httpd_log_t '/var/log/httpd(/.*)?' && \ restorecon -Rv /var/lib/kiosk /var/log/httpd || true RUN cat > /etc/containers/auth.json <<'EOF' { "auths": { "quay.io/alitestseverything": { "auth": "base64 encoded (username:token)" } } } EOF # --- Kiosk user --- RUN useradd -m -G wheel kiosk && \ echo 'kiosk:kiosk' | chpasswd # --- Autologin on tty1 --- RUN mkdir -p /etc/systemd/system/getty@tty1.service.d/ && \ cat > /etc/systemd/system/getty@tty1.service.d/autologin.conf <<'EOF' [Service] ExecStart= ExecStart=-/sbin/agetty --autologin kiosk --noclear %I $TERM EOF # --- Script to refresh/relaunch Chromium --- RUN cat > /usr/local/bin/kiosk-refresh.sh <<'EOF' #!/bin/bash # Find the Chromium process running as the kiosk user and terminate it. # The kiosk-session.sh loop will automatically restart it. pkill -u kiosk -f chromium || echo "Chromium not running." EOF RUN chmod +x /usr/local/bin/kiosk-refresh.sh # --- Kiosk session command (Chromium opens httpd) --- # IMPORTANT: On EPEL/RHEL-like setups the executable is often /usr/bin/chromium-browser (not /usr/bin/chromium), # so we detect it at runtime. [web:378] RUN cat > /usr/local/bin/kiosk-session.sh <<'EOF' #!/bin/bash set -euo pipefail # Detect resolution from xrandr # We wait a moment for X to initialize the display sleep 2 WIDTH=$(xrandr | grep '*' | awk '{print $1}' | cut -d 'x' -f1) HEIGHT=$(xrandr | grep '*' | awk '{print $1}' | cut -d 'x' -f2) URL="http://127.0.0.1/" BROWSER="$(command -v chromium-browser || true)" if [[ -z "${BROWSER}" ]]; then BROWSER="$(command -v chromium || true)" fi if [[ -z "${BROWSER}" ]]; then echo "No chromium binary found (expected chromium-browser or chromium)" >&2 exit 1 fi while true; do rm -rf /tmp/chromium-kiosk-profile || true /usr/bin/dbus-run-session -- "${BROWSER}" \ --kiosk \ --no-first-run \ --window-position=0,0 \ --window-size="${WIDTH},${HEIGHT}" \ --force-device-scale-factor=1 \ --disable-session-crashed-bubble \ --disable-infobars \ --disable-notifications \ --user-data-dir=/tmp/chromium-kiosk-profile \ "${URL}" \ || true sleep 1 done EOF RUN chmod +x /usr/local/bin/kiosk-session.sh # --- systemd unit: start X rootless on VT1 with logind session --- RUN cat > /etc/systemd/system/kiosk.service <<'EOF' [Unit] Description=Kiosk (Xorg + Chromium) Wants=network-online.target httpd.service After=systemd-user-sessions.service network-online.target httpd.service StartLimitIntervalSec=0 [Service] User=kiosk WorkingDirectory=/var/home/kiosk PAMName=login Environment=XDG_SESSION_TYPE=x11 Environment=DISPLAY=:0 TTYPath=/dev/tty8 StandardInput=tty StandardOutput=journal StandardError=journal UnsetEnvironment=TERM UtmpIdentifier=tty8 UtmpMode=user ExecStartPre=/usr/bin/chvt 8 ExecStartPre=/bin/bash -lc 'for i in $(seq 1 60); do curl -fsS http://127.0.0.1/ >/dev/null 2>&1 && exit 0; sleep 1; done; exit 0' ExecStart=/usr/bin/startx /usr/local/bin/kiosk-session.sh -- vt8 -keeptty -nolisten tcp -verbose 3 Restart=always RestartSec=2 [Install] WantedBy=graphical.target EOF # --- Enable services --- RUN systemctl enable httpd && \ systemctl enable flightctl-agent.service && \ systemctl enable kiosk.service && \ systemctl enable vmtoolsd.service RUN systemctl set-default graphical.target # --- Cleanup --- RUN rm -rf /var/cache/* /var/tmp/*