Raspberry Pi 3 - Browser Client: Difference between revisions

From Alpine Linux
(Add page to Category:Raspberry)
No edit summary
Line 1: Line 1:
This is a guide for setting up a RAM based Alpine which is able to run X, and firefox. This tutorial will go through setting up auto login, and starting X on boot without user interaction. It is a type of kiosk or possibly digital signage.
This is a guide for setting up a RAM based Alpine which is able to run X, and firefox. This tutorial will go through setting up auto login, and starting X on boot without user interaction, useful as a kiosk or for digital signage.


'''Tested as of 05/2020''' - RPI 3
'''Tested as of 05/2020''' - RPI 3
Line 10: Line 10:
This guide uses the following:
This guide uses the following:
* aarch64 img (though this guide is also x86-compatible)
* aarch64 img (though this guide is also x86-compatible)
* RPI3
* Raspberry Pi3
* community repo is used.
* community repo.


It is based off of this guide: [[Raspberry_Pi]]. Due to the dependencies required to run X and FF, there is very little RAM disk space for the user to operate in, after this tutorial is complete (about 30MB is v3.11). The 2GB RPI 4 has 1GB of ram, without adjusting /boot/config.txt. 1GB may be enough for most needs.
It is based on this guide: [[Raspberry_Pi]]. Due to the dependencies required to run X and Firefox, after this tutorial is complete there is very little RAM disk space for the user to operate in. (about 30MB in v3.11). The 2GB RPI 4 has 1GB of ram available without adjusting /boot/config.txt. 1GB may be enough for most needs.


aarch64 is used, because firefox-esr is in the community repo. armhf (as of v3.11) does not have firefox prepackaged in the base or community repo.
aarch64 is used because firefox-esr is in the community repo. armhf (as of v3.11) does not have firefox prepackaged in the base or community repo.


See https://pkgs.alpinelinux.org/packages?name=*firefox*&branch=v3.11&arch=aarch64
See https://pkgs.alpinelinux.org/packages?name=*firefox*&branch=v3.11&arch=aarch64


Note that the aarch64 build is not compatible with all RPI. See [[Raspberry Pi]].
Note: the aarch64 build is not compatible with all Raspberry Pi models. See [[Raspberry Pi]].


==Steps==
==Steps==
===Base Install===
===Base Install===


These steps are duplicated from [[Raspberry_Pi]] page.
These steps are duplicated from the [[Raspberry_Pi]] page.


Use fdisk or gdisk to format the SD card. You must have the first partition
Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem.  
be a bootable, FAT filesystem.  
e.g.:
e.g.:
<pre>
<pre>
Line 48: Line 47:
  tar xvf archive.tar -C /mnt/folder/.
  tar xvf archive.tar -C /mnt/folder/.


If you plan to enable increased RAM (e.g. for RPI4 with 2 or 4GB) or other
If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other
config settings, do so in a usercfg.txt now.
config settings, do so in usercfg.txt now.


Again, duplicating the [[Raspberry Pi]] page  
Again, duplicating the [[Raspberry Pi]] page  


     Insert the SD card into the Raspberry Pi and turn it on
     Insert the SD card into the Raspberry Pi and turn it on
     Login into the Alpine system as root. Leave the password empty.
     Log in to Alpine as root. Leave the password empty.
     Type setup-alpine
     Type setup-alpine, hit enter.
     Once the installation is complete, commit the changes by typing lbu commit -d
     Once the installation is complete, commit the changes by typing lbu commit -d


Things to keep in mind here:
Things to keep in mind:
* There is no need to make multiple partitions (e.g. on an sdcard). One partition that takes up the whole of the storage will suffice in diskless / sys mode.  
* There is no need to make multiple partitions (e.g. on an sdcard). One partition that occupies the entire storage medium will suffice in diskless / sys mode.  
* For the setup-alpine install, most of the choices will be at the defaults. Particularly when prompted with "No disks available, try boot media /mmcblk0p1". Here you will click the default [n]. If you make a mistake during the install, you can always reimage and start over.
* For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with "No disks available, try boot media /mmcblk0p1". Select the default [n]. If you make a mistake during the install, you can always reimage and start over.


Saving space: busybox instead of chronyd, dropbear instead of openssh
Saving space: busybox instead of chronyd, dropbear instead of openssh
Line 73: Line 72:
  rc-update add dropbear
  rc-update add dropbear


If you need an accurate clock, enable software/ntp here (optional, i don't need a clock for the website I view).
If you need an accurate clock, enable software/ntp here. (this step is optional)
  rc-update add swclock boot # enable the software clock  
  rc-update add swclock boot # enable the software clock  
  rc-update del hwclock boot # disable the hardware clock
  rc-update del hwclock boot # disable the hardware clock
Line 79: Line 78:


===Browser Client Install===
===Browser Client Install===


Enable community repo (/etc/apk/repositories) (uncomment community)
Enable community repo (/etc/apk/repositories) (uncomment community)
Line 85: Line 83:
  apk update
  apk update


install firefox and X dependencies:
install the firefox and X dependencies:
  apk add libx11-dev libxft-dev libxinerama-dev adwaita-gtk2-theme adwaita-icon-theme ttf-dejavu
  apk add libx11-dev libxft-dev libxinerama-dev adwaita-gtk2-theme adwaita-icon-theme ttf-dejavu
<small>Note that the fonts/icon theme are required for FF to display correctly. Without these, firefox will load, but text will not render on the browser menus.</small>
<small>Note: the fonts/icon theme is required for FF to display correctly. Without it, firefox will load, but text will not render on the browser menus.</small>


the RAM tmp fs remaining can be viewed while installing, with watch df -h
the amount of RAM tmp fs available can be viewed while installing with: watch df -h


install firefox
install firefox
Line 98: Line 96:
  apk add xf86-video-fbdev
  apk add xf86-video-fbdev


<small>note: this command can vary if you are using x86. For example, I installed no xf86-video... drivers, and had a libEGL.so missing library error on Xorg, and that was resolved via "apk search libEGL.so" which pointed to mesa-egl. Note that apk search is case sensitive.</small>
<small>note: this command can vary if you are using x86. For example, I installed no xf86-video... drivers, and had a libEGL.so missing library error on Xorg that was resolved with "apk search libEGL.so" which pointed to mesa-egl. Note: apk search is case sensitive.</small>


At this point, we have about 421MB used up (if NTP was not setup).
At this point, we have about 421MB of RAM used (if NTP was not set up).
<pre>
<pre>
Filesystem                Size      Used Available Use% Mounted on
Filesystem                Size      Used Available Use% Mounted on
Line 115: Line 113:
===AutoLogin, Startx automatically on Boot===
===AutoLogin, Startx automatically on Boot===


At this point, you should be able to login as root, and run startx manually. Now, we will add a number of configuration files that allow this to happen without user interaction.
At this point, you should be able to login as root, and run startx manually. Now we'll add configuration files to enable that without user interaction.


/root/ doesn't save any files, so it's necessary to edit files in /etc/ and lbu_commit -d after all changes. First let's add a file that will call firefox.
/root/ doesn't save any files, so it's necessary to edit files in /etc/ and run lbu_commit -d after all changes. First let's add a file that we'll call firefox.
<small>lbu_commit is alpine local backup. If you want to save folders other than /etc see:https://wiki.alpinelinux.org/wiki/Alpine_local_backup#Include_special_files.2Ffolders_to_the_apkovl
<small>lbu_commit is alpine local backup. If you want to save folders other than /etc see:https://wiki.alpinelinux.org/wiki/Alpine_local_backup#Include_special_files.2Ffolders_to_the_apkovl
also see: /etc/apk/protected_paths.d/lbu.list</small>
also see: /etc/apk/protected_paths.d/lbu.list</small>
Line 125: Line 123:
  firefox http://somewebsite.com
  firefox http://somewebsite.com


!!!NOTE: This is ash, not bash. By default, alpine ships with the ashbourne shell. Although bash is available in the repositories.
!!!NOTE: This is ash, not bash. By default, alpine ships with the ash shell. Bash is available in the repositories.


We have to edit xinitrc, and the profile configs. Normally, this would be done in the user's directory, but here we will use the globals for simplicity.
We have to edit xinitrc, and the profile configs. Normally, this would be done in the user's directory, but here we will use the globals for simplicity.
  mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK
  mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK
  nano /etc/X11/xinit/xinitrc
  nano /etc/X11/xinit/xinitrc
In this file put:
In this file, insert:
  /etc/startup.sh
  /etc/startup.sh
At the end of /etc/profile (leave the existing file) append
At the end of /etc/profile (leave the existing file) append
  startx
  startx
And remember to: lbu_commit -d For autologin, alpine uses busybox, which has an alias to /sbin/getty as well as /bin/login. It's possible to navigate to /sbin/ or /bin/ and run /sbin/getty -h to see what settings are available. To have root auto login upon boot, review the existing inittab and edit as needed, according to the config below.
Remember to run lbu_commit -d<BR>
For autologin, alpine uses busybox, which has an alias to /sbin/getty as well as /bin/login. It's possible to navigate to /sbin/ or /bin/ and run /sbin/getty -h to see what settings are available. To have root auto login at boot, review the existing inittab and edit as needed according to the config below:
<pre>
<pre>
# Set up a couple of getty's
# Set up a couple of gettys
#tty1::respawn:/sbin/getty 38400 tty1
#tty1::respawn:/sbin/getty 38400 tty1
tty2::respawn:/sbin/getty 38400 tty2
tty2::respawn:/sbin/getty 38400 tty2
Line 149: Line 148:
===Disable Screensaver, and refresh webpage (optional)===
===Disable Screensaver, and refresh webpage (optional)===


As a kiosk, the RPI will need to have the screensaver ([https://wiki.archlinux.org/DPMS DPMS]) disabled. Also, my particular application (video streams) required a refresh occasionally. These were managed with xorg.conf, xdotool, and crontab respectively.
As a kiosk, a Raspberry Pi needs to have the screensaver ([https://wiki.archlinux.org/DPMS DPMS]) disabled. My particular application (video streams) required a refresh occasionally. These were managed with xorg.conf, xdotool, and crontab respectively.


{{cat|/etc/X11/xorg.conf|
{{cat|/etc/X11/xorg.conf|
Line 161: Line 160:
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5</pre>
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5</pre>


<small>Note that xset is not an option here, as it's not included by default. It can be installed from repositories, if needed.</small>
<small>Note: xset is not an option here as it's not included by default. It can be installed from the repositories, if needed.</small><BR>
That's it. Now reboot, and watch the RPI boot into firefox without user intervention. At this point, you have a functioning minimal OS booting from RAM, with firefox, and ~30MB of available space for further configuration.
That's it. Reboot and the RPI should boot into firefox without user intervention. At this point, you have a functioning minimal OS booting from RAM, with firefox, and ~30MB of available space for further configuration.


==Digital Signage==
==Digital Signage==
It's common to use GNULinux and x86/RPIs for digital signage. A quick glance at https://elinux.org/RPi_Projects/Digital_Signage will show a number of options. Why would you use this guide for digital signage vs. those pre-built projects?  
It's common to use GNULinux and x86/RPIs for digital signage. A quick glance at https://elinux.org/RPi_Projects/Digital_Signage will show a number of options. Why would you use this guide for digital signage vs. those pre-built projects?  
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd).  
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd).  
# There is no requirement to use 'cloud' services, or depend upon an internet connection.  
# There is no requirement to use 'cloud' services, or an internet connection.  
# You have full control over the build and design (all kiosk build steps are documented & have a small learning curve, compared to some of the more complex projects mentioned above).
# You have full control over the build and design (all kiosk build steps are documented & have a small learning curve, compared to some of the more complex projects mentioned above).
# Free software. No recurring costs (outside of optional maintenance).  
# Free software. No recurring costs (outside of optional maintenance).  
# No ties to external infrastructure / frameworks. Full freedom.
# No ties to external infrastructure / frameworks. Full freedom.


In this addition to the guide above, I will install Chromium, which seems to be the defacto standard. However, you could use any application that runs in X. Here we will also run a web server with PHP, which hosts the resources we want to display on the sign.
In this addition to the guide above, we'll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we'll also run a web server with PHP, which hosts the resources we want to display on the sign.
Make sure community apk is enabled in /etc/apk/repositories
Make sure community apk is enabled in /etc/apk/repositories
  apk add chromium
  apk add chromium
In /etc/startup.sh add the browser instead of firefox:
In /etc/startup.sh add chromium instead of firefox:
   chromium-browser --home-page http://127.0.0.1/resource --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type
   chromium-browser --home-page http://127.0.0.1/resource --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type
Note that this is a potentially insecure setup, and users are advised to add a user, and remove the --no-sandbox tag. The tags used are the following: --home-page will start us on a given URL. --no-sandbox will allow root to run chromium. --window-size will give us the resolution we want, and start-fullscreen will ensure the browser takes up all of the screen.
Note: this is a potentially insecure setup. Users are advised to add a user, and remove the --no-sandbox tag. The following tags are used: --home-page will start us on a given URL. --no-sandbox will allow root to run chromium. --window-size will give us the resolution we want, and start-fullscreen will ensure the browser occupies the entire screen.


If you deploy the device on a TV, and you are unsure what resolution it is, you can access the resolution from the terminal (not in X), by using  
If you deploy the device on a TV, and you're unsure what resolution it is, you can access the resolution from the terminal (not in X), by using  
  xrandr -d :0
  xrandr -d :0
For example, I built my device on a computer monitor that was 1920x1280, but when I deployed, the TV was 1920x1080. Since we run chromium straight on X, without any WM, it's necessary to query xrandr from the console. If desired, you could install DWM and hide the bar, obtaining access to a terminal accessible via keyboard shortcut configured in dwm's config.h, But a WM is not required.
For example, I built my device on a computer monitor that was 1920x1280, but when I deployed, the TV was 1920x1080. Since we run chromium straight on X, without any WM, it's necessary to query xrandr from the console. If desired, you could install DWM and hide the bar, obtaining access to a terminal accessible via keyboard shortcut configured in dwm's config.h, But a WM is not required.


Make sure to lbu_commit -d, in order to save any changes as needed in the apkvol on the SD or HDD storage.
Make sure to run lbu_commit -d, in order to save any changes as needed in the apkvol on the SD or HDD storage.


===Install Apache/PHP===
===Install Apache/PHP===
Line 194: Line 193:


===Hide Scrollbars of Browser===
===Hide Scrollbars of Browser===
This can be done in CSS.
This can be done with CSS.
  body {
  body {
   overflow: hidden; /* Hide scrollbars */
   overflow: hidden; /* Hide scrollbars */
Line 201: Line 200:
==Tips/Troubleshooting==
==Tips/Troubleshooting==
===Why was this setup used? Why not Awesome, or dwm?===
===Why was this setup used? Why not Awesome, or dwm?===
I ran through a few different setups of alpine on the rpi, and found that (dwm | awesome) & firefox required too many dependencies to run on an RPI3 with 512MB in /tmp (running in RAM), or other browsers which used less dependencies were unstable (the application was viewing video streams). Therefore, running firefox direct off X was just barely able to fit into the available space, and was stable. This is one of the reasons aarch64 was used, instead of armhf. The 2GB RPI4 by default has 1GB of ram in alpine available (for storage), and doesn't have this limitation. It should be possible to get more RAM via /boot/config.txt
I ran through a few different setups of Alpine on the RPi, and found that (dwm | awesome) and Firefox required too many dependencies to run on an RPI3 with 512MB in /tmp (running in RAM). Other browsers that used fewer dependencies were unstable (the application was viewing video streams). Running firefox direct on X fit in the available space, and was stable. This is one of the reasons aarch64 was used, instead of armhf. With Alpine, by default the 2GB RPI4 has 1GB of RAM available (for storage), and doesn't have this limitation. It should be possible to get more RAM via /boot/config.txt


If your application doesn't require media (i.e. a static webpage) you may be able to run other browsers, such as midori, falkon, or surf, without stability issues on the RPI.
If your application doesn't require media (e.g. a static webpage) you may be able to run other browsers on the RPi, such as midori, falkon, or surf, without stability issues.


It is possible that VLC or a GTK/QT app would also fit into the limited space on the RPI 3. This was not tested.
It is possible that VLC or a GTK/QT app would also fit into the limited space on the RPI 3. That was not tested.


===Width & height of firefox doesn't fit the monitor===
===Width & height of firefox doesn't fit the monitor===
Line 212: Line 211:


===Periodic Firefox Crashes on RPI3 due to Low Memory===
===Periodic Firefox Crashes on RPI3 due to Low Memory===
With the RPI3, I found firefox crashing reliably after a couple days uptime of watching video. On the server I saw notices of memory running out. This may have been a memory leak, and with the small amount of RAM available, it would crash firefox, leaving the screen blank.  
With the RPI3, I found firefox would crash consistently after watching video for a couple of days. On the server I saw notices of memory running out. This may have been a memory leak. With the small amount of RAM available, Firefox would crash, leaving the screen blank.  


The solution was to setup a nightly reboot of the system via cron, and this has kept the system stable since. However, if I was to do this again, I would try an RPI4 with >1GB ram which may obviate the need for a nightly reboot.
The solution was to setup a nightly reboot of the system via cron. The system has been stable since. However, if I were to do this again, I would use an RPi4 with >1GB ram which may eliminate the need for a nightly reboot.





Revision as of 13:22, 8 August 2021

This is a guide for setting up a RAM based Alpine which is able to run X, and firefox. This tutorial will go through setting up auto login, and starting X on boot without user interaction, useful as a kiosk or for digital signage.

Tested as of 05/2020 - RPI 3

12/2020 - x86

04/2021 - RPI 4

Overview

This guide uses the following:

  • aarch64 img (though this guide is also x86-compatible)
  • Raspberry Pi3
  • community repo.

It is based on this guide: Raspberry_Pi. Due to the dependencies required to run X and Firefox, after this tutorial is complete there is very little RAM disk space for the user to operate in. (about 30MB in v3.11). The 2GB RPI 4 has 1GB of ram available without adjusting /boot/config.txt. 1GB may be enough for most needs.

aarch64 is used because firefox-esr is in the community repo. armhf (as of v3.11) does not have firefox prepackaged in the base or community repo.

See https://pkgs.alpinelinux.org/packages?name=*firefox*&branch=v3.11&arch=aarch64

Note: the aarch64 build is not compatible with all Raspberry Pi models. See Raspberry Pi.

Steps

Base Install

These steps are duplicated from the Raspberry_Pi page.

Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem. e.g.:

Command (m for help): p
Disk /dev/sdb: 59.5 GiB, 63864569856 bytes, 124735488 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000

Device     Boot Start      End  Sectors Size Id Type
/dev/sdb1  *     2048 62916607 62914560  30G  b W95 FAT32
mkdosfs -F 32 /dev/sdX1

untar onto mounted disk

mount /dev/sdX1 /mnt/folder
tar xvf archive.tar -C /mnt/folder/.

If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other config settings, do so in usercfg.txt now.

Again, duplicating the Raspberry Pi page

   Insert the SD card into the Raspberry Pi and turn it on
   Log in to Alpine as root. Leave the password empty.
   Type setup-alpine, hit enter.
   Once the installation is complete, commit the changes by typing lbu commit -d

Things to keep in mind:

  • There is no need to make multiple partitions (e.g. on an sdcard). One partition that occupies the entire storage medium will suffice in diskless / sys mode.
  • For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with "No disks available, try boot media /mmcblk0p1". Select the default [n]. If you make a mistake during the install, you can always reimage and start over.

Saving space: busybox instead of chronyd, dropbear instead of openssh

After setup, make sure dropbear is installed

apk add dropbear

Start it:

rc-service dropbear start

Add it to the default runlevel:

rc-update add dropbear

If you need an accurate clock, enable software/ntp here. (this step is optional)

rc-update add swclock boot # enable the software clock 
rc-update del hwclock boot # disable the hardware clock
setup-ntp

Browser Client Install

Enable community repo (/etc/apk/repositories) (uncomment community)

nano /etc/apk/repositories
apk update

install the firefox and X dependencies:

apk add libx11-dev libxft-dev libxinerama-dev adwaita-gtk2-theme adwaita-icon-theme ttf-dejavu

Note: the fonts/icon theme is required for FF to display correctly. Without it, firefox will load, but text will not render on the browser menus.

the amount of RAM tmp fs available can be viewed while installing with: watch df -h

install firefox

apk add firefox-esr

install X

setup-xorg-base

The RPI also requires for X:

apk add xf86-video-fbdev

note: this command can vary if you are using x86. For example, I installed no xf86-video... drivers, and had a libEGL.so missing library error on Xorg that was resolved with "apk search libEGL.so" which pointed to mesa-egl. Note: apk search is case sensitive.

At this point, we have about 421MB of RAM used (if NTP was not set up).

Filesystem                Size      Used Available Use% Mounted on
devtmpfs                 10.0M         0     10.0M   0% /dev
shm                     457.9M         0    457.9M   0% /dev/shm
/dev/mmcblk0p1           30.0G    259.4M     29.7G   1% /media/mmcblk0p1
tmpfs                   457.9M    420.0M     37.9M  92% /
tmpfs                    91.6M    188.0K     91.4M   0% /run
/dev/loop0               24.9M     24.9M         0 100% /.modloop
lbu_commit -d

AutoLogin, Startx automatically on Boot

At this point, you should be able to login as root, and run startx manually. Now we'll add configuration files to enable that without user interaction.

/root/ doesn't save any files, so it's necessary to edit files in /etc/ and run lbu_commit -d after all changes. First let's add a file that we'll call firefox. lbu_commit is alpine local backup. If you want to save folders other than /etc see:https://wiki.alpinelinux.org/wiki/Alpine_local_backup#Include_special_files.2Ffolders_to_the_apkovl also see: /etc/apk/protected_paths.d/lbu.list

create a file named /etc/startup.sh:

#!/bin/ash
firefox http://somewebsite.com

!!!NOTE: This is ash, not bash. By default, alpine ships with the ash shell. Bash is available in the repositories.

We have to edit xinitrc, and the profile configs. Normally, this would be done in the user's directory, but here we will use the globals for simplicity.

mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK
nano /etc/X11/xinit/xinitrc

In this file, insert:

/etc/startup.sh

At the end of /etc/profile (leave the existing file) append

startx

Remember to run lbu_commit -d
For autologin, alpine uses busybox, which has an alias to /sbin/getty as well as /bin/login. It's possible to navigate to /sbin/ or /bin/ and run /sbin/getty -h to see what settings are available. To have root auto login at boot, review the existing inittab and edit as needed according to the config below:

# Set up a couple of gettys
#tty1::respawn:/sbin/getty 38400 tty1
tty2::respawn:/sbin/getty 38400 tty2
tty3::respawn:/sbin/getty 38400 tty3
tty4::respawn:/sbin/getty 38400 tty4
tty5::respawn:/sbin/getty 38400 tty5
tty6::respawn:/sbin/getty 38400 tty6

tty1::respawn:/bin/login -f root

Disable Screensaver, and refresh webpage (optional)

As a kiosk, a Raspberry Pi needs to have the screensaver (DPMS) disabled. My particular application (video streams) required a refresh occasionally. These were managed with xorg.conf, xdotool, and crontab respectively.

Contents of /etc/X11/xorg.conf

Section "Extensions" Option "DPMS" "Disable" EndSection

# apk add xdotool

# crontab -u root -e 
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5

Note: xset is not an option here as it's not included by default. It can be installed from the repositories, if needed.
That's it. Reboot and the RPI should boot into firefox without user intervention. At this point, you have a functioning minimal OS booting from RAM, with firefox, and ~30MB of available space for further configuration.

Digital Signage

It's common to use GNULinux and x86/RPIs for digital signage. A quick glance at https://elinux.org/RPi_Projects/Digital_Signage will show a number of options. Why would you use this guide for digital signage vs. those pre-built projects?

  1. Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd).
  2. There is no requirement to use 'cloud' services, or an internet connection.
  3. You have full control over the build and design (all kiosk build steps are documented & have a small learning curve, compared to some of the more complex projects mentioned above).
  4. Free software. No recurring costs (outside of optional maintenance).
  5. No ties to external infrastructure / frameworks. Full freedom.

In this addition to the guide above, we'll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we'll also run a web server with PHP, which hosts the resources we want to display on the sign. Make sure community apk is enabled in /etc/apk/repositories

apk add chromium

In /etc/startup.sh add chromium instead of firefox:

 chromium-browser --home-page http://127.0.0.1/resource --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type

Note: this is a potentially insecure setup. Users are advised to add a user, and remove the --no-sandbox tag. The following tags are used: --home-page will start us on a given URL. --no-sandbox will allow root to run chromium. --window-size will give us the resolution we want, and start-fullscreen will ensure the browser occupies the entire screen.

If you deploy the device on a TV, and you're unsure what resolution it is, you can access the resolution from the terminal (not in X), by using

xrandr -d :0

For example, I built my device on a computer monitor that was 1920x1280, but when I deployed, the TV was 1920x1080. Since we run chromium straight on X, without any WM, it's necessary to query xrandr from the console. If desired, you could install DWM and hide the bar, obtaining access to a terminal accessible via keyboard shortcut configured in dwm's config.h, But a WM is not required.

Make sure to run lbu_commit -d, in order to save any changes as needed in the apkvol on the SD or HDD storage.

Install Apache/PHP

See Apache.

Install xset to disable screensaver

apk add xset
xset q
xset s off

Hide Scrollbars of Browser

This can be done with CSS.

body {
  overflow: hidden; /* Hide scrollbars */
}

Tips/Troubleshooting

Why was this setup used? Why not Awesome, or dwm?

I ran through a few different setups of Alpine on the RPi, and found that (dwm | awesome) and Firefox required too many dependencies to run on an RPI3 with 512MB in /tmp (running in RAM). Other browsers that used fewer dependencies were unstable (the application was viewing video streams). Running firefox direct on X fit in the available space, and was stable. This is one of the reasons aarch64 was used, instead of armhf. With Alpine, by default the 2GB RPI4 has 1GB of RAM available (for storage), and doesn't have this limitation. It should be possible to get more RAM via /boot/config.txt

If your application doesn't require media (e.g. a static webpage) you may be able to run other browsers on the RPi, such as midori, falkon, or surf, without stability issues.

It is possible that VLC or a GTK/QT app would also fit into the limited space on the RPI 3. That was not tested.

Width & height of firefox doesn't fit the monitor

Firefox can be called with -height and -width flags, e.g.

firefox -width 480 -height 640 somewebsite.com

Periodic Firefox Crashes on RPI3 due to Low Memory

With the RPI3, I found firefox would crash consistently after watching video for a couple of days. On the server I saw notices of memory running out. This may have been a memory leak. With the small amount of RAM available, Firefox would crash, leaving the screen blank.

The solution was to setup a nightly reboot of the system via cron. The system has been stable since. However, if I were to do this again, I would use an RPi4 with >1GB ram which may eliminate the need for a nightly reboot.


Related Links