Raspberry Pi 3 - Browser Client: Difference between revisions
Alpineuser (talk | contribs) |
Alpineuser (talk | contribs) No edit summary |
||
(49 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
This is a guide for setting up a RAM based | 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. Later on I will use chromium which was used for a production sign and runs well, with a local website. | ||
This guide (more or less, I may have made some other customizations) Production tested with 3.13.5 (on RPI4) and stable for over 3 years. I have also run this on 3.17 with x86 (not tested as long). | |||
Note that this guide started out with an RPI3, has been used with x86, and currently runs with an RPI4, though the guide hasn't been fully updated yet. Hopefully, when time permits, and I have to remake the sign (or a new one) I will be able to edit this doc to represent either the RPI4 or RPI5 with alpine. | |||
==Overview== | ==Overview== | ||
This guide uses the following: | This guide uses the following: | ||
* aarch64 img | * aarch64 img (though this guide is also tested to be roughly x86-compatible) | ||
* | * Raspberry Pi3 | ||
* community repo | * community repo. | ||
It is based | 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 {{path|/boot/config.txt}}. 1GB may be enough for most needs. | ||
aarch64 is used | 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 | 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 [[ | These steps are duplicated from the [[Raspberry Pi]] page. (Note that for sake of this guide, it's assumed the RPI is a RAM only install. Although there is no requirement for it to be done this way). | ||
Use fdisk or gdisk to format the SD card. | 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 37: | Line 38: | ||
/dev/sdb1 * 2048 62916607 62914560 30G b W95 FAT32 | /dev/sdb1 * 2048 62916607 62914560 30G b W95 FAT32 | ||
</pre> | </pre> | ||
{{cmd|# mkdosfs -F 32 /dev/sdX1}} | |||
untar onto mounted disk | untar onto mounted disk | ||
{{cmd|<nowiki># mount /dev/sdX1 /mnt/folder | |||
# tar xvf archive.tar -C /mnt/folder/. | |||
</nowiki>}} | |||
If you plan to | If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other | ||
config settings, do so in | config settings, do so in {{path|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 | ||
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: | |||
* 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 | After setup, make sure dropbear is installed | ||
{{cmd|# apk add dropbear}} | |||
Start it: | Start it: | ||
{{cmd|# rc-service dropbear start}} | |||
Add it to the default runlevel: | Add it to the default runlevel: | ||
{{cmd|# rc-update add dropbear}} | |||
If you need an accurate clock, enable software/ntp here (optional | If you need an accurate clock, enable software/ntp here. (this step is optional) | ||
{{cmd|<nowiki># rc-update add swclock boot # enable the software clock | |||
# rc-update del hwclock boot # disable the hardware clock | |||
# setup-ntp | |||
</nowiki>}} | |||
===Browser Client Install=== | ===Browser Client Install=== | ||
Enable community repo ({{path|/etc/apk/repositories}}) (uncomment community) | |||
{{cmd|<nowiki># nano /etc/apk/repositories | |||
# apk update</nowiki>}} | |||
install firefox dependencies: | |||
{{cmd|# apk add libx11-dev libxft-dev libxinerama-dev font-dejavu}} | |||
<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 amount of RAM tmp fs available can be viewed while installing with: <code>watch df -h</code> | |||
the RAM tmp fs | |||
install firefox | install firefox | ||
{{cmd|# apk add firefox-esr}} | |||
install X | install X | ||
{{cmd|# setup-xorg-base}} | |||
The RPI also requires for X: | The RPI also requires for X: | ||
{{cmd|# 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 | <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. Some other video drivers may be xf86-video-intel, xf86-video-vesa... Refer to the Xorg logs if you get an error with the display drivers.</small> | ||
At this point, we have about 421MB used | 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 104: | Line 109: | ||
</pre> | </pre> | ||
{{cmd|# lbu_commit -d}} | |||
===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 | 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. | ||
<small>What is happening here from my understanding is: | |||
1) User logs in. {{path|/etc/profile}} is run (which includes a call to startx) | |||
2) Startx references any relevant xinitrc (user folder or {{path|/etc/X11}}), which calls {{path|/etc/startup.sh}} | |||
3) {{path|/etc/startup.sh}} runs any commands, such as dwm, firefox, or chromium. | |||
If you want to manually startx upon login, then omit /etc/profile, or alternatively include only a custom profile for {{path|/root/.profile}}, so that other users can login without starting the xserver. The above behavior can be tracked in {{path|/var/log/messages}} by including calls to "logger" in shell scripts.</small> | |||
{{path|/root/}} doesn't save any files, so it's necessary to edit files in {{path|/etc/}} and run <code>lbu_commit -d</code> 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 {{path|/etc}} see: [[Alpine_local_backup#Include_special_files.2Ffolders_to_the_apkovl]] | |||
also see: {{path|/etc/apk/protected_paths.d/lbu.list}}</small> | |||
create a file named {{path|/etc/startup.sh}}: | |||
{{cat|/etc/startup.sh|#!/bin/sh | |||
firefox-esr <nowiki>http://awebsite.com</nowiki> | |||
}} | |||
!!!NOTE: This is ash, not bash. By default, alpine ships with the ash shell. Bash is available in the repositories. You may also substitute firefox-esr for e.g. dwm. | |||
Make sure the file is executable. | |||
{{cmd|# chmod +x /etc/startup.sh}} | |||
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. Note that here we are 'moving' the xinitrc, not copying it. This is not a typo. The new file will have only one line in it (for the call to the {{path|/etc/startup.sh}} script). | ||
{{cmd|<nowiki># mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK | |||
# nano /etc/X11/xinit/xinitrc</nowiki>}} | |||
In this file | In this file, insert: | ||
{{cat|/etc/X11/xinit/xinitrc|... | |||
At the end of /etc/profile (leave the existing file) append | /etc/startup.sh}} | ||
At the end of {{path|/etc/profile}} (leave the existing file) append | |||
{{cat|/etc/profile|... | |||
< | startx}} | ||
# Set up a couple of | Remember to run <code>lbu_commit -d</code><BR> | ||
For autologin, alpine uses busybox, which has an alias to {{path|/sbin/getty}} as well as {{path|/bin/login}}. It's possible to navigate to {{path|/sbin/}} or {{path|/bin/}} and run <code>/sbin/getty -h</code> 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: | |||
{{cat|/etc/inittab|<nowiki># 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 136: | Line 156: | ||
tty1::respawn:/bin/login -f root | tty1::respawn:/bin/login -f root | ||
</ | </nowiki>}} | ||
It is probably a good idea to make a second user at this point. While this guide runs with root for simplicity, there is the potential for Xorg boot loops when trying to login as root. If you do accidentally lock yourself out (oops) just scp a new startup.sh file. | |||
===Disable Screensaver, and refresh webpage (optional)=== | ===Disable Screensaver, and refresh webpage (optional)=== | ||
As a kiosk, | As a kiosk, a Raspberry Pi needs to have the screensaver ([[Display Power Management Signaling DPMS]]) disabled.{{citation needed}} 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 147: | Line 168: | ||
EndSection}} | EndSection}} | ||
{{cmd|# apk add xdotool}} | {{cmd|# apk add {{pkg|xdotool|arch=a*}}}} | ||
<pre># crontab -u root -e | <pre># crontab -u root -e | ||
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5</pre> | * * * * * DISPLAY=:0 /usr/bin/xdotool key F5</pre> | ||
<small>Note | <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. | 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. If you use an RPI4, you'll have even more resources available. | ||
==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? | |||
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd). | |||
# 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). | |||
# Free software. No recurring costs (outside of optional maintenance). | |||
# 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 {{path|/etc/apk/repositories}} | |||
{{cmd|# apk add {{pkg|chromium|arch=a*}}}} | |||
In {{path|/etc/startup.sh}} add chromium instead of firefox: | |||
{{cat|/etc/startup.sh|<nowiki>... | |||
chromium-browser --home-page http://127.0.0.1/resource --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type | |||
</nowiki>}} | |||
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 | |||
{{cmd|# 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 <code>lbu_commit -d</code>, 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=== | |||
{{cmd|# apk add {{pkg|xset|arch=a*}} | |||
# xset q | |||
# xset s off | |||
}} | |||
===Hide Scrollbars of Browser=== | |||
This can be done with CSS. | |||
body { | |||
overflow: hidden; /* Hide scrollbars */ | |||
} | |||
==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) and Firefox required too many dependencies to run on an RPI3 with 512MB in {{path|/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 {{path|/boot/config.txt}} | |||
If your application doesn't require media ( | 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 would also fit into the limited space on the RPI. | 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=== | ||
Firefox can be called with -height and -width flags, e.g. | Firefox can be called with -height and -width flags, e.g. | ||
{{cmd|firefox -width 480 -height 640 example.org}} | |||
===Periodic Firefox Crashes due to Low Memory=== | ===Periodic Firefox Crashes on RPI3 due to Low Memory=== | ||
With the RPI3, I found firefox | 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 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. | ||
===Firefox-esr segmentation fault on x86 for 3.17=== | |||
In running firefox on an old intel atom netbook, I see firefox having a 'segmentation fault' when trying to run. However dwm works. This may be due to the netbook being x86 (and atom). Chromium is x86-64 only in pkgs.alpinelinux.org so something to keep in mind when allocating for a given setup. | |||
===How do I easily backup my diskless system?=== | |||
You should backup the apkvol which is located in /media/mmc (the location of the sd card). | |||
==Related Links== | ==Related Links== | ||
* [[dwm]] | * [[dwm]] | ||
* [[Raspberry Pi]] | * [[Raspberry Pi]] | ||
* [[Apache]] | |||
[[Category:Raspberry]] |
Latest revision as of 08:52, 15 November 2024
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. Later on I will use chromium which was used for a production sign and runs well, with a local website.
This guide (more or less, I may have made some other customizations) Production tested with 3.13.5 (on RPI4) and stable for over 3 years. I have also run this on 3.17 with x86 (not tested as long).
Note that this guide started out with an RPI3, has been used with x86, and currently runs with an RPI4, though the guide hasn't been fully updated yet. Hopefully, when time permits, and I have to remake the sign (or a new one) I will be able to edit this doc to represent either the RPI4 or RPI5 with alpine.
Overview
This guide uses the following:
- aarch64 img (though this guide is also tested to be roughly 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. (Note that for sake of this guide, it's assumed the RPI is a RAM only install. Although there is no requirement for it to be done this way).
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 firefox dependencies:
# apk add libx11-dev libxft-dev libxinerama-dev font-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. Some other video drivers may be xf86-video-intel, xf86-video-vesa... Refer to the Xorg logs if you get an error with the display drivers.
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.
What is happening here from my understanding is:
1) User logs in. /etc/profile is run (which includes a call to startx) 2) Startx references any relevant xinitrc (user folder or /etc/X11), which calls /etc/startup.sh 3) /etc/startup.sh runs any commands, such as dwm, firefox, or chromium.
If you want to manually startx upon login, then omit /etc/profile, or alternatively include only a custom profile for /root/.profile, so that other users can login without starting the xserver. The above behavior can be tracked in /var/log/messages by including calls to "logger" in shell scripts.
/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: 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:
Contents of /etc/startup.sh
!!!NOTE: This is ash, not bash. By default, alpine ships with the ash shell. Bash is available in the repositories. You may also substitute firefox-esr for e.g. dwm.
Make sure the file is executable.
# chmod +x /etc/startup.sh
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. Note that here we are 'moving' the xinitrc, not copying it. This is not a typo. The new file will have only one line in it (for the call to the /etc/startup.sh script).
# mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK # nano /etc/X11/xinit/xinitrc
In this file, insert:
Contents of /etc/X11/xinit/xinitrc
At the end of /etc/profile (leave the existing file) append
Contents of /etc/profile
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:
Contents of /etc/inittab
It is probably a good idea to make a second user at this point. While this guide runs with root for simplicity, there is the potential for Xorg boot loops when trying to login as root. If you do accidentally lock yourself out (oops) just scp a new startup.sh file.
Disable Screensaver, and refresh webpage (optional)
As a kiosk, a Raspberry Pi needs to have the screensaver (Display Power Management Signaling DPMS) disabled. [citation needed] 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
# 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. If you use an RPI4, you'll have even more resources available.
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?
- Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd).
- 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).
- Free software. No recurring costs (outside of optional maintenance).
- 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:
Contents of /etc/startup.sh
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 example.org
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.
Firefox-esr segmentation fault on x86 for 3.17
In running firefox on an old intel atom netbook, I see firefox having a 'segmentation fault' when trying to run. However dwm works. This may be due to the netbook being x86 (and atom). Chromium is x86-64 only in pkgs.alpinelinux.org so something to keep in mind when allocating for a given setup.
How do I easily backup my diskless system?
You should backup the apkvol which is located in /media/mmc (the location of the sd card).