<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.alpinelinux.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Alpineuser</id>
	<title>Alpine Linux - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.alpinelinux.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Alpineuser"/>
	<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/wiki/Special:Contributions/Alpineuser"/>
	<updated>2026-04-29T17:39:23Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.40.0</generator>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=31907</id>
		<title>Raspberry Pi 3 - Browser Client</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=31907"/>
		<updated>2025-12-31T05:51:47Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* Related Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;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.&lt;br /&gt;
&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
Note that this guide started out with an RPI3, has been used with x86, and currently runs with an RPI4, though the guide hasn&#039;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.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This guide uses the following:&lt;br /&gt;
* aarch64 img (though this guide is also tested to be roughly x86-compatible)&lt;br /&gt;
* Raspberry Pi3&lt;br /&gt;
* community repo.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
See https://pkgs.alpinelinux.org/packages?name=*firefox*&amp;amp;branch=v3.11&amp;amp;arch=aarch64&lt;br /&gt;
&lt;br /&gt;
Note: the aarch64 build is not compatible with all Raspberry Pi models. See [[Raspberry Pi]].&lt;br /&gt;
&lt;br /&gt;
==Steps==&lt;br /&gt;
===Base Install===&lt;br /&gt;
&lt;br /&gt;
These steps are duplicated from the [[Raspberry Pi]] page. (Note that for sake of this guide, it&#039;s assumed the RPI is a RAM only install. Although there is no requirement for it to be done this way).&lt;br /&gt;
&lt;br /&gt;
Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem. &lt;br /&gt;
e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Command (m for help): p&lt;br /&gt;
Disk /dev/sdb: 59.5 GiB, 63864569856 bytes, 124735488 sectors&lt;br /&gt;
Units: sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disklabel type: dos&lt;br /&gt;
Disk identifier: 0x00000000&lt;br /&gt;
&lt;br /&gt;
Device     Boot Start      End  Sectors Size Id Type&lt;br /&gt;
/dev/sdb1  *     2048 62916607 62914560  30G  b W95 FAT32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{cmd|# mkdosfs -F 32 /dev/sdX1}}&lt;br /&gt;
&lt;br /&gt;
untar onto mounted disk&lt;br /&gt;
&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# mount /dev/sdX1 /mnt/folder&lt;br /&gt;
# tar xvf archive.tar -C /mnt/folder/.&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other&lt;br /&gt;
config settings, do so in {{path|usercfg.txt}} now.&lt;br /&gt;
&lt;br /&gt;
Again, duplicating the [[Raspberry Pi]] page &lt;br /&gt;
&lt;br /&gt;
    Insert the SD card into the Raspberry Pi and turn it on&lt;br /&gt;
    Log in to Alpine as root. Leave the password empty.&lt;br /&gt;
    Type setup-alpine, hit enter.&lt;br /&gt;
    Once the installation is complete, commit the changes by typing lbu commit -d&lt;br /&gt;
&lt;br /&gt;
Things to keep in mind:&lt;br /&gt;
* 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. &lt;br /&gt;
* For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with &amp;quot;No disks available, try boot media /mmcblk0p1&amp;quot;. Select the default [n]. If you make a mistake during the install, you can always reimage and start over.&lt;br /&gt;
&lt;br /&gt;
Saving space: busybox instead of chronyd, dropbear instead of openssh&lt;br /&gt;
&lt;br /&gt;
After setup, make sure dropbear is installed&lt;br /&gt;
{{cmd|# apk add dropbear}}&lt;br /&gt;
&lt;br /&gt;
Start it:&lt;br /&gt;
{{cmd|# rc-service dropbear start}}&lt;br /&gt;
&lt;br /&gt;
Add it to the default runlevel:&lt;br /&gt;
{{cmd|# rc-update add dropbear}}&lt;br /&gt;
&lt;br /&gt;
If you need an accurate clock, enable software/ntp here. (this step is optional)&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# rc-update add swclock boot # enable the software clock &lt;br /&gt;
# rc-update del hwclock boot # disable the hardware clock&lt;br /&gt;
# setup-ntp&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
===Browser Client Install===&lt;br /&gt;
&lt;br /&gt;
Enable community repo ({{path|/etc/apk/repositories}}) (uncomment community)&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# nano /etc/apk/repositories&lt;br /&gt;
# apk update&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
install firefox dependencies:&lt;br /&gt;
{{cmd|# apk add libx11-dev libxft-dev libxinerama-dev font-dejavu}}&lt;br /&gt;
&amp;lt;small&amp;gt;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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the amount of RAM tmp fs available can be viewed while installing with: &amp;lt;code&amp;gt;watch df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
install firefox&lt;br /&gt;
{{cmd|# apk add firefox-esr}}&lt;br /&gt;
install X&lt;br /&gt;
{{cmd|# setup-xorg-base}}&lt;br /&gt;
The RPI also requires for X:&lt;br /&gt;
{{cmd|# apk add xf86-video-fbdev}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;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 &amp;quot;apk search libEGL.so&amp;quot; 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. This is pretty easy, as when X loaded for me, I could see in the logs that it was trying to look for a couple backends (intel, fbdev, vesa) and while installing one didn&#039;t work another did. However, you have to make sure to edit the xinitrc files otherwise, when it is working, it will run then close, if you didn&#039;t tell it start any program. the backends are viewable with apk search xf86-video of course.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, we have about 421MB of RAM used (if NTP was not set up).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
devtmpfs                 10.0M         0     10.0M   0% /dev&lt;br /&gt;
shm                     457.9M         0    457.9M   0% /dev/shm&lt;br /&gt;
/dev/mmcblk0p1           30.0G    259.4M     29.7G   1% /media/mmcblk0p1&lt;br /&gt;
tmpfs                   457.9M    420.0M     37.9M  92% /&lt;br /&gt;
tmpfs                    91.6M    188.0K     91.4M   0% /run&lt;br /&gt;
/dev/loop0               24.9M     24.9M         0 100% /.modloop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{cmd|# lbu_commit -d}}&lt;br /&gt;
&lt;br /&gt;
===AutoLogin, Startx automatically on Boot===&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to login as root, and run startx manually. Now we&#039;ll add configuration files to enable that without user interaction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;What is happening here from my understanding is:&lt;br /&gt;
 1) User logs in. {{path|/etc/profile}} is run (which includes a call to startx)&lt;br /&gt;
 2) Startx references any relevant xinitrc (user folder or {{path|/etc/X11}}), which calls {{path|/etc/startup.sh}}&lt;br /&gt;
 3) {{path|/etc/startup.sh}} runs any commands, such as dwm, firefox, or chromium.&lt;br /&gt;
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 &amp;quot;logger&amp;quot; in shell scripts.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{path|/root/}} doesn&#039;t save any files, so it&#039;s necessary to edit files in {{path|/etc/}} and run &amp;lt;code&amp;gt;lbu_commit -d&amp;lt;/code&amp;gt; after all changes. First let&#039;s add a file that we&#039;ll call firefox.&lt;br /&gt;
&amp;lt;small&amp;gt;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]]&lt;br /&gt;
also see: {{path|/etc/apk/protected_paths.d/lbu.list}}&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
create a file named {{path|/etc/startup.sh}}:&lt;br /&gt;
{{cat|/etc/startup.sh|#!/bin/sh&lt;br /&gt;
firefox-esr &amp;lt;nowiki&amp;gt;http://awebsite.com&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
!!!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.&lt;br /&gt;
&lt;br /&gt;
Make sure the file is executable.&lt;br /&gt;
{{cmd|# chmod +x /etc/startup.sh}}&lt;br /&gt;
&lt;br /&gt;
We have to edit xinitrc, and the profile configs. Normally, this would be done in the user&#039;s directory, but here we will use the globals for simplicity. Note that here we are &#039;moving&#039; 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).&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK&lt;br /&gt;
# nano /etc/X11/xinit/xinitrc&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
In this file, insert:&lt;br /&gt;
{{cat|/etc/X11/xinit/xinitrc|...&lt;br /&gt;
/etc/startup.sh}}&lt;br /&gt;
At the end of {{path|/etc/profile}} (leave the existing file) append&lt;br /&gt;
{{cat|/etc/profile|...&lt;br /&gt;
startx}}&lt;br /&gt;
Remember to run &amp;lt;code&amp;gt;lbu_commit -d&amp;lt;/code&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
For autologin, alpine uses busybox, which has an alias to {{path|/sbin/getty}} as well as {{path|/bin/login}}. It&#039;s possible to navigate to {{path|/sbin/}} or {{path|/bin/}} and run &amp;lt;code&amp;gt;/sbin/getty -h&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
{{cat|/etc/inittab|&amp;lt;nowiki&amp;gt;# Set up a couple of gettys&lt;br /&gt;
#tty1::respawn:/sbin/getty 38400 tty1&lt;br /&gt;
tty2::respawn:/sbin/getty 38400 tty2&lt;br /&gt;
tty3::respawn:/sbin/getty 38400 tty3&lt;br /&gt;
tty4::respawn:/sbin/getty 38400 tty4&lt;br /&gt;
tty5::respawn:/sbin/getty 38400 tty5&lt;br /&gt;
tty6::respawn:/sbin/getty 38400 tty6&lt;br /&gt;
&lt;br /&gt;
tty1::respawn:/bin/login -f root&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Disable Screensaver, and refresh webpage (optional)===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/X11/xorg.conf|&lt;br /&gt;
Section &amp;quot;Extensions&amp;quot;&lt;br /&gt;
    Option      &amp;quot;DPMS&amp;quot; &amp;quot;Disable&amp;quot;&lt;br /&gt;
EndSection}} &lt;br /&gt;
&lt;br /&gt;
{{cmd|# apk add {{pkg|xdotool|arch=a*}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# crontab -u root -e &lt;br /&gt;
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Note: xset is not an option here as it&#039;s not included by default. It can be installed from the repositories, if needed.&amp;lt;/small&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
That&#039;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&#039;ll have even more resources available.&lt;br /&gt;
&lt;br /&gt;
==Digital Signage==&lt;br /&gt;
It&#039;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? &lt;br /&gt;
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd). &lt;br /&gt;
# There is no requirement to use &#039;cloud&#039; services, or an internet connection. &lt;br /&gt;
# You have full control over the build and design (all kiosk build steps are documented &amp;amp; have a small learning curve, compared to some of the more complex projects mentioned above).&lt;br /&gt;
# Free software. No recurring costs (outside of optional maintenance). &lt;br /&gt;
# No ties to external infrastructure / frameworks. Full freedom.&lt;br /&gt;
&lt;br /&gt;
In this addition to the guide above, we&#039;ll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we&#039;ll also run a web server with PHP, which hosts the resources we want to display on the sign.&lt;br /&gt;
Make sure community apk is enabled in {{path|/etc/apk/repositories}}&lt;br /&gt;
{{cmd|# apk add {{pkg|chromium|arch=a*}}}}&lt;br /&gt;
In {{path|/etc/startup.sh}} add chromium instead of firefox:&lt;br /&gt;
{{cat|/etc/startup.sh|&amp;lt;nowiki&amp;gt;...&lt;br /&gt;
chromium-browser --home-page http://127.0.0.1/resource --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you deploy the device on a TV, and you&#039;re unsure what resolution it is, you can access the resolution from the terminal (not in X), by using &lt;br /&gt;
{{cmd|# xrandr -d :0}}&lt;br /&gt;
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&#039;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&#039;s config.h, But a WM is not required.&lt;br /&gt;
&lt;br /&gt;
Make sure to run &amp;lt;code&amp;gt;lbu_commit -d&amp;lt;/code&amp;gt;, in order to save any changes as needed in the apkvol on the SD or HDD storage.&lt;br /&gt;
&lt;br /&gt;
===Install Apache/PHP===&lt;br /&gt;
See [[Apache]].&lt;br /&gt;
&lt;br /&gt;
===Install xset to disable screensaver===&lt;br /&gt;
{{cmd|# apk add {{pkg|xset|arch=a*}}&lt;br /&gt;
&amp;amp;num; xset q&lt;br /&gt;
&amp;amp;num; xset s off&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Hide Scrollbars of Browser===&lt;br /&gt;
This can be done with CSS.&lt;br /&gt;
 body {&lt;br /&gt;
   overflow: hidden; /* Hide scrollbars */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
===Why was this setup used? Why not Awesome, or dwm?===&lt;br /&gt;
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&#039;t have this limitation. It should be possible to get more RAM via {{path|/boot/config.txt}}&lt;br /&gt;
&lt;br /&gt;
If your application doesn&#039;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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Width &amp;amp; height of firefox doesn&#039;t fit the monitor===&lt;br /&gt;
Firefox can be called with -height and -width flags, e.g. &lt;br /&gt;
{{cmd|firefox -width 480 -height 640 example.org}}&lt;br /&gt;
&lt;br /&gt;
===Periodic Firefox Crashes on RPI3 due to Low Memory===&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
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 &amp;gt;1GB ram which may eliminate the need for a nightly reboot.&lt;br /&gt;
&lt;br /&gt;
===Firefox-esr segmentation fault on x86 for 3.17===&lt;br /&gt;
In running firefox on an old intel atom netbook, I see firefox having a &#039;segmentation fault&#039; 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.&lt;br /&gt;
&lt;br /&gt;
===How do I easily backup my diskless system?===&lt;br /&gt;
You should backup the apkvol which is located in /media/mmc (the location of the sd card).&lt;br /&gt;
&lt;br /&gt;
===How do I backup firefox about:config edits?===&lt;br /&gt;
Use lbu include, and point to the &#039;full path&#039; of the file. Finally, set it with lbu_commit -d. You can review the page for [[lbu]], for more details. A trap, is that if you use a relative path, it will also include a relative (useless) path in /etc/apk/protected_paths.d/lbu.list&lt;br /&gt;
===Ntpd configuration===&lt;br /&gt;
The default ntp is busybox. You can run setup-ntp but that only chooses which daemon to run. If you want to change the default ntp command line options, you are looking for /etc/conf.d/. A mistake is to try to change the /etc/init.d/ntpd script. Both the script and the conf.d have pool.ntp.org set, but the conf.d file takes precedence.&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* [[dwm]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
* [https://lowendbox.com/blog/yes-you-can-run-18-static-sites-on-a-64mb-link-1-vps/ Low End Box - Yes, you can run 18 static sites on a 65mb link-1 vps] - A similar guide of removing programs to save on RAM use. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=File_management&amp;diff=30935</id>
		<title>File management</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=File_management&amp;diff=30935"/>
		<updated>2025-09-19T12:54:00Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* Automounting removable storage */ Fixed: Missing a comma. Removed: Repeated the word &amp;quot;such as&amp;quot; twice. Removed:Repetition of the word &amp;#039;storage&amp;#039; three times.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;File management and storage access in Alpine Linux [[Desktop environments and Window managers|desktop environments (DEs)]] involve various components. In Alpine Linux, [[#File managers|file managers]] require additional software packages to:-&lt;br /&gt;
&lt;br /&gt;
* Automatically mount removable media&lt;br /&gt;
* Browse storage across shared networks&lt;br /&gt;
* Display and access partitions using different [[Filesystems|filesystems]] with other installed operating systems&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
* Enable [[Polkit]] for privileged operations using a GUI&lt;br /&gt;
&lt;br /&gt;
== File managers ==&lt;br /&gt;
&lt;br /&gt;
[https://en.wikipedia.org/wiki/File_manager File managers] provide a user interface for file management i.e to manage files and folders. A partial list of file managers available in Alpine Linux is given below:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;width:100%; border:1px #0771a6 solid; background:#f9f9f9; text-align:left; border-collapse:collapse;&amp;quot;&lt;br /&gt;
|-style=&amp;quot;background:#333333; color:#ffffff; font-size: 1.2em; text-align:center;&amp;quot;&lt;br /&gt;
|width=&amp;quot;25%&amp;quot; | Tool &lt;br /&gt;
|width=&amp;quot;10%&amp;quot;| Graphical/TUI/CLI&lt;br /&gt;
|Brief Notes&lt;br /&gt;
|-&lt;br /&gt;
|{{pkg|caja}} ||Graphical||The file manager for the [[MATE|MATE desktop]]&lt;br /&gt;
|-&lt;br /&gt;
|{{pkg|clifm}} ||CLI||The shell-like command line terminal file manager&lt;br /&gt;
|-&lt;br /&gt;
|{{pkg|dolphin}} ||Graphical||File manager for [[KDE]] Plasma desktop &lt;br /&gt;
|-&lt;br /&gt;
|{{pkg|konqueror}} ||Graphical||[[KDE]] file manager and web browser&lt;br /&gt;
|-&lt;br /&gt;
|{{pkg|krusader}} ||GUI||Twin panel, Commander-style file manager&lt;br /&gt;
|-&lt;br /&gt;
|{{pkg|lf}} ||TUI||Terminal file manager written in Go with {{pkg|vim}}-style keybindings&lt;br /&gt;
|-&lt;br /&gt;
|{{pkg|lomiri-filemanager-app}} ||Graphical||Convergent file manager: for mobiles, desktops e.g. [https://gitlab.com/ubports/development/core/lomiri Lomiri] DE, [https://postmarketos.org postmarketOS]&lt;br /&gt;
|-&lt;br /&gt;
|{{pkg|mc}} ||TUI||Midnight Commander file manager/shell that emulates Norton Commander&lt;br /&gt;
|-&lt;br /&gt;
|{{pkg|nautilus}}||Graphical||[[Gnome|GNOME]] file manager also known as [https://apps.gnome.org/Nautilus/ &#039;GNOME Files&#039;]&lt;br /&gt;
|-&lt;br /&gt;
|{{Pkg|nemo}} ||Graphical||File manager for [https://github.com/linuxmint/cinnamon Cinnamon] desktop environment&lt;br /&gt;
|-&lt;br /&gt;
|{{pkg|nnn}} ||TUI||The unorthodox terminal file manager&lt;br /&gt;
|-&lt;br /&gt;
|{{pkg|pcmanfm}} ||Graphical||Extremely fast and lightweight file manager for [http://www.lxde.org LXDE]&lt;br /&gt;
|-&lt;br /&gt;
|{{pkg|pcmanfm-qt}} ||Graphical|| Qt port of {{pkg|pcmanfm}}&lt;br /&gt;
|-&lt;br /&gt;
|{{pkg|ranger}} ||TUI||{{Pkg|vim}}-inspired file manager for the console&lt;br /&gt;
|-&lt;br /&gt;
|{{pkg|spacefm}} ||GUI|| File manager (GTK2 version) from a legacy {{pkg|pcmanfm}} fork&lt;br /&gt;
|-&lt;br /&gt;
|{{pkg|thunar}} ||Graphical||File manager for [[Xfce]]&lt;br /&gt;
|-&lt;br /&gt;
|{{pkg|vifm}} ||TUI|| {{Pkg|vim}}-like file manager using {{Pkg|ncurses}} &lt;br /&gt;
|-&lt;br /&gt;
|{{pkg|xfe}} ||GUI|| Commander-like file manager for X&lt;br /&gt;
|-&lt;br /&gt;
|{{pkg|yazi}} ||TUI|| File manager written in Rust with asynchronous I/O, {{Pkg|vim}}-like input and bulk rename&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Automounting removable storage ==&lt;br /&gt;
&lt;br /&gt;
The tools [[#GVfs|GVfs]] and [[#Udisks|Udisks]] enable automatic mounting of removable storage such as USB drives, external HDDs, and network drives. To install them, issue the command: {{Cmd|# apk add gvfs-fuse udisks2}}&lt;br /&gt;
&lt;br /&gt;
To mount encrypted devices, ensure that appropriate packages such as {{pkg|device-mapper}} and {{pkg|lvm2}} are installed.&lt;br /&gt;
&lt;br /&gt;
=== Udisks === &lt;br /&gt;
&lt;br /&gt;
[https://www.freedesktop.org/wiki/Software/udisks/ udisks] makes managing disks, including removable drives such as USB, much easier by providing a {{ic|udisks}} daemon and {{ic|udisksctl}}, a cli-based tool. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;width:100%; border:1px #0771a6 solid; background:#f9f9f9; text-align:left; border-collapse:collapse;&amp;quot;&lt;br /&gt;
|-style=&amp;quot;background:#333333; color:#ffffff; font-size: 1.2em; text-align:center;&amp;quot;&lt;br /&gt;
|width=&amp;quot;50%&amp;quot; | Action&lt;br /&gt;
|Command&lt;br /&gt;
|-&lt;br /&gt;
|To see the mounted disks|| udisksctl status&lt;br /&gt;
|-&lt;br /&gt;
|To mount a disk {{Path|/dev/sdb1}}|| udisksctl mount -b /dev/sdb1&lt;br /&gt;
|-&lt;br /&gt;
|To unmount a disk, {{Path|/dev/sdb1}}|| udisksctl unmount -b /dev/sdb1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GVfs ===&lt;br /&gt;
&lt;br /&gt;
Many GUI file managers rely on [https://gitlab.gnome.org/GNOME/gvfs GVfs], a userspace virtual filesystem implementation. GVfs comes with a set of backends for SFTP, SMB, HTTP, DAV and many others. Depending on what devices you intend to mount, additional packages may be installed from the list below:-&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;width:100%; border:1px #0771a6 solid; background:#f9f9f9; text-align:left; border-collapse:collapse;&amp;quot;&lt;br /&gt;
|-style=&amp;quot;background:#333333; color:#ffffff; font-size: 1.2em; text-align:center;&amp;quot;&lt;br /&gt;
|width=&amp;quot;15%&amp;quot; | Package Name &lt;br /&gt;
|Brief Notes&lt;br /&gt;
|-&lt;br /&gt;
|    {{Pkg|ntfs-3g}}      || Stable, full-featured, read-write NTFS (driver)&lt;br /&gt;
|-&lt;br /&gt;
|    {{Pkg|gvfs-cdda}}    || CDDA support for gvfs&lt;br /&gt;
|-&lt;br /&gt;
|    {{Pkg|gvfs-afp}}     || AFP support for gvfs&lt;br /&gt;
|-&lt;br /&gt;
|    {{Pkg|gvfs-goa}}     || GNOME Online Accounts support for gvfs&lt;br /&gt;
|-&lt;br /&gt;
|    {{Pkg|gvfs-mtp}}     || MTP support for gvfs to mount android devices&lt;br /&gt;
|-&lt;br /&gt;
|    {{Pkg|gvfs-smb}}     || Windows fileshare support for gvfs&lt;br /&gt;
|-&lt;br /&gt;
|    {{Pkg|gvfs-lang}}    || Languages for the gvfs package&lt;br /&gt;
|-&lt;br /&gt;
|    {{Pkg|gvfs-afc}}     || Apple mobile devices support for gvfs&lt;br /&gt;
|-&lt;br /&gt;
|    {{Pkg|gvfs-nfs}}     || NFS support for gvfs&lt;br /&gt;
|-&lt;br /&gt;
|    {{Pkg|gvfs-dev}}     || Backends for the gio framework in GLib (development files) - Alpine Linux v3.19-v3.20 only.{{Pill||v3.19.x-v3.20.x|orange|goldenrod}} &lt;br /&gt;
|-&lt;br /&gt;
|    {{Pkg|gvfs-archive}} || Archiving support for gvfs&lt;br /&gt;
|-&lt;br /&gt;
|    {{Pkg|gvfs-dav}}     || WebDAV support for gvfs&lt;br /&gt;
|-&lt;br /&gt;
|    {{Pkg|gvfs-fuse}}    || FUSE support for gvfs to mount external storage devices&lt;br /&gt;
|-&lt;br /&gt;
|    {{Pkg|gvfs-gphoto2}} || {{Pkg|gphoto2}} support for gvfs&lt;br /&gt;
|-&lt;br /&gt;
|    {{Pkg|gvfs-avahi}}   || DNS-SD support for gvfs&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To list descriptions of all &#039;&#039;gvfs-&#039;&#039; packages:{{cmd|$ apk info -d gvfs-*}}&lt;br /&gt;
&lt;br /&gt;
In addition to the packages above, {{ic|fuse}} service from {{pkg|fuse-openrc}} package is required for automounting a number of filesystems. To install it:{{Cmd|# apk add fuse-openrc}}&lt;br /&gt;
&lt;br /&gt;
Start the fuse OpenRC service as follows:{{Cmd|# rc-service fuse start}}&lt;br /&gt;
&lt;br /&gt;
If the desktop sessions are already in progress, they need to be restarted for the changes to take effect i.e. log out and log in again.&lt;br /&gt;
&lt;br /&gt;
The fuse service can be added to start up automatically at boot time:{{Cmd|# rc-update add fuse}}&lt;br /&gt;
&lt;br /&gt;
When [[Polkit#Using polkit with seatd|polkit is used with seatd]], additional [[Polkit#Example1|configuration]] is required for automounting to work.&lt;br /&gt;
&lt;br /&gt;
=== Network browsing ===&lt;br /&gt;
&lt;br /&gt;
For browsing of network shares that works seamlessly with file associations, install the {{Pkg|gvfs*}} packages for the required network protocols. For example, to browse in a SMB/cifs windows network:{{Cmd|# apk add gvfs-smb}}&lt;br /&gt;
&lt;br /&gt;
== Enabling privilege escalation GUI ==&lt;br /&gt;
&lt;br /&gt;
When using file managers, to enable the privilege escalation GUI for an [[Setting_up_a_new_user#Admin_user|admin user]], implement the following:-&lt;br /&gt;
* Install an appropriate [[Polkit#Authentication agents|polkit authentication agent]] for the desktop environment &lt;br /&gt;
* Enable [[Polkit#Using polkit with elogind|polkit to be used with elogind]]&lt;br /&gt;
* Authentication agent is autostarted along with the desktop environment&lt;br /&gt;
* A [[Display manager|display manager]] is used to start the desktop session (recommended)&lt;br /&gt;
&lt;br /&gt;
If the steps above are completed, whenever {{ic|admin://}} is typed in the address bar of the [[File_management#File_managers|file manager]], a password dialogue will appear. &lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Error due to missing polkit ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Error mounting /dev/sda1: GDBus.Error:org.freedesktop.UDisks2.Error.NotAuthorized: Not authorized to perform operation (polkit authority not available and caller is not uid 0)&#039;&#039;  &lt;br /&gt;
&lt;br /&gt;
If [[Polkit|polkit]] is not available, then the error above will occur.  In this case, either install and enable [[Polkit|polkit]], or using [[Setting up a new user#doas|doas]] is recommended.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Polkit]]&lt;br /&gt;
* [https://wiki.archlinux.org/title/File_manager_functionality Archwiki - File manager functionality]&lt;br /&gt;
* [[Default applications|Change default application]] associated with a filetype&lt;br /&gt;
&lt;br /&gt;
[[Category:Storage]]&lt;br /&gt;
[[Category:Desktop]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Mdevd&amp;diff=30881</id>
		<title>Mdevd</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Mdevd&amp;diff=30881"/>
		<updated>2025-09-07T20:25:43Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* Remove */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:mdevd}}&lt;br /&gt;
[https://skarnet.org/software/mdevd/ mdevd] is a [[Device_Manager|device manager]] that is compatible with [[mdev]].&lt;br /&gt;
For configuration and other things please look at the [[mdev|mdev article]].&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
The easy way to setup mdevd is throught the [[#Setup_Script|setup script]]. For custom installation see the [[#Manually|manually section]]. Note that a manual installation is only recommended for advanced users.&lt;br /&gt;
&lt;br /&gt;
=== Setup Script ===&lt;br /&gt;
&lt;br /&gt;
The {{pkg|alpine-conf}} package privides [https://git.alpinelinux.org/alpine-conf/tree/setup-devd.in setup-devd] to easily install and setup device managers.&lt;br /&gt;
&lt;br /&gt;
Install {{pkg|alpine-conf}} if it is not already installed.&lt;br /&gt;
{{cmd|# apk add {{pkg|alpine-conf}}}}&lt;br /&gt;
Setup mdevd.&lt;br /&gt;
{{cmd|# setup-devd mdevd}}&lt;br /&gt;
&lt;br /&gt;
=== Manually ===&lt;br /&gt;
&lt;br /&gt;
You first need to install the mdevd package.&lt;br /&gt;
{{cmd|# apk add {{pkg|mdevd}}}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you already have a device manager installed you need to stop it before you start mdevd.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then enable the services.&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# rc-update add mdevd sysinit&lt;br /&gt;
# rc-update add mdevd-init sysinit&lt;br /&gt;
# rc-update add hwdrivers sysinit&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
If you are not running in a chroot you will also want to start mdevd.&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# rc-service mdevd start&lt;br /&gt;
# rc-service hwdrivers start&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
If {{path|/dev}} hasn&#039;t been initialized by another device manager you need to do that manually.&lt;br /&gt;
{{cmd|# rc-service mdevd-init start}}&lt;br /&gt;
&lt;br /&gt;
== Remove ==&lt;br /&gt;
{{warning|Use the [[#Setup script|Setup script]] to change the device manager. Removing the device manager without first setting up an alternative may cause unexpected issues.}}&lt;br /&gt;
&lt;br /&gt;
To remove mdevd you need to stop it first. This step can be skipped if you are running in a chroot.&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# rc-service hwdrivers stop&lt;br /&gt;
# rc-service mdevd stop&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Then disable the services.&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# rc-update delete hwdrivers sysinit&lt;br /&gt;
# rc-update delete mdevd-init sysinit&lt;br /&gt;
# rc-update delete mdevd sysinit&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
You might also want to uninstall the mdevd package since they are not used anymore.&lt;br /&gt;
{{cmd|# apk del {{pkg|mdevd}}}}&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[mdev]]&lt;br /&gt;
* [[:Category:Device_Manager|Device Managers]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Device_Manager]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Mdevd&amp;diff=30880</id>
		<title>Mdevd</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Mdevd&amp;diff=30880"/>
		<updated>2025-09-07T20:25:28Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* Remove */  Making it easier to read.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:mdevd}}&lt;br /&gt;
[https://skarnet.org/software/mdevd/ mdevd] is a [[Device_Manager|device manager]] that is compatible with [[mdev]].&lt;br /&gt;
For configuration and other things please look at the [[mdev|mdev article]].&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
The easy way to setup mdevd is throught the [[#Setup_Script|setup script]]. For custom installation see the [[#Manually|manually section]]. Note that a manual installation is only recommended for advanced users.&lt;br /&gt;
&lt;br /&gt;
=== Setup Script ===&lt;br /&gt;
&lt;br /&gt;
The {{pkg|alpine-conf}} package privides [https://git.alpinelinux.org/alpine-conf/tree/setup-devd.in setup-devd] to easily install and setup device managers.&lt;br /&gt;
&lt;br /&gt;
Install {{pkg|alpine-conf}} if it is not already installed.&lt;br /&gt;
{{cmd|# apk add {{pkg|alpine-conf}}}}&lt;br /&gt;
Setup mdevd.&lt;br /&gt;
{{cmd|# setup-devd mdevd}}&lt;br /&gt;
&lt;br /&gt;
=== Manually ===&lt;br /&gt;
&lt;br /&gt;
You first need to install the mdevd package.&lt;br /&gt;
{{cmd|# apk add {{pkg|mdevd}}}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you already have a device manager installed you need to stop it before you start mdevd.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then enable the services.&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# rc-update add mdevd sysinit&lt;br /&gt;
# rc-update add mdevd-init sysinit&lt;br /&gt;
# rc-update add hwdrivers sysinit&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
If you are not running in a chroot you will also want to start mdevd.&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# rc-service mdevd start&lt;br /&gt;
# rc-service hwdrivers start&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
If {{path|/dev}} hasn&#039;t been initialized by another device manager you need to do that manually.&lt;br /&gt;
{{cmd|# rc-service mdevd-init start}}&lt;br /&gt;
&lt;br /&gt;
== Remove ==&lt;br /&gt;
{{warning|Use [[#Setup script|Setup script]] to change the device manager. Removing the device manager without first setting up an alternative may cause unexpected issues.}}&lt;br /&gt;
&lt;br /&gt;
To remove mdevd you need to stop it first. This step can be skipped if you are running in a chroot.&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# rc-service hwdrivers stop&lt;br /&gt;
# rc-service mdevd stop&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Then disable the services.&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# rc-update delete hwdrivers sysinit&lt;br /&gt;
# rc-update delete mdevd-init sysinit&lt;br /&gt;
# rc-update delete mdevd sysinit&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
You might also want to uninstall the mdevd package since they are not used anymore.&lt;br /&gt;
{{cmd|# apk del {{pkg|mdevd}}}}&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[mdev]]&lt;br /&gt;
* [[:Category:Device_Manager|Device Managers]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Device_Manager]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=30572</id>
		<title>Raspberry Pi 3 - Browser Client</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=30572"/>
		<updated>2025-07-23T09:37:09Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* How do I backup firefox about:config edits? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;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.&lt;br /&gt;
&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
Note that this guide started out with an RPI3, has been used with x86, and currently runs with an RPI4, though the guide hasn&#039;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.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This guide uses the following:&lt;br /&gt;
* aarch64 img (though this guide is also tested to be roughly x86-compatible)&lt;br /&gt;
* Raspberry Pi3&lt;br /&gt;
* community repo.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
See https://pkgs.alpinelinux.org/packages?name=*firefox*&amp;amp;branch=v3.11&amp;amp;arch=aarch64&lt;br /&gt;
&lt;br /&gt;
Note: the aarch64 build is not compatible with all Raspberry Pi models. See [[Raspberry Pi]].&lt;br /&gt;
&lt;br /&gt;
==Steps==&lt;br /&gt;
===Base Install===&lt;br /&gt;
&lt;br /&gt;
These steps are duplicated from the [[Raspberry Pi]] page. (Note that for sake of this guide, it&#039;s assumed the RPI is a RAM only install. Although there is no requirement for it to be done this way).&lt;br /&gt;
&lt;br /&gt;
Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem. &lt;br /&gt;
e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Command (m for help): p&lt;br /&gt;
Disk /dev/sdb: 59.5 GiB, 63864569856 bytes, 124735488 sectors&lt;br /&gt;
Units: sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disklabel type: dos&lt;br /&gt;
Disk identifier: 0x00000000&lt;br /&gt;
&lt;br /&gt;
Device     Boot Start      End  Sectors Size Id Type&lt;br /&gt;
/dev/sdb1  *     2048 62916607 62914560  30G  b W95 FAT32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{cmd|# mkdosfs -F 32 /dev/sdX1}}&lt;br /&gt;
&lt;br /&gt;
untar onto mounted disk&lt;br /&gt;
&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# mount /dev/sdX1 /mnt/folder&lt;br /&gt;
# tar xvf archive.tar -C /mnt/folder/.&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other&lt;br /&gt;
config settings, do so in {{path|usercfg.txt}} now.&lt;br /&gt;
&lt;br /&gt;
Again, duplicating the [[Raspberry Pi]] page &lt;br /&gt;
&lt;br /&gt;
    Insert the SD card into the Raspberry Pi and turn it on&lt;br /&gt;
    Log in to Alpine as root. Leave the password empty.&lt;br /&gt;
    Type setup-alpine, hit enter.&lt;br /&gt;
    Once the installation is complete, commit the changes by typing lbu commit -d&lt;br /&gt;
&lt;br /&gt;
Things to keep in mind:&lt;br /&gt;
* 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. &lt;br /&gt;
* For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with &amp;quot;No disks available, try boot media /mmcblk0p1&amp;quot;. Select the default [n]. If you make a mistake during the install, you can always reimage and start over.&lt;br /&gt;
&lt;br /&gt;
Saving space: busybox instead of chronyd, dropbear instead of openssh&lt;br /&gt;
&lt;br /&gt;
After setup, make sure dropbear is installed&lt;br /&gt;
{{cmd|# apk add dropbear}}&lt;br /&gt;
&lt;br /&gt;
Start it:&lt;br /&gt;
{{cmd|# rc-service dropbear start}}&lt;br /&gt;
&lt;br /&gt;
Add it to the default runlevel:&lt;br /&gt;
{{cmd|# rc-update add dropbear}}&lt;br /&gt;
&lt;br /&gt;
If you need an accurate clock, enable software/ntp here. (this step is optional)&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# rc-update add swclock boot # enable the software clock &lt;br /&gt;
# rc-update del hwclock boot # disable the hardware clock&lt;br /&gt;
# setup-ntp&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
===Browser Client Install===&lt;br /&gt;
&lt;br /&gt;
Enable community repo ({{path|/etc/apk/repositories}}) (uncomment community)&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# nano /etc/apk/repositories&lt;br /&gt;
# apk update&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
install firefox dependencies:&lt;br /&gt;
{{cmd|# apk add libx11-dev libxft-dev libxinerama-dev font-dejavu}}&lt;br /&gt;
&amp;lt;small&amp;gt;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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the amount of RAM tmp fs available can be viewed while installing with: &amp;lt;code&amp;gt;watch df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
install firefox&lt;br /&gt;
{{cmd|# apk add firefox-esr}}&lt;br /&gt;
install X&lt;br /&gt;
{{cmd|# setup-xorg-base}}&lt;br /&gt;
The RPI also requires for X:&lt;br /&gt;
{{cmd|# apk add xf86-video-fbdev}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;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 &amp;quot;apk search libEGL.so&amp;quot; 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. This is pretty easy, as when X loaded for me, I could see in the logs that it was trying to look for a couple backends (intel, fbdev, vesa) and while installing one didn&#039;t work another did. However, you have to make sure to edit the xinitrc files otherwise, when it is working, it will run then close, if you didn&#039;t tell it start any program. the backends are viewable with apk search xf86-video of course.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, we have about 421MB of RAM used (if NTP was not set up).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
devtmpfs                 10.0M         0     10.0M   0% /dev&lt;br /&gt;
shm                     457.9M         0    457.9M   0% /dev/shm&lt;br /&gt;
/dev/mmcblk0p1           30.0G    259.4M     29.7G   1% /media/mmcblk0p1&lt;br /&gt;
tmpfs                   457.9M    420.0M     37.9M  92% /&lt;br /&gt;
tmpfs                    91.6M    188.0K     91.4M   0% /run&lt;br /&gt;
/dev/loop0               24.9M     24.9M         0 100% /.modloop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{cmd|# lbu_commit -d}}&lt;br /&gt;
&lt;br /&gt;
===AutoLogin, Startx automatically on Boot===&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to login as root, and run startx manually. Now we&#039;ll add configuration files to enable that without user interaction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;What is happening here from my understanding is:&lt;br /&gt;
 1) User logs in. {{path|/etc/profile}} is run (which includes a call to startx)&lt;br /&gt;
 2) Startx references any relevant xinitrc (user folder or {{path|/etc/X11}}), which calls {{path|/etc/startup.sh}}&lt;br /&gt;
 3) {{path|/etc/startup.sh}} runs any commands, such as dwm, firefox, or chromium.&lt;br /&gt;
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 &amp;quot;logger&amp;quot; in shell scripts.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{path|/root/}} doesn&#039;t save any files, so it&#039;s necessary to edit files in {{path|/etc/}} and run &amp;lt;code&amp;gt;lbu_commit -d&amp;lt;/code&amp;gt; after all changes. First let&#039;s add a file that we&#039;ll call firefox.&lt;br /&gt;
&amp;lt;small&amp;gt;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]]&lt;br /&gt;
also see: {{path|/etc/apk/protected_paths.d/lbu.list}}&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
create a file named {{path|/etc/startup.sh}}:&lt;br /&gt;
{{cat|/etc/startup.sh|#!/bin/sh&lt;br /&gt;
firefox-esr &amp;lt;nowiki&amp;gt;http://awebsite.com&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
!!!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.&lt;br /&gt;
&lt;br /&gt;
Make sure the file is executable.&lt;br /&gt;
{{cmd|# chmod +x /etc/startup.sh}}&lt;br /&gt;
&lt;br /&gt;
We have to edit xinitrc, and the profile configs. Normally, this would be done in the user&#039;s directory, but here we will use the globals for simplicity. Note that here we are &#039;moving&#039; 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).&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK&lt;br /&gt;
# nano /etc/X11/xinit/xinitrc&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
In this file, insert:&lt;br /&gt;
{{cat|/etc/X11/xinit/xinitrc|...&lt;br /&gt;
/etc/startup.sh}}&lt;br /&gt;
At the end of {{path|/etc/profile}} (leave the existing file) append&lt;br /&gt;
{{cat|/etc/profile|...&lt;br /&gt;
startx}}&lt;br /&gt;
Remember to run &amp;lt;code&amp;gt;lbu_commit -d&amp;lt;/code&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
For autologin, alpine uses busybox, which has an alias to {{path|/sbin/getty}} as well as {{path|/bin/login}}. It&#039;s possible to navigate to {{path|/sbin/}} or {{path|/bin/}} and run &amp;lt;code&amp;gt;/sbin/getty -h&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
{{cat|/etc/inittab|&amp;lt;nowiki&amp;gt;# Set up a couple of gettys&lt;br /&gt;
#tty1::respawn:/sbin/getty 38400 tty1&lt;br /&gt;
tty2::respawn:/sbin/getty 38400 tty2&lt;br /&gt;
tty3::respawn:/sbin/getty 38400 tty3&lt;br /&gt;
tty4::respawn:/sbin/getty 38400 tty4&lt;br /&gt;
tty5::respawn:/sbin/getty 38400 tty5&lt;br /&gt;
tty6::respawn:/sbin/getty 38400 tty6&lt;br /&gt;
&lt;br /&gt;
tty1::respawn:/bin/login -f root&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Disable Screensaver, and refresh webpage (optional)===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/X11/xorg.conf|&lt;br /&gt;
Section &amp;quot;Extensions&amp;quot;&lt;br /&gt;
    Option      &amp;quot;DPMS&amp;quot; &amp;quot;Disable&amp;quot;&lt;br /&gt;
EndSection}} &lt;br /&gt;
&lt;br /&gt;
{{cmd|# apk add {{pkg|xdotool|arch=a*}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# crontab -u root -e &lt;br /&gt;
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Note: xset is not an option here as it&#039;s not included by default. It can be installed from the repositories, if needed.&amp;lt;/small&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
That&#039;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&#039;ll have even more resources available.&lt;br /&gt;
&lt;br /&gt;
==Digital Signage==&lt;br /&gt;
It&#039;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? &lt;br /&gt;
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd). &lt;br /&gt;
# There is no requirement to use &#039;cloud&#039; services, or an internet connection. &lt;br /&gt;
# You have full control over the build and design (all kiosk build steps are documented &amp;amp; have a small learning curve, compared to some of the more complex projects mentioned above).&lt;br /&gt;
# Free software. No recurring costs (outside of optional maintenance). &lt;br /&gt;
# No ties to external infrastructure / frameworks. Full freedom.&lt;br /&gt;
&lt;br /&gt;
In this addition to the guide above, we&#039;ll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we&#039;ll also run a web server with PHP, which hosts the resources we want to display on the sign.&lt;br /&gt;
Make sure community apk is enabled in {{path|/etc/apk/repositories}}&lt;br /&gt;
{{cmd|# apk add {{pkg|chromium|arch=a*}}}}&lt;br /&gt;
In {{path|/etc/startup.sh}} add chromium instead of firefox:&lt;br /&gt;
{{cat|/etc/startup.sh|&amp;lt;nowiki&amp;gt;...&lt;br /&gt;
chromium-browser --home-page http://127.0.0.1/resource --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you deploy the device on a TV, and you&#039;re unsure what resolution it is, you can access the resolution from the terminal (not in X), by using &lt;br /&gt;
{{cmd|# xrandr -d :0}}&lt;br /&gt;
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&#039;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&#039;s config.h, But a WM is not required.&lt;br /&gt;
&lt;br /&gt;
Make sure to run &amp;lt;code&amp;gt;lbu_commit -d&amp;lt;/code&amp;gt;, in order to save any changes as needed in the apkvol on the SD or HDD storage.&lt;br /&gt;
&lt;br /&gt;
===Install Apache/PHP===&lt;br /&gt;
See [[Apache]].&lt;br /&gt;
&lt;br /&gt;
===Install xset to disable screensaver===&lt;br /&gt;
{{cmd|# apk add {{pkg|xset|arch=a*}}&lt;br /&gt;
&amp;amp;num; xset q&lt;br /&gt;
&amp;amp;num; xset s off&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Hide Scrollbars of Browser===&lt;br /&gt;
This can be done with CSS.&lt;br /&gt;
 body {&lt;br /&gt;
   overflow: hidden; /* Hide scrollbars */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
===Why was this setup used? Why not Awesome, or dwm?===&lt;br /&gt;
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&#039;t have this limitation. It should be possible to get more RAM via {{path|/boot/config.txt}}&lt;br /&gt;
&lt;br /&gt;
If your application doesn&#039;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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Width &amp;amp; height of firefox doesn&#039;t fit the monitor===&lt;br /&gt;
Firefox can be called with -height and -width flags, e.g. &lt;br /&gt;
{{cmd|firefox -width 480 -height 640 example.org}}&lt;br /&gt;
&lt;br /&gt;
===Periodic Firefox Crashes on RPI3 due to Low Memory===&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
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 &amp;gt;1GB ram which may eliminate the need for a nightly reboot.&lt;br /&gt;
&lt;br /&gt;
===Firefox-esr segmentation fault on x86 for 3.17===&lt;br /&gt;
In running firefox on an old intel atom netbook, I see firefox having a &#039;segmentation fault&#039; 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.&lt;br /&gt;
&lt;br /&gt;
===How do I easily backup my diskless system?===&lt;br /&gt;
You should backup the apkvol which is located in /media/mmc (the location of the sd card).&lt;br /&gt;
&lt;br /&gt;
===How do I backup firefox about:config edits?===&lt;br /&gt;
Use lbu include, and point to the &#039;full path&#039; of the file. Finally, set it with lbu_commit -d. You can review the page for [[lbu]], for more details. A trap, is that if you use a relative path, it will also include a relative (useless) path in /etc/apk/protected_paths.d/lbu.list&lt;br /&gt;
===Ntpd configuration===&lt;br /&gt;
The default ntp is busybox. You can run setup-ntp but that only chooses which daemon to run. If you want to change the default ntp command line options, you are looking for /etc/conf.d/. A mistake is to try to change the /etc/init.d/ntpd script. Both the script and the conf.d have pool.ntp.org set, but the conf.d file takes precedence.&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* [[dwm]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=30372</id>
		<title>Raspberry Pi 3 - Browser Client</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=30372"/>
		<updated>2025-07-08T14:24:11Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* Browser Client Install */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;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.&lt;br /&gt;
&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
Note that this guide started out with an RPI3, has been used with x86, and currently runs with an RPI4, though the guide hasn&#039;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.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This guide uses the following:&lt;br /&gt;
* aarch64 img (though this guide is also tested to be roughly x86-compatible)&lt;br /&gt;
* Raspberry Pi3&lt;br /&gt;
* community repo.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
See https://pkgs.alpinelinux.org/packages?name=*firefox*&amp;amp;branch=v3.11&amp;amp;arch=aarch64&lt;br /&gt;
&lt;br /&gt;
Note: the aarch64 build is not compatible with all Raspberry Pi models. See [[Raspberry Pi]].&lt;br /&gt;
&lt;br /&gt;
==Steps==&lt;br /&gt;
===Base Install===&lt;br /&gt;
&lt;br /&gt;
These steps are duplicated from the [[Raspberry Pi]] page. (Note that for sake of this guide, it&#039;s assumed the RPI is a RAM only install. Although there is no requirement for it to be done this way).&lt;br /&gt;
&lt;br /&gt;
Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem. &lt;br /&gt;
e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Command (m for help): p&lt;br /&gt;
Disk /dev/sdb: 59.5 GiB, 63864569856 bytes, 124735488 sectors&lt;br /&gt;
Units: sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disklabel type: dos&lt;br /&gt;
Disk identifier: 0x00000000&lt;br /&gt;
&lt;br /&gt;
Device     Boot Start      End  Sectors Size Id Type&lt;br /&gt;
/dev/sdb1  *     2048 62916607 62914560  30G  b W95 FAT32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{cmd|# mkdosfs -F 32 /dev/sdX1}}&lt;br /&gt;
&lt;br /&gt;
untar onto mounted disk&lt;br /&gt;
&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# mount /dev/sdX1 /mnt/folder&lt;br /&gt;
# tar xvf archive.tar -C /mnt/folder/.&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other&lt;br /&gt;
config settings, do so in {{path|usercfg.txt}} now.&lt;br /&gt;
&lt;br /&gt;
Again, duplicating the [[Raspberry Pi]] page &lt;br /&gt;
&lt;br /&gt;
    Insert the SD card into the Raspberry Pi and turn it on&lt;br /&gt;
    Log in to Alpine as root. Leave the password empty.&lt;br /&gt;
    Type setup-alpine, hit enter.&lt;br /&gt;
    Once the installation is complete, commit the changes by typing lbu commit -d&lt;br /&gt;
&lt;br /&gt;
Things to keep in mind:&lt;br /&gt;
* 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. &lt;br /&gt;
* For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with &amp;quot;No disks available, try boot media /mmcblk0p1&amp;quot;. Select the default [n]. If you make a mistake during the install, you can always reimage and start over.&lt;br /&gt;
&lt;br /&gt;
Saving space: busybox instead of chronyd, dropbear instead of openssh&lt;br /&gt;
&lt;br /&gt;
After setup, make sure dropbear is installed&lt;br /&gt;
{{cmd|# apk add dropbear}}&lt;br /&gt;
&lt;br /&gt;
Start it:&lt;br /&gt;
{{cmd|# rc-service dropbear start}}&lt;br /&gt;
&lt;br /&gt;
Add it to the default runlevel:&lt;br /&gt;
{{cmd|# rc-update add dropbear}}&lt;br /&gt;
&lt;br /&gt;
If you need an accurate clock, enable software/ntp here. (this step is optional)&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# rc-update add swclock boot # enable the software clock &lt;br /&gt;
# rc-update del hwclock boot # disable the hardware clock&lt;br /&gt;
# setup-ntp&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
===Browser Client Install===&lt;br /&gt;
&lt;br /&gt;
Enable community repo ({{path|/etc/apk/repositories}}) (uncomment community)&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# nano /etc/apk/repositories&lt;br /&gt;
# apk update&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
install firefox dependencies:&lt;br /&gt;
{{cmd|# apk add libx11-dev libxft-dev libxinerama-dev font-dejavu}}&lt;br /&gt;
&amp;lt;small&amp;gt;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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the amount of RAM tmp fs available can be viewed while installing with: &amp;lt;code&amp;gt;watch df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
install firefox&lt;br /&gt;
{{cmd|# apk add firefox-esr}}&lt;br /&gt;
install X&lt;br /&gt;
{{cmd|# setup-xorg-base}}&lt;br /&gt;
The RPI also requires for X:&lt;br /&gt;
{{cmd|# apk add xf86-video-fbdev}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;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 &amp;quot;apk search libEGL.so&amp;quot; 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. This is pretty easy, as when X loaded for me, I could see in the logs that it was trying to look for a couple backends (intel, fbdev, vesa) and while installing one didn&#039;t work another did. However, you have to make sure to edit the xinitrc files otherwise, when it is working, it will run then close, if you didn&#039;t tell it start any program. the backends are viewable with apk search xf86-video of course.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, we have about 421MB of RAM used (if NTP was not set up).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
devtmpfs                 10.0M         0     10.0M   0% /dev&lt;br /&gt;
shm                     457.9M         0    457.9M   0% /dev/shm&lt;br /&gt;
/dev/mmcblk0p1           30.0G    259.4M     29.7G   1% /media/mmcblk0p1&lt;br /&gt;
tmpfs                   457.9M    420.0M     37.9M  92% /&lt;br /&gt;
tmpfs                    91.6M    188.0K     91.4M   0% /run&lt;br /&gt;
/dev/loop0               24.9M     24.9M         0 100% /.modloop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{cmd|# lbu_commit -d}}&lt;br /&gt;
&lt;br /&gt;
===AutoLogin, Startx automatically on Boot===&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to login as root, and run startx manually. Now we&#039;ll add configuration files to enable that without user interaction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;What is happening here from my understanding is:&lt;br /&gt;
 1) User logs in. {{path|/etc/profile}} is run (which includes a call to startx)&lt;br /&gt;
 2) Startx references any relevant xinitrc (user folder or {{path|/etc/X11}}), which calls {{path|/etc/startup.sh}}&lt;br /&gt;
 3) {{path|/etc/startup.sh}} runs any commands, such as dwm, firefox, or chromium.&lt;br /&gt;
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 &amp;quot;logger&amp;quot; in shell scripts.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{path|/root/}} doesn&#039;t save any files, so it&#039;s necessary to edit files in {{path|/etc/}} and run &amp;lt;code&amp;gt;lbu_commit -d&amp;lt;/code&amp;gt; after all changes. First let&#039;s add a file that we&#039;ll call firefox.&lt;br /&gt;
&amp;lt;small&amp;gt;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]]&lt;br /&gt;
also see: {{path|/etc/apk/protected_paths.d/lbu.list}}&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
create a file named {{path|/etc/startup.sh}}:&lt;br /&gt;
{{cat|/etc/startup.sh|#!/bin/sh&lt;br /&gt;
firefox-esr &amp;lt;nowiki&amp;gt;http://awebsite.com&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
!!!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.&lt;br /&gt;
&lt;br /&gt;
Make sure the file is executable.&lt;br /&gt;
{{cmd|# chmod +x /etc/startup.sh}}&lt;br /&gt;
&lt;br /&gt;
We have to edit xinitrc, and the profile configs. Normally, this would be done in the user&#039;s directory, but here we will use the globals for simplicity. Note that here we are &#039;moving&#039; 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).&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK&lt;br /&gt;
# nano /etc/X11/xinit/xinitrc&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
In this file, insert:&lt;br /&gt;
{{cat|/etc/X11/xinit/xinitrc|...&lt;br /&gt;
/etc/startup.sh}}&lt;br /&gt;
At the end of {{path|/etc/profile}} (leave the existing file) append&lt;br /&gt;
{{cat|/etc/profile|...&lt;br /&gt;
startx}}&lt;br /&gt;
Remember to run &amp;lt;code&amp;gt;lbu_commit -d&amp;lt;/code&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
For autologin, alpine uses busybox, which has an alias to {{path|/sbin/getty}} as well as {{path|/bin/login}}. It&#039;s possible to navigate to {{path|/sbin/}} or {{path|/bin/}} and run &amp;lt;code&amp;gt;/sbin/getty -h&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
{{cat|/etc/inittab|&amp;lt;nowiki&amp;gt;# Set up a couple of gettys&lt;br /&gt;
#tty1::respawn:/sbin/getty 38400 tty1&lt;br /&gt;
tty2::respawn:/sbin/getty 38400 tty2&lt;br /&gt;
tty3::respawn:/sbin/getty 38400 tty3&lt;br /&gt;
tty4::respawn:/sbin/getty 38400 tty4&lt;br /&gt;
tty5::respawn:/sbin/getty 38400 tty5&lt;br /&gt;
tty6::respawn:/sbin/getty 38400 tty6&lt;br /&gt;
&lt;br /&gt;
tty1::respawn:/bin/login -f root&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Disable Screensaver, and refresh webpage (optional)===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/X11/xorg.conf|&lt;br /&gt;
Section &amp;quot;Extensions&amp;quot;&lt;br /&gt;
    Option      &amp;quot;DPMS&amp;quot; &amp;quot;Disable&amp;quot;&lt;br /&gt;
EndSection}} &lt;br /&gt;
&lt;br /&gt;
{{cmd|# apk add {{pkg|xdotool|arch=a*}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# crontab -u root -e &lt;br /&gt;
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Note: xset is not an option here as it&#039;s not included by default. It can be installed from the repositories, if needed.&amp;lt;/small&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
That&#039;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&#039;ll have even more resources available.&lt;br /&gt;
&lt;br /&gt;
==Digital Signage==&lt;br /&gt;
It&#039;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? &lt;br /&gt;
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd). &lt;br /&gt;
# There is no requirement to use &#039;cloud&#039; services, or an internet connection. &lt;br /&gt;
# You have full control over the build and design (all kiosk build steps are documented &amp;amp; have a small learning curve, compared to some of the more complex projects mentioned above).&lt;br /&gt;
# Free software. No recurring costs (outside of optional maintenance). &lt;br /&gt;
# No ties to external infrastructure / frameworks. Full freedom.&lt;br /&gt;
&lt;br /&gt;
In this addition to the guide above, we&#039;ll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we&#039;ll also run a web server with PHP, which hosts the resources we want to display on the sign.&lt;br /&gt;
Make sure community apk is enabled in {{path|/etc/apk/repositories}}&lt;br /&gt;
{{cmd|# apk add {{pkg|chromium|arch=a*}}}}&lt;br /&gt;
In {{path|/etc/startup.sh}} add chromium instead of firefox:&lt;br /&gt;
{{cat|/etc/startup.sh|&amp;lt;nowiki&amp;gt;...&lt;br /&gt;
chromium-browser --home-page http://127.0.0.1/resource --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you deploy the device on a TV, and you&#039;re unsure what resolution it is, you can access the resolution from the terminal (not in X), by using &lt;br /&gt;
{{cmd|# xrandr -d :0}}&lt;br /&gt;
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&#039;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&#039;s config.h, But a WM is not required.&lt;br /&gt;
&lt;br /&gt;
Make sure to run &amp;lt;code&amp;gt;lbu_commit -d&amp;lt;/code&amp;gt;, in order to save any changes as needed in the apkvol on the SD or HDD storage.&lt;br /&gt;
&lt;br /&gt;
===Install Apache/PHP===&lt;br /&gt;
See [[Apache]].&lt;br /&gt;
&lt;br /&gt;
===Install xset to disable screensaver===&lt;br /&gt;
{{cmd|# apk add {{pkg|xset|arch=a*}}&lt;br /&gt;
&amp;amp;num; xset q&lt;br /&gt;
&amp;amp;num; xset s off&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Hide Scrollbars of Browser===&lt;br /&gt;
This can be done with CSS.&lt;br /&gt;
 body {&lt;br /&gt;
   overflow: hidden; /* Hide scrollbars */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
===Why was this setup used? Why not Awesome, or dwm?===&lt;br /&gt;
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&#039;t have this limitation. It should be possible to get more RAM via {{path|/boot/config.txt}}&lt;br /&gt;
&lt;br /&gt;
If your application doesn&#039;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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Width &amp;amp; height of firefox doesn&#039;t fit the monitor===&lt;br /&gt;
Firefox can be called with -height and -width flags, e.g. &lt;br /&gt;
{{cmd|firefox -width 480 -height 640 example.org}}&lt;br /&gt;
&lt;br /&gt;
===Periodic Firefox Crashes on RPI3 due to Low Memory===&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
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 &amp;gt;1GB ram which may eliminate the need for a nightly reboot.&lt;br /&gt;
&lt;br /&gt;
===Firefox-esr segmentation fault on x86 for 3.17===&lt;br /&gt;
In running firefox on an old intel atom netbook, I see firefox having a &#039;segmentation fault&#039; 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.&lt;br /&gt;
&lt;br /&gt;
===How do I easily backup my diskless system?===&lt;br /&gt;
You should backup the apkvol which is located in /media/mmc (the location of the sd card).&lt;br /&gt;
&lt;br /&gt;
===How do I backup firefox about:config edits?===&lt;br /&gt;
Use lbu include, and point to the &#039;full path&#039; of the file. Finally, set it with lbu_commit -d. You can review the page for [[lbu]], for more details. A trap, is that if you use a relative path, it will also include a relative (useless) path in /etc/apk/protected_paths.d/lbu.list&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* [[dwm]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=30371</id>
		<title>Raspberry Pi 3 - Browser Client</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=30371"/>
		<updated>2025-07-08T13:43:26Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* How do I easily backup my diskless system? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;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.&lt;br /&gt;
&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
Note that this guide started out with an RPI3, has been used with x86, and currently runs with an RPI4, though the guide hasn&#039;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.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This guide uses the following:&lt;br /&gt;
* aarch64 img (though this guide is also tested to be roughly x86-compatible)&lt;br /&gt;
* Raspberry Pi3&lt;br /&gt;
* community repo.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
See https://pkgs.alpinelinux.org/packages?name=*firefox*&amp;amp;branch=v3.11&amp;amp;arch=aarch64&lt;br /&gt;
&lt;br /&gt;
Note: the aarch64 build is not compatible with all Raspberry Pi models. See [[Raspberry Pi]].&lt;br /&gt;
&lt;br /&gt;
==Steps==&lt;br /&gt;
===Base Install===&lt;br /&gt;
&lt;br /&gt;
These steps are duplicated from the [[Raspberry Pi]] page. (Note that for sake of this guide, it&#039;s assumed the RPI is a RAM only install. Although there is no requirement for it to be done this way).&lt;br /&gt;
&lt;br /&gt;
Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem. &lt;br /&gt;
e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Command (m for help): p&lt;br /&gt;
Disk /dev/sdb: 59.5 GiB, 63864569856 bytes, 124735488 sectors&lt;br /&gt;
Units: sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disklabel type: dos&lt;br /&gt;
Disk identifier: 0x00000000&lt;br /&gt;
&lt;br /&gt;
Device     Boot Start      End  Sectors Size Id Type&lt;br /&gt;
/dev/sdb1  *     2048 62916607 62914560  30G  b W95 FAT32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{cmd|# mkdosfs -F 32 /dev/sdX1}}&lt;br /&gt;
&lt;br /&gt;
untar onto mounted disk&lt;br /&gt;
&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# mount /dev/sdX1 /mnt/folder&lt;br /&gt;
# tar xvf archive.tar -C /mnt/folder/.&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other&lt;br /&gt;
config settings, do so in {{path|usercfg.txt}} now.&lt;br /&gt;
&lt;br /&gt;
Again, duplicating the [[Raspberry Pi]] page &lt;br /&gt;
&lt;br /&gt;
    Insert the SD card into the Raspberry Pi and turn it on&lt;br /&gt;
    Log in to Alpine as root. Leave the password empty.&lt;br /&gt;
    Type setup-alpine, hit enter.&lt;br /&gt;
    Once the installation is complete, commit the changes by typing lbu commit -d&lt;br /&gt;
&lt;br /&gt;
Things to keep in mind:&lt;br /&gt;
* 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. &lt;br /&gt;
* For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with &amp;quot;No disks available, try boot media /mmcblk0p1&amp;quot;. Select the default [n]. If you make a mistake during the install, you can always reimage and start over.&lt;br /&gt;
&lt;br /&gt;
Saving space: busybox instead of chronyd, dropbear instead of openssh&lt;br /&gt;
&lt;br /&gt;
After setup, make sure dropbear is installed&lt;br /&gt;
{{cmd|# apk add dropbear}}&lt;br /&gt;
&lt;br /&gt;
Start it:&lt;br /&gt;
{{cmd|# rc-service dropbear start}}&lt;br /&gt;
&lt;br /&gt;
Add it to the default runlevel:&lt;br /&gt;
{{cmd|# rc-update add dropbear}}&lt;br /&gt;
&lt;br /&gt;
If you need an accurate clock, enable software/ntp here. (this step is optional)&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# rc-update add swclock boot # enable the software clock &lt;br /&gt;
# rc-update del hwclock boot # disable the hardware clock&lt;br /&gt;
# setup-ntp&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
===Browser Client Install===&lt;br /&gt;
&lt;br /&gt;
Enable community repo ({{path|/etc/apk/repositories}}) (uncomment community)&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# nano /etc/apk/repositories&lt;br /&gt;
# apk update&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
install firefox dependencies:&lt;br /&gt;
{{cmd|# apk add libx11-dev libxft-dev libxinerama-dev font-dejavu}}&lt;br /&gt;
&amp;lt;small&amp;gt;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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the amount of RAM tmp fs available can be viewed while installing with: &amp;lt;code&amp;gt;watch df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
install firefox&lt;br /&gt;
{{cmd|# apk add firefox-esr}}&lt;br /&gt;
install X&lt;br /&gt;
{{cmd|# setup-xorg-base}}&lt;br /&gt;
The RPI also requires for X:&lt;br /&gt;
{{cmd|# apk add xf86-video-fbdev}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;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 &amp;quot;apk search libEGL.so&amp;quot; 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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, we have about 421MB of RAM used (if NTP was not set up).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
devtmpfs                 10.0M         0     10.0M   0% /dev&lt;br /&gt;
shm                     457.9M         0    457.9M   0% /dev/shm&lt;br /&gt;
/dev/mmcblk0p1           30.0G    259.4M     29.7G   1% /media/mmcblk0p1&lt;br /&gt;
tmpfs                   457.9M    420.0M     37.9M  92% /&lt;br /&gt;
tmpfs                    91.6M    188.0K     91.4M   0% /run&lt;br /&gt;
/dev/loop0               24.9M     24.9M         0 100% /.modloop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{cmd|# lbu_commit -d}}&lt;br /&gt;
&lt;br /&gt;
===AutoLogin, Startx automatically on Boot===&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to login as root, and run startx manually. Now we&#039;ll add configuration files to enable that without user interaction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;What is happening here from my understanding is:&lt;br /&gt;
 1) User logs in. {{path|/etc/profile}} is run (which includes a call to startx)&lt;br /&gt;
 2) Startx references any relevant xinitrc (user folder or {{path|/etc/X11}}), which calls {{path|/etc/startup.sh}}&lt;br /&gt;
 3) {{path|/etc/startup.sh}} runs any commands, such as dwm, firefox, or chromium.&lt;br /&gt;
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 &amp;quot;logger&amp;quot; in shell scripts.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{path|/root/}} doesn&#039;t save any files, so it&#039;s necessary to edit files in {{path|/etc/}} and run &amp;lt;code&amp;gt;lbu_commit -d&amp;lt;/code&amp;gt; after all changes. First let&#039;s add a file that we&#039;ll call firefox.&lt;br /&gt;
&amp;lt;small&amp;gt;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]]&lt;br /&gt;
also see: {{path|/etc/apk/protected_paths.d/lbu.list}}&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
create a file named {{path|/etc/startup.sh}}:&lt;br /&gt;
{{cat|/etc/startup.sh|#!/bin/sh&lt;br /&gt;
firefox-esr &amp;lt;nowiki&amp;gt;http://awebsite.com&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
!!!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.&lt;br /&gt;
&lt;br /&gt;
Make sure the file is executable.&lt;br /&gt;
{{cmd|# chmod +x /etc/startup.sh}}&lt;br /&gt;
&lt;br /&gt;
We have to edit xinitrc, and the profile configs. Normally, this would be done in the user&#039;s directory, but here we will use the globals for simplicity. Note that here we are &#039;moving&#039; 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).&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK&lt;br /&gt;
# nano /etc/X11/xinit/xinitrc&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
In this file, insert:&lt;br /&gt;
{{cat|/etc/X11/xinit/xinitrc|...&lt;br /&gt;
/etc/startup.sh}}&lt;br /&gt;
At the end of {{path|/etc/profile}} (leave the existing file) append&lt;br /&gt;
{{cat|/etc/profile|...&lt;br /&gt;
startx}}&lt;br /&gt;
Remember to run &amp;lt;code&amp;gt;lbu_commit -d&amp;lt;/code&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
For autologin, alpine uses busybox, which has an alias to {{path|/sbin/getty}} as well as {{path|/bin/login}}. It&#039;s possible to navigate to {{path|/sbin/}} or {{path|/bin/}} and run &amp;lt;code&amp;gt;/sbin/getty -h&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
{{cat|/etc/inittab|&amp;lt;nowiki&amp;gt;# Set up a couple of gettys&lt;br /&gt;
#tty1::respawn:/sbin/getty 38400 tty1&lt;br /&gt;
tty2::respawn:/sbin/getty 38400 tty2&lt;br /&gt;
tty3::respawn:/sbin/getty 38400 tty3&lt;br /&gt;
tty4::respawn:/sbin/getty 38400 tty4&lt;br /&gt;
tty5::respawn:/sbin/getty 38400 tty5&lt;br /&gt;
tty6::respawn:/sbin/getty 38400 tty6&lt;br /&gt;
&lt;br /&gt;
tty1::respawn:/bin/login -f root&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Disable Screensaver, and refresh webpage (optional)===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/X11/xorg.conf|&lt;br /&gt;
Section &amp;quot;Extensions&amp;quot;&lt;br /&gt;
    Option      &amp;quot;DPMS&amp;quot; &amp;quot;Disable&amp;quot;&lt;br /&gt;
EndSection}} &lt;br /&gt;
&lt;br /&gt;
{{cmd|# apk add {{pkg|xdotool|arch=a*}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# crontab -u root -e &lt;br /&gt;
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Note: xset is not an option here as it&#039;s not included by default. It can be installed from the repositories, if needed.&amp;lt;/small&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
That&#039;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&#039;ll have even more resources available.&lt;br /&gt;
&lt;br /&gt;
==Digital Signage==&lt;br /&gt;
It&#039;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? &lt;br /&gt;
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd). &lt;br /&gt;
# There is no requirement to use &#039;cloud&#039; services, or an internet connection. &lt;br /&gt;
# You have full control over the build and design (all kiosk build steps are documented &amp;amp; have a small learning curve, compared to some of the more complex projects mentioned above).&lt;br /&gt;
# Free software. No recurring costs (outside of optional maintenance). &lt;br /&gt;
# No ties to external infrastructure / frameworks. Full freedom.&lt;br /&gt;
&lt;br /&gt;
In this addition to the guide above, we&#039;ll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we&#039;ll also run a web server with PHP, which hosts the resources we want to display on the sign.&lt;br /&gt;
Make sure community apk is enabled in {{path|/etc/apk/repositories}}&lt;br /&gt;
{{cmd|# apk add {{pkg|chromium|arch=a*}}}}&lt;br /&gt;
In {{path|/etc/startup.sh}} add chromium instead of firefox:&lt;br /&gt;
{{cat|/etc/startup.sh|&amp;lt;nowiki&amp;gt;...&lt;br /&gt;
chromium-browser --home-page http://127.0.0.1/resource --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you deploy the device on a TV, and you&#039;re unsure what resolution it is, you can access the resolution from the terminal (not in X), by using &lt;br /&gt;
{{cmd|# xrandr -d :0}}&lt;br /&gt;
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&#039;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&#039;s config.h, But a WM is not required.&lt;br /&gt;
&lt;br /&gt;
Make sure to run &amp;lt;code&amp;gt;lbu_commit -d&amp;lt;/code&amp;gt;, in order to save any changes as needed in the apkvol on the SD or HDD storage.&lt;br /&gt;
&lt;br /&gt;
===Install Apache/PHP===&lt;br /&gt;
See [[Apache]].&lt;br /&gt;
&lt;br /&gt;
===Install xset to disable screensaver===&lt;br /&gt;
{{cmd|# apk add {{pkg|xset|arch=a*}}&lt;br /&gt;
&amp;amp;num; xset q&lt;br /&gt;
&amp;amp;num; xset s off&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Hide Scrollbars of Browser===&lt;br /&gt;
This can be done with CSS.&lt;br /&gt;
 body {&lt;br /&gt;
   overflow: hidden; /* Hide scrollbars */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
===Why was this setup used? Why not Awesome, or dwm?===&lt;br /&gt;
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&#039;t have this limitation. It should be possible to get more RAM via {{path|/boot/config.txt}}&lt;br /&gt;
&lt;br /&gt;
If your application doesn&#039;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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Width &amp;amp; height of firefox doesn&#039;t fit the monitor===&lt;br /&gt;
Firefox can be called with -height and -width flags, e.g. &lt;br /&gt;
{{cmd|firefox -width 480 -height 640 example.org}}&lt;br /&gt;
&lt;br /&gt;
===Periodic Firefox Crashes on RPI3 due to Low Memory===&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
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 &amp;gt;1GB ram which may eliminate the need for a nightly reboot.&lt;br /&gt;
&lt;br /&gt;
===Firefox-esr segmentation fault on x86 for 3.17===&lt;br /&gt;
In running firefox on an old intel atom netbook, I see firefox having a &#039;segmentation fault&#039; 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.&lt;br /&gt;
&lt;br /&gt;
===How do I easily backup my diskless system?===&lt;br /&gt;
You should backup the apkvol which is located in /media/mmc (the location of the sd card).&lt;br /&gt;
&lt;br /&gt;
===How do I backup firefox about:config edits?===&lt;br /&gt;
Use lbu include, and point to the &#039;full path&#039; of the file. Finally, set it with lbu_commit -d. You can review the page for [[lbu]], for more details. A trap, is that if you use a relative path, it will also include a relative (useless) path in /etc/apk/protected_paths.d/lbu.list&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* [[dwm]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Cross-Compiler_targeting_Alpine&amp;diff=29879</id>
		<title>Cross-Compiler targeting Alpine</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Cross-Compiler_targeting_Alpine&amp;diff=29879"/>
		<updated>2025-05-21T02:59:00Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Obsolete|This was written before the change to musl so it will most likely not work at all}}&lt;br /&gt;
&lt;br /&gt;
This page explains how I set up a cross-compiler on [https://www.archlinux.org/ ArchLinux] (both x86 and x86_64) targeting Alpine. There are only a few situations in which you&#039;d want to do this. I had to do it because I wanted to port [https://www.haskell.org/ghc/ GHC] to Alpine, and to do that, you need to start with some already-compiled GHC binary. So that meant cross-compiling from some system where the binaries were already available.&lt;br /&gt;
&lt;br /&gt;
I used [https://buildroot.uclibc.org/ Buildroot] to setup my cross-compiler. These instructions target Buildroot 2013.05 and Alpine 2.6.0, both released in May 2013. The specific versions installed by this Buildroot (as I&#039;ve configured it) are:&lt;br /&gt;
&lt;br /&gt;
* kernel headers v3.9.2&lt;br /&gt;
* uClibc v0.9.33.2&lt;br /&gt;
* binutils v2.23.2&lt;br /&gt;
* gcc v4.7.3&lt;br /&gt;
* gmp v5.1.1&lt;br /&gt;
* mpc v1.0.1&lt;br /&gt;
* mpfr v3.1.2 (Alpine currently using mpfr3-3.1.1)&lt;br /&gt;
* m4 v1.4.16&lt;br /&gt;
* autoconf v2.68 (Alpine currently using autoconf-2.69)&lt;br /&gt;
* automake v1.11.6 (Alpine currently using automake-1.13.1)&lt;br /&gt;
* libiconv v1.14 (Alpine currently using 1.12)&lt;br /&gt;
* libtool v2.2.10 (Alpine currently using libtool-2.4.2)&lt;br /&gt;
* ncurses v5.9&lt;br /&gt;
* libffi v3.0.13&lt;br /&gt;
&lt;br /&gt;
Buildroot also installs BusyBox v1.12.0, but I ignore this.&lt;br /&gt;
&lt;br /&gt;
The instructions below also describe how to install a cross-compiling LLVM and Clang v3.2 on top of the Buildroot tools. This might be useful for some purposes.&lt;br /&gt;
&lt;br /&gt;
If you want to use these instructions as a basis for doing the same thing with more recent releases of Buildroot or targeting newer releases of Alpine, be sure to check for patches added to the Alpine ports tree, especially to [[gcc]] or uClibc, after [https://git.alpinelinux.org/aports/log/?h=v2.6.0 2.6.0].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;OL&amp;gt;&lt;br /&gt;
&amp;lt;LI&amp;gt;&amp;lt;div&amp;gt;&lt;br /&gt;
I began by [[Installing ArchLinux inside an Alpine chroot]].&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;LI&amp;gt;&amp;lt;div&amp;gt;&lt;br /&gt;
On the Arch system, install the following packages:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|pacman -S less man-db man-pages licenses procps-ng psmisc sysfsutils \&lt;br /&gt;
  base-devel openssh cpio elfutils gperf rsync unzip vim wget zip}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;LI&amp;gt;&amp;lt;div&amp;gt;&lt;br /&gt;
On the Arch system, do the following:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|mkdir ~/python2-path&lt;br /&gt;
ln -s /usr/bin/python2 ~/python2-path/python&lt;br /&gt;
export PATH{{=}}$HOME/python2-path:$PATH&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;LI&amp;gt;&amp;lt;div&amp;gt;&lt;br /&gt;
On the Arch system, prepare the sources and patches to build the cross-compiler.&lt;br /&gt;
&lt;br /&gt;
{{Cmd|&amp;lt;nowiki&amp;gt;mkdir -p $HOME/sources/patches &amp;amp;&amp;amp; cd $HOME/sources&lt;br /&gt;
&lt;br /&gt;
get_from_aports() (&lt;br /&gt;
    local APORTS_URL=https://git.alpinelinux.org/aports/plain&lt;br /&gt;
    mkdir -p $1&lt;br /&gt;
    cd $1 || return 1&lt;br /&gt;
    if [ -n &amp;quot;$3&amp;quot; ]; then&lt;br /&gt;
        wget -N -O $(printf &#039;%02d-%s&#039; $3 ${2##*/}) $APORTS_URL/main/$2&lt;br /&gt;
    else&lt;br /&gt;
        wget -N $APORTS_URL/main/$2&lt;br /&gt;
    fi&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
get_from_gist() (&lt;br /&gt;
    local GIST_URL=https://gist.github.com/dubiousjim/5603159/raw&lt;br /&gt;
    mkdir -p $1&lt;br /&gt;
    cd $1 || return 1&lt;br /&gt;
    if [ -n &amp;quot;$3&amp;quot; ]; then&lt;br /&gt;
        wget -N -O $(printf &#039;%02d-%s&#039; $3 ${2##*/}) $GIST_URL/$2&lt;br /&gt;
    else&lt;br /&gt;
        wget -N $GIST_URL/$2&lt;br /&gt;
    fi&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
get_from_aports patches/binutils/2.23.2 binutils/binutils-ld-fix-static-linking.patch&lt;br /&gt;
&lt;br /&gt;
get_from_aports patches/gcc/4.7.3 gcc/pt_gnu_eh_frame.patch 1&lt;br /&gt;
get_from_aports patches/gcc/4.7.3 gcc/uclibc-getipinfo.patch 2&lt;br /&gt;
get_from_aports patches/gcc/4.7.3 gcc/gcc-4.7-dynamic-linker.patch 3&lt;br /&gt;
get_from_aports patches/gcc/4.7.3 gcc/gcc-4.6-pr32219.patch 4&lt;br /&gt;
get_from_aports patches/gcc/4.7.3 gcc/gcc-pure64.patch 5&lt;br /&gt;
sed -i -e &#039;s/\$(ESP_NOPIE_CFLAGS) //&#039; patches/gcc/4.7.3/03-gcc-4.7-dynamic-linker.patch&lt;br /&gt;
&lt;br /&gt;
get_from_aports patches/gmp/5.1.1 gmp5/gmp-4.1.4-noexecstack.patch&lt;br /&gt;
&lt;br /&gt;
# work around rpath issue&lt;br /&gt;
get_from_gist patches/libiconv/1.14 libiconv-configure.patch&lt;br /&gt;
   &lt;br /&gt;
get_from_aports patches/uClibc/0.9.33.2 libc0.9.32/APKBUILD&lt;br /&gt;
source=$( cd patches/uClibc/0.9.33.2 &amp;amp;&amp;amp; . APKBUILD &amp;amp;&amp;amp; echo $source )&lt;br /&gt;
j=1&lt;br /&gt;
for i in $source; do&lt;br /&gt;
    case $i in&lt;br /&gt;
    *.patch) get_from_aports patches/uClibc/0.9.33.2 libc0.9.32/$i $((j++))&lt;br /&gt;
    esac&lt;br /&gt;
done&lt;br /&gt;
# finally, set abi version and remove unsupported warnings c flag&lt;br /&gt;
get_from_gist patches/uClibc/0.9.33.2 uclibc-Rules.mak.patch $j&lt;br /&gt;
&lt;br /&gt;
case `uname -m` in&lt;br /&gt;
x86_64) ARCH=x86_64; H=$ARCH T=$ARCH;;&lt;br /&gt;
i?86) ARCH=x86 H=i686 T=i486;;&lt;br /&gt;
*) echo Unknown architecture;;&lt;br /&gt;
esac&lt;br /&gt;
&lt;br /&gt;
get_from_aports . libc0.9.32/uclibcconfig.$ARCH&lt;br /&gt;
echo &#039;# USE_OLD_VFPRINTF is not set&#039; &amp;gt;&amp;gt; uclibcconfig.$ARCH&lt;br /&gt;
   &lt;br /&gt;
BUILDROOTVER=2013.05-rc2&lt;br /&gt;
wget -N https://buildroot.uclibc.org/downloads/buildroot-$BUILDROOTVER.tar.bz2&lt;br /&gt;
get_from_gist . config.$ARCH&lt;br /&gt;
get_from_gist . buildroot-makes.patch&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;LI&amp;gt;&amp;lt;div&amp;gt;&lt;br /&gt;
Now, compile buildroot:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|&amp;lt;nowiki&amp;gt;cd &amp;amp;&amp;amp; tar -xjf sources/buildroot-$BUILDROOTVER.tar.bz2&lt;br /&gt;
cd buildroot-$BUILDROOTVER &amp;amp;&amp;amp; patch -p1 -i ../sources/buildroot-makes.patch&lt;br /&gt;
BUILDROOT=$HOME/buildroot-$ARCH&lt;br /&gt;
mkdir $BUILDROOT &amp;amp;&amp;amp; cd $BUILDROOT &amp;amp;&amp;amp; cp ../sources/config.$ARCH .config&lt;br /&gt;
make O=$PWD -C ../buildroot-$BUILDROOTVER 2&amp;gt;&amp;amp;1 | tee build.log&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;LI&amp;gt;&amp;lt;div&amp;gt;&lt;br /&gt;
If the compilation was successful, then:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|export PATH{{=}}$PATH:$BUILDROOT/host/usr/bin}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;LI&amp;gt;&amp;lt;div&amp;gt;&lt;br /&gt;
(Optional) Download and compile LLVM and clang. (This needs the patch at {{Issue|1915}}, which hasn&#039;t yet made it into the aports tree.)&lt;br /&gt;
&lt;br /&gt;
{{Cmd|&amp;lt;nowiki&amp;gt;cd $HOME/sources&lt;br /&gt;
wget -N https://llvm.org/releases/3.2/llvm-3.2.src.tar.gz&lt;br /&gt;
wget -N https://llvm.org/releases/3.2/clang-3.2.src.tar.gz&lt;br /&gt;
get_from_aports . llvm/llvm-3.2-alpine-linux.patch&lt;br /&gt;
cd &amp;amp;&amp;amp; tar -xzf sources/llvm-3.2.src.tar.gz &amp;amp;&amp;amp; tar -xzf sources/clang-3.2.src.tar.gz &amp;amp;&amp;amp; cd llvm-3.2.src&lt;br /&gt;
rm -rf tools/clang &amp;amp;&amp;amp; mv ../clang-3.2.src tools/clang&lt;br /&gt;
patch -p1 &amp;lt; ../sources/llvm-3.2-alpine-linux.patch&lt;br /&gt;
cd &amp;amp;&amp;amp; mkdir llvm-build.$ARCH &amp;amp;&amp;amp; cd llvm-build.$ARCH&lt;br /&gt;
../llvm-3.2.src/configure --prefix=$BUILDROOT/host/usr \&lt;br /&gt;
  --build=$H-pc-linux-gnu --host=$H-pc-linux-gnu --target=$T-buildroot-linux-uclibc \&lt;br /&gt;
  --with-gcc-toolchain=$BUILDROOT/host/usr --with-default-sysroot=$BUILDROOT/staging \&lt;br /&gt;
  --enable-jit --enable-pic --enable-assertions --enable-optimized --enable-shared --disable-docs \&lt;br /&gt;
  --enable-targets=x86,x86_64 | tee build.log&lt;br /&gt;
{ make &amp;amp;&amp;amp; make install; } 2&amp;gt;&amp;amp;1 | tee -a build.log&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/OL&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now on the Arch system you can do this:&lt;br /&gt;
{{Cmd|echo &#039;int main(void) {return 0;}&#039; &amp;gt; test.c&lt;br /&gt;
i486-buildroot-linux-uclibc-gcc -o test test.c&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Or you could use &amp;lt;code&amp;gt;i486-buildroot-linux-uclibc-clang&amp;lt;/code&amp;gt; instead.&lt;br /&gt;
&lt;br /&gt;
The resulting binary won&#039;t run on the Arch system (or from a shell launched from inside the Arch chroot, if the Arch system is on a chroot inside your Alpine system, as mine is). But it will run on the Alpine system (or from a shell launched from outside the Arch chroot).&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=28991</id>
		<title>ZoneMinder video camera security and surveillance</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=28991"/>
		<updated>2025-02-11T21:38:52Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* Troubleshooting */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://www.zoneminder.com/ ZoneMinder] usually runs with [[Apache]], but in this short how-to we use [[Lighttpd]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Base Install==&lt;br /&gt;
&lt;br /&gt;
ZoneMinder is found in the community repositories, please enable it by following the instructions [[Repositories#Enabling_the_community_repository|here]]&lt;br /&gt;
&lt;br /&gt;
Then, add the packages for zoneminder to our system&lt;br /&gt;
&lt;br /&gt;
 apk add zoneminder mariadb mysql-client lighttpd php-fpm php-pdo php-pdo_mysql php-intl php-session php-ctype &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: You will need to adjust the above to use the appropriate php version. For example, in alpine 3.17 php 8.1 is used therefore you would enter php81-fpm. In alpine 3.20 php 8.3 is used so you would enter php83-fpm. You can look up the php version by typing apk search php and sorting through the results for your given release. This version suffix should be added to each php package.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Database===&lt;br /&gt;
&lt;br /&gt;
Initialize [https://www.mysql.com/ MySQL] database&lt;br /&gt;
&lt;br /&gt;
 rc-service mariadb setup&lt;br /&gt;
&lt;br /&gt;
Start the database&lt;br /&gt;
&lt;br /&gt;
 rc-service mariadb start&lt;br /&gt;
&lt;br /&gt;
Set root password for MySQL as instructed by MySQL setup&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mysqladmin -u root password &#039;your_secure_root_mysql_password&#039;&lt;br /&gt;
&lt;br /&gt;
You can log into MySQL as current root user with&lt;br /&gt;
 mysql&lt;br /&gt;
&lt;br /&gt;
Create a ZoneMinder MySQL database and user&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; create database zm;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; CREATE USER zmuser@localhost IDENTIFIED BY &#039;your_zm_password_as_set_in_config&#039;;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; grant ALL on zm.* to zmuser@localhost;&lt;br /&gt;
&lt;br /&gt;
===Web Server===&lt;br /&gt;
&lt;br /&gt;
We are running &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;, so let&#039;s run &amp;lt;code&amp;gt;php-fpm&amp;lt;/code&amp;gt; as lighttpd user/group&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php8/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: for php 8.1&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php81/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
Add this section to the bottom of the file:&lt;br /&gt;
&lt;br /&gt;
 ; Unix user/group of processes&lt;br /&gt;
 ; Note: The user is mandatory. If the group is not set, the default user&#039;s group&lt;br /&gt;
 ;       will be used.&lt;br /&gt;
 ;user = nobody&lt;br /&gt;
 ;group = nobody&lt;br /&gt;
 user = lighttpd&lt;br /&gt;
 group = lighttpd&lt;br /&gt;
&lt;br /&gt;
Enable the php cgi fpm config in &amp;lt;code&amp;gt;lighttpd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
Go down to the server modules section and uncomment &amp;lt;code&amp;gt;mod_alias&amp;lt;/code&amp;gt;, which is needed for the cgi-bin, and &amp;lt;code&amp;gt;mod_rewrite&amp;lt;/code&amp;gt;, for the api. It should look like:&lt;br /&gt;
&lt;br /&gt;
 # {{{ modules&lt;br /&gt;
 # At the very least, mod_access and mod_accesslog should be enabled.&lt;br /&gt;
 # All other modules should only be loaded if necessary.&lt;br /&gt;
 # NOTE: the order of modules is important.&lt;br /&gt;
 server.modules = (&lt;br /&gt;
      &amp;quot;mod_rewrite&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_redirect&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_alias&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_access&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_cml&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_trigger_b4_dl&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_auth&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_status&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_setenv&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_proxy&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_simple_vhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_evhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_userdir&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_deflate&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_ssi&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_usertrack&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_expire&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_secdownload&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_rrdtool&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_webdav&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_accesslog&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
Go down to the includes section, it should look like:&lt;br /&gt;
 # {{{ includes&lt;br /&gt;
 include &amp;quot;mime-types.conf&amp;quot;&lt;br /&gt;
 # uncomment for cgi support&lt;br /&gt;
    include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi support&lt;br /&gt;
 #   include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi fpm support&lt;br /&gt;
    include &amp;quot;mod_fastcgi_fpm.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
In order for video streaming to work in 1.36, you&#039;ll need the following&lt;br /&gt;
added to /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
 server.stream-response-body = 1&lt;br /&gt;
&lt;br /&gt;
In lighttpd.conf for the API, we will want to redirect any api+ requests to cakephp. Thus, add:&lt;br /&gt;
 url.rewrite = (&lt;br /&gt;
       &amp;quot;^/zm/api(.+)$&amp;quot;           =&amp;gt;              &amp;quot;/zm/api/index.php&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Edit lighttpd cgi config and add old style cgi support by adding to cgi.assign&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/mod_cgi.conf&lt;br /&gt;
&lt;br /&gt;
which should look like&lt;br /&gt;
&lt;br /&gt;
 cgi.assign = (&lt;br /&gt;
     &amp;quot;&amp;quot;      =&amp;gt;      &amp;quot;&amp;quot;,&lt;br /&gt;
     &amp;quot;.pl&amp;quot;   =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
     &amp;quot;.cgi&amp;quot;  =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Also add the following to alias.url in mod_cgi.conf so that it looks like&lt;br /&gt;
&lt;br /&gt;
 alias.url = (&lt;br /&gt;
     &amp;quot;/cgi-bin/&amp;quot;            =&amp;gt;      var.basedir + &amp;quot;/cgi-bin/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/api&amp;quot;              =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/api/app/webroot/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/&amp;quot;                 =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Remove the symlink in /var/www/localhost/htdocs (we will be using the alias, not the symlink). &lt;br /&gt;
 unlink /var/www/localhost/htdocs/zm&lt;br /&gt;
&lt;br /&gt;
Start php-fpm&lt;br /&gt;
&lt;br /&gt;
 rc-service php-fpm8 start&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; for php-fpm81, use the following command:&lt;br /&gt;
&lt;br /&gt;
 rc-service php-fpm81 start&lt;br /&gt;
&lt;br /&gt;
Start lighttpd&lt;br /&gt;
&lt;br /&gt;
 rc-service lighttpd start&lt;br /&gt;
&lt;br /&gt;
===Zoneminder===&lt;br /&gt;
&lt;br /&gt;
Set the MySQL hostname, username, password.&lt;br /&gt;
&lt;br /&gt;
Change the ZoneMinder user (&amp;lt;code&amp;gt;ZM_WEB_USER&amp;lt;/code&amp;gt;) and group (&amp;lt;code&amp;gt;ZM_WEB_GROUP&amp;lt;/code&amp;gt;) to lighttpd&lt;br /&gt;
&lt;br /&gt;
And set &amp;lt;code&amp;gt;ZM_SERVER_HOST&amp;lt;/code&amp;gt; to your ZoneMinder hostname/ipaddress&lt;br /&gt;
&lt;br /&gt;
 vi /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Which should look like:&lt;br /&gt;
&lt;br /&gt;
 # Username and group that web daemon (httpd/apache) runs as&lt;br /&gt;
 ZM_WEB_USER=lighttpd&lt;br /&gt;
 ZM_WEB_GROUP=lighttpd&lt;br /&gt;
 ZM_PATH_DATA=/usr/share/zoneminder&lt;br /&gt;
&lt;br /&gt;
 # ZoneMinder database type: so far only mysql is supported&lt;br /&gt;
 ZM_DB_TYPE=mysql&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database hostname or ip address&lt;br /&gt;
 ZM_DB_HOST=localhost&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database name&lt;br /&gt;
 ZM_DB_NAME=zm&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database user&lt;br /&gt;
 ZM_DB_USER=zmuser&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database password&lt;br /&gt;
 ZM_DB_PASS=your_zm_password_as_set_in_config&lt;br /&gt;
 &lt;br /&gt;
 # Host of this machine&lt;br /&gt;
 ZM_SERVER_HOST=yourserver&lt;br /&gt;
&lt;br /&gt;
Change ownership of &amp;lt;code&amp;gt;zm.conf&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 chown lighttpd.lighttpd /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Zoneminder will create a cache in &amp;lt;code&amp;gt;/var/cache/zoneminder&amp;lt;/code&amp;gt; which isn&#039;t created by default. Create this directory and allow lighttpd access to it. Note that if you are using a diskless install, you must lbu add /var/cache/zoneminder.&lt;br /&gt;
&lt;br /&gt;
 mkdir /var/cache/zoneminder&lt;br /&gt;
 chown lighttpd.lighttpd /var/cache/zoneminder&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Initialize the ZoneMinder database&lt;br /&gt;
&lt;br /&gt;
 rc-service zoneminder setup&lt;br /&gt;
&lt;br /&gt;
Start ZoneMinder&lt;br /&gt;
&lt;br /&gt;
 rc-service zoneminder start&lt;br /&gt;
&lt;br /&gt;
Profit!&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
To access ZoneMinder, browse to &amp;lt;nowiki&amp;gt;http://yourserver/zm/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To test the API, run&lt;br /&gt;
 curl -X GET  &amp;lt;nowiki&amp;gt;http://yourserver/zm/api/host/getVersion.json&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
(This assumes you aren&#039;t using authentication.)&lt;br /&gt;
&lt;br /&gt;
To make it start automatically on boot:&lt;br /&gt;
&lt;br /&gt;
 rc-update add lighttpd default&lt;br /&gt;
 rc-update add mariadb default&lt;br /&gt;
 rc-update add php-fpm8 default&lt;br /&gt;
 rc-update add zoneminder default&lt;br /&gt;
&lt;br /&gt;
== Added notes to work with Nginx ==&lt;br /&gt;
Later to add some notes about running via nginx&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
===General troubleshooting of lighttpd===&lt;br /&gt;
You can enable debugging on lighttpd by uncommenting the debug options in /etc/lighttpd/lighttpd.conf (which in 3.20 were): &lt;br /&gt;
 debug.log-request-header   = &amp;quot;enable&amp;quot;&lt;br /&gt;
 debug.log-response-header  = &amp;quot;enable&amp;quot;&lt;br /&gt;
 debug.log-request-handling = &amp;quot;enable&amp;quot;&lt;br /&gt;
 debug.log-file-not-found   = &amp;quot;enable&amp;quot;&lt;br /&gt;
Note that since 3.14, mod_alias is now built into lighttpd and is not a module (.so file).&lt;br /&gt;
&lt;br /&gt;
For further troubleshooting, refer to the alpine build logs (https://pkgs.alpinelinux.org/package/v3.21/main/x86_64/lighttpd or https://pkgs.alpinelinux.org/package/v3.21/main/x86_64/zoneminder)  or alternatively, the lighttpd redmine wiki &amp;amp; forums. The ZoneMinder forum/discord/github issues tracker is also available for any errors related to ZoneMinder.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===PHP Fatal Error in /var/log/lighttpd/error.log===&lt;br /&gt;
Sometimes the php extensions are missing. For example, in 3.20 I had to manually install php83-ctype, which was not required in previous versions. This is confusing because, there is php82 and php-fpm83 installed. Testing ctype from the php82 interactive shell will succeed, but ZM is using php-fpm83, and phpinfo() from an index.php lists ctype (which you might assume is installed) however ctype is listed as &#039;enable=shared&#039; which I assume means you have to install the shared library for ctype.&lt;br /&gt;
&lt;br /&gt;
===ZM is not compiled with LibVNC support in 3.20===&lt;br /&gt;
This is a missing feature, and should be resolved at some point in the future. This means source type:VNC will not work.&lt;br /&gt;
&lt;br /&gt;
[[Category:Software]]&lt;br /&gt;
[[Category:Security]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=28990</id>
		<title>ZoneMinder video camera security and surveillance</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=28990"/>
		<updated>2025-02-11T21:37:54Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* Base Install */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://www.zoneminder.com/ ZoneMinder] usually runs with [[Apache]], but in this short how-to we use [[Lighttpd]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Base Install==&lt;br /&gt;
&lt;br /&gt;
ZoneMinder is found in the community repositories, please enable it by following the instructions [[Repositories#Enabling_the_community_repository|here]]&lt;br /&gt;
&lt;br /&gt;
Then, add the packages for zoneminder to our system&lt;br /&gt;
&lt;br /&gt;
 apk add zoneminder mariadb mysql-client lighttpd php-fpm php-pdo php-pdo_mysql php-intl php-session php-ctype &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: You will need to adjust the above to use the appropriate php version. For example, in alpine 3.17 php 8.1 is used therefore you would enter php81-fpm. In alpine 3.20 php 8.3 is used so you would enter php83-fpm. You can look up the php version by typing apk search php and sorting through the results for your given release. This version suffix should be added to each php package.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Database===&lt;br /&gt;
&lt;br /&gt;
Initialize [https://www.mysql.com/ MySQL] database&lt;br /&gt;
&lt;br /&gt;
 rc-service mariadb setup&lt;br /&gt;
&lt;br /&gt;
Start the database&lt;br /&gt;
&lt;br /&gt;
 rc-service mariadb start&lt;br /&gt;
&lt;br /&gt;
Set root password for MySQL as instructed by MySQL setup&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mysqladmin -u root password &#039;your_secure_root_mysql_password&#039;&lt;br /&gt;
&lt;br /&gt;
You can log into MySQL as current root user with&lt;br /&gt;
 mysql&lt;br /&gt;
&lt;br /&gt;
Create a ZoneMinder MySQL database and user&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; create database zm;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; CREATE USER zmuser@localhost IDENTIFIED BY &#039;your_zm_password_as_set_in_config&#039;;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; grant ALL on zm.* to zmuser@localhost;&lt;br /&gt;
&lt;br /&gt;
===Web Server===&lt;br /&gt;
&lt;br /&gt;
We are running &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;, so let&#039;s run &amp;lt;code&amp;gt;php-fpm&amp;lt;/code&amp;gt; as lighttpd user/group&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php8/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: for php 8.1&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php81/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
Add this section to the bottom of the file:&lt;br /&gt;
&lt;br /&gt;
 ; Unix user/group of processes&lt;br /&gt;
 ; Note: The user is mandatory. If the group is not set, the default user&#039;s group&lt;br /&gt;
 ;       will be used.&lt;br /&gt;
 ;user = nobody&lt;br /&gt;
 ;group = nobody&lt;br /&gt;
 user = lighttpd&lt;br /&gt;
 group = lighttpd&lt;br /&gt;
&lt;br /&gt;
Enable the php cgi fpm config in &amp;lt;code&amp;gt;lighttpd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
Go down to the server modules section and uncomment &amp;lt;code&amp;gt;mod_alias&amp;lt;/code&amp;gt;, which is needed for the cgi-bin, and &amp;lt;code&amp;gt;mod_rewrite&amp;lt;/code&amp;gt;, for the api. It should look like:&lt;br /&gt;
&lt;br /&gt;
 # {{{ modules&lt;br /&gt;
 # At the very least, mod_access and mod_accesslog should be enabled.&lt;br /&gt;
 # All other modules should only be loaded if necessary.&lt;br /&gt;
 # NOTE: the order of modules is important.&lt;br /&gt;
 server.modules = (&lt;br /&gt;
      &amp;quot;mod_rewrite&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_redirect&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_alias&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_access&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_cml&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_trigger_b4_dl&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_auth&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_status&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_setenv&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_proxy&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_simple_vhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_evhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_userdir&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_deflate&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_ssi&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_usertrack&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_expire&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_secdownload&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_rrdtool&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_webdav&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_accesslog&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
Go down to the includes section, it should look like:&lt;br /&gt;
 # {{{ includes&lt;br /&gt;
 include &amp;quot;mime-types.conf&amp;quot;&lt;br /&gt;
 # uncomment for cgi support&lt;br /&gt;
    include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi support&lt;br /&gt;
 #   include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi fpm support&lt;br /&gt;
    include &amp;quot;mod_fastcgi_fpm.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
In order for video streaming to work in 1.36, you&#039;ll need the following&lt;br /&gt;
added to /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
 server.stream-response-body = 1&lt;br /&gt;
&lt;br /&gt;
In lighttpd.conf for the API, we will want to redirect any api+ requests to cakephp. Thus, add:&lt;br /&gt;
 url.rewrite = (&lt;br /&gt;
       &amp;quot;^/zm/api(.+)$&amp;quot;           =&amp;gt;              &amp;quot;/zm/api/index.php&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Edit lighttpd cgi config and add old style cgi support by adding to cgi.assign&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/mod_cgi.conf&lt;br /&gt;
&lt;br /&gt;
which should look like&lt;br /&gt;
&lt;br /&gt;
 cgi.assign = (&lt;br /&gt;
     &amp;quot;&amp;quot;      =&amp;gt;      &amp;quot;&amp;quot;,&lt;br /&gt;
     &amp;quot;.pl&amp;quot;   =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
     &amp;quot;.cgi&amp;quot;  =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Also add the following to alias.url in mod_cgi.conf so that it looks like&lt;br /&gt;
&lt;br /&gt;
 alias.url = (&lt;br /&gt;
     &amp;quot;/cgi-bin/&amp;quot;            =&amp;gt;      var.basedir + &amp;quot;/cgi-bin/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/api&amp;quot;              =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/api/app/webroot/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/&amp;quot;                 =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Remove the symlink in /var/www/localhost/htdocs (we will be using the alias, not the symlink). &lt;br /&gt;
 unlink /var/www/localhost/htdocs/zm&lt;br /&gt;
&lt;br /&gt;
Start php-fpm&lt;br /&gt;
&lt;br /&gt;
 rc-service php-fpm8 start&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; for php-fpm81, use the following command:&lt;br /&gt;
&lt;br /&gt;
 rc-service php-fpm81 start&lt;br /&gt;
&lt;br /&gt;
Start lighttpd&lt;br /&gt;
&lt;br /&gt;
 rc-service lighttpd start&lt;br /&gt;
&lt;br /&gt;
===Zoneminder===&lt;br /&gt;
&lt;br /&gt;
Set the MySQL hostname, username, password.&lt;br /&gt;
&lt;br /&gt;
Change the ZoneMinder user (&amp;lt;code&amp;gt;ZM_WEB_USER&amp;lt;/code&amp;gt;) and group (&amp;lt;code&amp;gt;ZM_WEB_GROUP&amp;lt;/code&amp;gt;) to lighttpd&lt;br /&gt;
&lt;br /&gt;
And set &amp;lt;code&amp;gt;ZM_SERVER_HOST&amp;lt;/code&amp;gt; to your ZoneMinder hostname/ipaddress&lt;br /&gt;
&lt;br /&gt;
 vi /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Which should look like:&lt;br /&gt;
&lt;br /&gt;
 # Username and group that web daemon (httpd/apache) runs as&lt;br /&gt;
 ZM_WEB_USER=lighttpd&lt;br /&gt;
 ZM_WEB_GROUP=lighttpd&lt;br /&gt;
 ZM_PATH_DATA=/usr/share/zoneminder&lt;br /&gt;
&lt;br /&gt;
 # ZoneMinder database type: so far only mysql is supported&lt;br /&gt;
 ZM_DB_TYPE=mysql&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database hostname or ip address&lt;br /&gt;
 ZM_DB_HOST=localhost&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database name&lt;br /&gt;
 ZM_DB_NAME=zm&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database user&lt;br /&gt;
 ZM_DB_USER=zmuser&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database password&lt;br /&gt;
 ZM_DB_PASS=your_zm_password_as_set_in_config&lt;br /&gt;
 &lt;br /&gt;
 # Host of this machine&lt;br /&gt;
 ZM_SERVER_HOST=yourserver&lt;br /&gt;
&lt;br /&gt;
Change ownership of &amp;lt;code&amp;gt;zm.conf&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 chown lighttpd.lighttpd /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Zoneminder will create a cache in &amp;lt;code&amp;gt;/var/cache/zoneminder&amp;lt;/code&amp;gt; which isn&#039;t created by default. Create this directory and allow lighttpd access to it. Note that if you are using a diskless install, you must lbu add /var/cache/zoneminder.&lt;br /&gt;
&lt;br /&gt;
 mkdir /var/cache/zoneminder&lt;br /&gt;
 chown lighttpd.lighttpd /var/cache/zoneminder&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Initialize the ZoneMinder database&lt;br /&gt;
&lt;br /&gt;
 rc-service zoneminder setup&lt;br /&gt;
&lt;br /&gt;
Start ZoneMinder&lt;br /&gt;
&lt;br /&gt;
 rc-service zoneminder start&lt;br /&gt;
&lt;br /&gt;
Profit!&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
To access ZoneMinder, browse to &amp;lt;nowiki&amp;gt;http://yourserver/zm/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To test the API, run&lt;br /&gt;
 curl -X GET  &amp;lt;nowiki&amp;gt;http://yourserver/zm/api/host/getVersion.json&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
(This assumes you aren&#039;t using authentication.)&lt;br /&gt;
&lt;br /&gt;
To make it start automatically on boot:&lt;br /&gt;
&lt;br /&gt;
 rc-update add lighttpd default&lt;br /&gt;
 rc-update add mariadb default&lt;br /&gt;
 rc-update add php-fpm8 default&lt;br /&gt;
 rc-update add zoneminder default&lt;br /&gt;
&lt;br /&gt;
== Added notes to work with Nginx ==&lt;br /&gt;
Later to add some notes about running via nginx&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
===General troubleshooting of lighttpd===&lt;br /&gt;
You can enable debugging on lighttpd by uncommenting the debug options in /etc/lighttpd/lighttpd.conf (which in 3.20 were): &lt;br /&gt;
 debug.log-request-header   = &amp;quot;enable&amp;quot;&lt;br /&gt;
 debug.log-response-header  = &amp;quot;enable&amp;quot;&lt;br /&gt;
 debug.log-request-handling = &amp;quot;enable&amp;quot;&lt;br /&gt;
 debug.log-file-not-found   = &amp;quot;enable&amp;quot;&lt;br /&gt;
Note that since 3.14, mod_alias is now built into lighttpd and is not a module (.so file).&lt;br /&gt;
&lt;br /&gt;
For further troubleshooting, refer to the alpine build logs (https://pkgs.alpinelinux.org/package/v3.21/main/x86_64/lighttpd or https://pkgs.alpinelinux.org/package/v3.21/main/x86_64/zoneminder)  or alternatively, the lighttpd redmine wiki &amp;amp; forums. The ZoneMinder forum/discord/github issues tracker is also available for any errors related to ZoneMinder.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===PHP Fatal Error in /var/log/lighttpd/error.log===&lt;br /&gt;
Sometimes the php extensions are missing. For example, in 3.20 I had to manually install php83-ctype, which was not required in previous versions. This is confusing because, there is php82 and php-fpm83 installed. Testing ctype from the php82 interactive shell will succeed, but ZM is using php-fpm83, and phpinfo() from an index.php lists ctype (which you might assume is installed) however ctype is listed as &#039;enable=shared&#039; which I assume means you have to install the shared library for ctype.&lt;br /&gt;
[[Category:Software]]&lt;br /&gt;
[[Category:Security]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=28989</id>
		<title>ZoneMinder video camera security and surveillance</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=28989"/>
		<updated>2025-02-11T21:36:45Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* Troubleshooting */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://www.zoneminder.com/ ZoneMinder] usually runs with [[Apache]], but in this short how-to we use [[Lighttpd]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Base Install==&lt;br /&gt;
&lt;br /&gt;
ZoneMinder is found in the community repositories, please enable it by following the instructions [[Repositories#Enabling_the_community_repository|here]]&lt;br /&gt;
&lt;br /&gt;
Then, add the packages for zoneminder to our system&lt;br /&gt;
&lt;br /&gt;
 apk add zoneminder mariadb mysql-client lighttpd php-fpm php-pdo php-pdo_mysql php-intl php-session&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: You will need to adjust the above to use the appropriate php version. For example, in alpine 3.17 php 8.1 is used therefore you would enter php81-fpm. In alpine 3.20 php 8.3 is used so you would enter php83-fpm. You can look up the php version by typing apk search php and sorting through the results for your given release. This version suffix should be added to each php package.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Database===&lt;br /&gt;
&lt;br /&gt;
Initialize [https://www.mysql.com/ MySQL] database&lt;br /&gt;
&lt;br /&gt;
 rc-service mariadb setup&lt;br /&gt;
&lt;br /&gt;
Start the database&lt;br /&gt;
&lt;br /&gt;
 rc-service mariadb start&lt;br /&gt;
&lt;br /&gt;
Set root password for MySQL as instructed by MySQL setup&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mysqladmin -u root password &#039;your_secure_root_mysql_password&#039;&lt;br /&gt;
&lt;br /&gt;
You can log into MySQL as current root user with&lt;br /&gt;
 mysql&lt;br /&gt;
&lt;br /&gt;
Create a ZoneMinder MySQL database and user&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; create database zm;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; CREATE USER zmuser@localhost IDENTIFIED BY &#039;your_zm_password_as_set_in_config&#039;;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; grant ALL on zm.* to zmuser@localhost;&lt;br /&gt;
&lt;br /&gt;
===Web Server===&lt;br /&gt;
&lt;br /&gt;
We are running &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;, so let&#039;s run &amp;lt;code&amp;gt;php-fpm&amp;lt;/code&amp;gt; as lighttpd user/group&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php8/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: for php 8.1&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php81/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
Add this section to the bottom of the file:&lt;br /&gt;
&lt;br /&gt;
 ; Unix user/group of processes&lt;br /&gt;
 ; Note: The user is mandatory. If the group is not set, the default user&#039;s group&lt;br /&gt;
 ;       will be used.&lt;br /&gt;
 ;user = nobody&lt;br /&gt;
 ;group = nobody&lt;br /&gt;
 user = lighttpd&lt;br /&gt;
 group = lighttpd&lt;br /&gt;
&lt;br /&gt;
Enable the php cgi fpm config in &amp;lt;code&amp;gt;lighttpd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
Go down to the server modules section and uncomment &amp;lt;code&amp;gt;mod_alias&amp;lt;/code&amp;gt;, which is needed for the cgi-bin, and &amp;lt;code&amp;gt;mod_rewrite&amp;lt;/code&amp;gt;, for the api. It should look like:&lt;br /&gt;
&lt;br /&gt;
 # {{{ modules&lt;br /&gt;
 # At the very least, mod_access and mod_accesslog should be enabled.&lt;br /&gt;
 # All other modules should only be loaded if necessary.&lt;br /&gt;
 # NOTE: the order of modules is important.&lt;br /&gt;
 server.modules = (&lt;br /&gt;
      &amp;quot;mod_rewrite&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_redirect&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_alias&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_access&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_cml&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_trigger_b4_dl&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_auth&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_status&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_setenv&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_proxy&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_simple_vhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_evhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_userdir&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_deflate&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_ssi&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_usertrack&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_expire&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_secdownload&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_rrdtool&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_webdav&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_accesslog&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
Go down to the includes section, it should look like:&lt;br /&gt;
 # {{{ includes&lt;br /&gt;
 include &amp;quot;mime-types.conf&amp;quot;&lt;br /&gt;
 # uncomment for cgi support&lt;br /&gt;
    include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi support&lt;br /&gt;
 #   include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi fpm support&lt;br /&gt;
    include &amp;quot;mod_fastcgi_fpm.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
In order for video streaming to work in 1.36, you&#039;ll need the following&lt;br /&gt;
added to /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
 server.stream-response-body = 1&lt;br /&gt;
&lt;br /&gt;
In lighttpd.conf for the API, we will want to redirect any api+ requests to cakephp. Thus, add:&lt;br /&gt;
 url.rewrite = (&lt;br /&gt;
       &amp;quot;^/zm/api(.+)$&amp;quot;           =&amp;gt;              &amp;quot;/zm/api/index.php&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Edit lighttpd cgi config and add old style cgi support by adding to cgi.assign&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/mod_cgi.conf&lt;br /&gt;
&lt;br /&gt;
which should look like&lt;br /&gt;
&lt;br /&gt;
 cgi.assign = (&lt;br /&gt;
     &amp;quot;&amp;quot;      =&amp;gt;      &amp;quot;&amp;quot;,&lt;br /&gt;
     &amp;quot;.pl&amp;quot;   =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
     &amp;quot;.cgi&amp;quot;  =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Also add the following to alias.url in mod_cgi.conf so that it looks like&lt;br /&gt;
&lt;br /&gt;
 alias.url = (&lt;br /&gt;
     &amp;quot;/cgi-bin/&amp;quot;            =&amp;gt;      var.basedir + &amp;quot;/cgi-bin/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/api&amp;quot;              =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/api/app/webroot/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/&amp;quot;                 =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Remove the symlink in /var/www/localhost/htdocs (we will be using the alias, not the symlink). &lt;br /&gt;
 unlink /var/www/localhost/htdocs/zm&lt;br /&gt;
&lt;br /&gt;
Start php-fpm&lt;br /&gt;
&lt;br /&gt;
 rc-service php-fpm8 start&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; for php-fpm81, use the following command:&lt;br /&gt;
&lt;br /&gt;
 rc-service php-fpm81 start&lt;br /&gt;
&lt;br /&gt;
Start lighttpd&lt;br /&gt;
&lt;br /&gt;
 rc-service lighttpd start&lt;br /&gt;
&lt;br /&gt;
===Zoneminder===&lt;br /&gt;
&lt;br /&gt;
Set the MySQL hostname, username, password.&lt;br /&gt;
&lt;br /&gt;
Change the ZoneMinder user (&amp;lt;code&amp;gt;ZM_WEB_USER&amp;lt;/code&amp;gt;) and group (&amp;lt;code&amp;gt;ZM_WEB_GROUP&amp;lt;/code&amp;gt;) to lighttpd&lt;br /&gt;
&lt;br /&gt;
And set &amp;lt;code&amp;gt;ZM_SERVER_HOST&amp;lt;/code&amp;gt; to your ZoneMinder hostname/ipaddress&lt;br /&gt;
&lt;br /&gt;
 vi /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Which should look like:&lt;br /&gt;
&lt;br /&gt;
 # Username and group that web daemon (httpd/apache) runs as&lt;br /&gt;
 ZM_WEB_USER=lighttpd&lt;br /&gt;
 ZM_WEB_GROUP=lighttpd&lt;br /&gt;
 ZM_PATH_DATA=/usr/share/zoneminder&lt;br /&gt;
&lt;br /&gt;
 # ZoneMinder database type: so far only mysql is supported&lt;br /&gt;
 ZM_DB_TYPE=mysql&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database hostname or ip address&lt;br /&gt;
 ZM_DB_HOST=localhost&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database name&lt;br /&gt;
 ZM_DB_NAME=zm&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database user&lt;br /&gt;
 ZM_DB_USER=zmuser&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database password&lt;br /&gt;
 ZM_DB_PASS=your_zm_password_as_set_in_config&lt;br /&gt;
 &lt;br /&gt;
 # Host of this machine&lt;br /&gt;
 ZM_SERVER_HOST=yourserver&lt;br /&gt;
&lt;br /&gt;
Change ownership of &amp;lt;code&amp;gt;zm.conf&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 chown lighttpd.lighttpd /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Zoneminder will create a cache in &amp;lt;code&amp;gt;/var/cache/zoneminder&amp;lt;/code&amp;gt; which isn&#039;t created by default. Create this directory and allow lighttpd access to it. Note that if you are using a diskless install, you must lbu add /var/cache/zoneminder.&lt;br /&gt;
&lt;br /&gt;
 mkdir /var/cache/zoneminder&lt;br /&gt;
 chown lighttpd.lighttpd /var/cache/zoneminder&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Initialize the ZoneMinder database&lt;br /&gt;
&lt;br /&gt;
 rc-service zoneminder setup&lt;br /&gt;
&lt;br /&gt;
Start ZoneMinder&lt;br /&gt;
&lt;br /&gt;
 rc-service zoneminder start&lt;br /&gt;
&lt;br /&gt;
Profit!&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
To access ZoneMinder, browse to &amp;lt;nowiki&amp;gt;http://yourserver/zm/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To test the API, run&lt;br /&gt;
 curl -X GET  &amp;lt;nowiki&amp;gt;http://yourserver/zm/api/host/getVersion.json&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
(This assumes you aren&#039;t using authentication.)&lt;br /&gt;
&lt;br /&gt;
To make it start automatically on boot:&lt;br /&gt;
&lt;br /&gt;
 rc-update add lighttpd default&lt;br /&gt;
 rc-update add mariadb default&lt;br /&gt;
 rc-update add php-fpm8 default&lt;br /&gt;
 rc-update add zoneminder default&lt;br /&gt;
&lt;br /&gt;
== Added notes to work with Nginx ==&lt;br /&gt;
Later to add some notes about running via nginx&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
===General troubleshooting of lighttpd===&lt;br /&gt;
You can enable debugging on lighttpd by uncommenting the debug options in /etc/lighttpd/lighttpd.conf (which in 3.20 were): &lt;br /&gt;
 debug.log-request-header   = &amp;quot;enable&amp;quot;&lt;br /&gt;
 debug.log-response-header  = &amp;quot;enable&amp;quot;&lt;br /&gt;
 debug.log-request-handling = &amp;quot;enable&amp;quot;&lt;br /&gt;
 debug.log-file-not-found   = &amp;quot;enable&amp;quot;&lt;br /&gt;
Note that since 3.14, mod_alias is now built into lighttpd and is not a module (.so file).&lt;br /&gt;
&lt;br /&gt;
For further troubleshooting, refer to the alpine build logs (https://pkgs.alpinelinux.org/package/v3.21/main/x86_64/lighttpd or https://pkgs.alpinelinux.org/package/v3.21/main/x86_64/zoneminder)  or alternatively, the lighttpd redmine wiki &amp;amp; forums. The ZoneMinder forum/discord/github issues tracker is also available for any errors related to ZoneMinder.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===PHP Fatal Error in /var/log/lighttpd/error.log===&lt;br /&gt;
Sometimes the php extensions are missing. For example, in 3.20 I had to manually install php83-ctype, which was not required in previous versions. This is confusing because, there is php82 and php-fpm83 installed. Testing ctype from the php82 interactive shell will succeed, but ZM is using php-fpm83, and phpinfo() from an index.php lists ctype (which you might assume is installed) however ctype is listed as &#039;enable=shared&#039; which I assume means you have to install the shared library for ctype.&lt;br /&gt;
[[Category:Software]]&lt;br /&gt;
[[Category:Security]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=28652</id>
		<title>ZoneMinder video camera security and surveillance</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=28652"/>
		<updated>2025-01-08T08:32:43Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* Troubleshooting */ I had some trouble with Lighttpd and a new install of 3.20 and Zoneminder so I have put some notes in for future reference. There were two packages that were missing, php-intl and php-session.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://www.zoneminder.com/ ZoneMinder] usually runs with [[Apache]], but in this short how-to we use [[Lighttpd]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Base Install==&lt;br /&gt;
&lt;br /&gt;
ZoneMinder is found in the community repositories, please enable it by following the instructions [[Repositories#Enabling_the_community_repository|here]]&lt;br /&gt;
&lt;br /&gt;
Then, add the packages for zoneminder to our system&lt;br /&gt;
&lt;br /&gt;
 apk add zoneminder mariadb mysql-client lighttpd php-fpm php-pdo php-pdo_mysql php-intl php-session&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: You will need to adjust the above to use the appropriate php version. For example, in alpine 3.17 php 8.1 is used therefore you would enter php81-fpm. In alpine 3.20 php 8.3 is used so you would enter php83-fpm. You can look up the php version by typing apk search php and sorting through the results for your given release. This version suffix should be added to each php package.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Database===&lt;br /&gt;
&lt;br /&gt;
Initialize [https://www.mysql.com/ MySQL] database&lt;br /&gt;
&lt;br /&gt;
 rc-service mariadb setup&lt;br /&gt;
&lt;br /&gt;
Start the database&lt;br /&gt;
&lt;br /&gt;
 rc-service mariadb start&lt;br /&gt;
&lt;br /&gt;
Set root password for MySQL as instructed by MySQL setup&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mysqladmin -u root password &#039;your_secure_root_mysql_password&#039;&lt;br /&gt;
&lt;br /&gt;
You can log into MySQL as current root user with&lt;br /&gt;
 mysql&lt;br /&gt;
&lt;br /&gt;
Create a ZoneMinder MySQL database and user&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; create database zm;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; CREATE USER zmuser@localhost IDENTIFIED BY &#039;your_zm_password_as_set_in_config&#039;;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; grant ALL on zm.* to zmuser@localhost;&lt;br /&gt;
&lt;br /&gt;
===Web Server===&lt;br /&gt;
&lt;br /&gt;
We are running &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;, so let&#039;s run &amp;lt;code&amp;gt;php-fpm&amp;lt;/code&amp;gt; as lighttpd user/group&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php8/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: for php 8.1&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php81/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
Add this section to the bottom of the file:&lt;br /&gt;
&lt;br /&gt;
 ; Unix user/group of processes&lt;br /&gt;
 ; Note: The user is mandatory. If the group is not set, the default user&#039;s group&lt;br /&gt;
 ;       will be used.&lt;br /&gt;
 ;user = nobody&lt;br /&gt;
 ;group = nobody&lt;br /&gt;
 user = lighttpd&lt;br /&gt;
 group = lighttpd&lt;br /&gt;
&lt;br /&gt;
Enable the php cgi fpm config in &amp;lt;code&amp;gt;lighttpd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
Go down to the server modules section and uncomment &amp;lt;code&amp;gt;mod_alias&amp;lt;/code&amp;gt;, which is needed for the cgi-bin, and &amp;lt;code&amp;gt;mod_rewrite&amp;lt;/code&amp;gt;, for the api. It should look like:&lt;br /&gt;
&lt;br /&gt;
 # {{{ modules&lt;br /&gt;
 # At the very least, mod_access and mod_accesslog should be enabled.&lt;br /&gt;
 # All other modules should only be loaded if necessary.&lt;br /&gt;
 # NOTE: the order of modules is important.&lt;br /&gt;
 server.modules = (&lt;br /&gt;
      &amp;quot;mod_rewrite&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_redirect&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_alias&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_access&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_cml&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_trigger_b4_dl&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_auth&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_status&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_setenv&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_proxy&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_simple_vhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_evhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_userdir&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_deflate&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_ssi&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_usertrack&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_expire&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_secdownload&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_rrdtool&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_webdav&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_accesslog&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
Go down to the includes section, it should look like:&lt;br /&gt;
 # {{{ includes&lt;br /&gt;
 include &amp;quot;mime-types.conf&amp;quot;&lt;br /&gt;
 # uncomment for cgi support&lt;br /&gt;
    include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi support&lt;br /&gt;
 #   include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi fpm support&lt;br /&gt;
    include &amp;quot;mod_fastcgi_fpm.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
In order for video streaming to work in 1.36, you&#039;ll need the following&lt;br /&gt;
added to /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
 server.stream-response-body = 1&lt;br /&gt;
&lt;br /&gt;
In lighttpd.conf for the API, we will want to redirect any api+ requests to cakephp. Thus, add:&lt;br /&gt;
 url.rewrite = (&lt;br /&gt;
       &amp;quot;^/zm/api(.+)$&amp;quot;           =&amp;gt;              &amp;quot;/zm/api/index.php&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Edit lighttpd cgi config and add old style cgi support by adding to cgi.assign&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/mod_cgi.conf&lt;br /&gt;
&lt;br /&gt;
which should look like&lt;br /&gt;
&lt;br /&gt;
 cgi.assign = (&lt;br /&gt;
     &amp;quot;&amp;quot;      =&amp;gt;      &amp;quot;&amp;quot;,&lt;br /&gt;
     &amp;quot;.pl&amp;quot;   =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
     &amp;quot;.cgi&amp;quot;  =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Also add the following to alias.url in mod_cgi.conf so that it looks like&lt;br /&gt;
&lt;br /&gt;
 alias.url = (&lt;br /&gt;
     &amp;quot;/cgi-bin/&amp;quot;            =&amp;gt;      var.basedir + &amp;quot;/cgi-bin/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/api&amp;quot;              =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/api/app/webroot/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/&amp;quot;                 =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Remove the symlink in /var/www/localhost/htdocs (we will be using the alias, not the symlink). &lt;br /&gt;
 unlink /var/www/localhost/htdocs/zm&lt;br /&gt;
&lt;br /&gt;
Start php-fpm&lt;br /&gt;
&lt;br /&gt;
 rc-service php-fpm8 start&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; for php-fpm81, use the following command:&lt;br /&gt;
&lt;br /&gt;
 rc-service php-fpm81 start&lt;br /&gt;
&lt;br /&gt;
Start lighttpd&lt;br /&gt;
&lt;br /&gt;
 rc-service lighttpd start&lt;br /&gt;
&lt;br /&gt;
===Zoneminder===&lt;br /&gt;
&lt;br /&gt;
Set the MySQL hostname, username, password.&lt;br /&gt;
&lt;br /&gt;
Change the ZoneMinder user (&amp;lt;code&amp;gt;ZM_WEB_USER&amp;lt;/code&amp;gt;) and group (&amp;lt;code&amp;gt;ZM_WEB_GROUP&amp;lt;/code&amp;gt;) to lighttpd&lt;br /&gt;
&lt;br /&gt;
And set &amp;lt;code&amp;gt;ZM_SERVER_HOST&amp;lt;/code&amp;gt; to your ZoneMinder hostname/ipaddress&lt;br /&gt;
&lt;br /&gt;
 vi /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Which should look like:&lt;br /&gt;
&lt;br /&gt;
 # Username and group that web daemon (httpd/apache) runs as&lt;br /&gt;
 ZM_WEB_USER=lighttpd&lt;br /&gt;
 ZM_WEB_GROUP=lighttpd&lt;br /&gt;
 ZM_PATH_DATA=/usr/share/zoneminder&lt;br /&gt;
&lt;br /&gt;
 # ZoneMinder database type: so far only mysql is supported&lt;br /&gt;
 ZM_DB_TYPE=mysql&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database hostname or ip address&lt;br /&gt;
 ZM_DB_HOST=localhost&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database name&lt;br /&gt;
 ZM_DB_NAME=zm&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database user&lt;br /&gt;
 ZM_DB_USER=zmuser&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database password&lt;br /&gt;
 ZM_DB_PASS=your_zm_password_as_set_in_config&lt;br /&gt;
 &lt;br /&gt;
 # Host of this machine&lt;br /&gt;
 ZM_SERVER_HOST=yourserver&lt;br /&gt;
&lt;br /&gt;
Change ownership of &amp;lt;code&amp;gt;zm.conf&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 chown lighttpd.lighttpd /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Zoneminder will create a cache in &amp;lt;code&amp;gt;/var/cache/zoneminder&amp;lt;/code&amp;gt; which isn&#039;t created by default. Create this directory and allow lighttpd access to it. Note that if you are using a diskless install, you must lbu add /var/cache/zoneminder.&lt;br /&gt;
&lt;br /&gt;
 mkdir /var/cache/zoneminder&lt;br /&gt;
 chown lighttpd.lighttpd /var/cache/zoneminder&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Initialize the ZoneMinder database&lt;br /&gt;
&lt;br /&gt;
 rc-service zoneminder setup&lt;br /&gt;
&lt;br /&gt;
Start ZoneMinder&lt;br /&gt;
&lt;br /&gt;
 rc-service zoneminder start&lt;br /&gt;
&lt;br /&gt;
Profit!&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
To access ZoneMinder, browse to &amp;lt;nowiki&amp;gt;http://yourserver/zm/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To test the API, run&lt;br /&gt;
 curl -X GET  &amp;lt;nowiki&amp;gt;http://yourserver/zm/api/host/getVersion.json&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
(This assumes you aren&#039;t using authentication.)&lt;br /&gt;
&lt;br /&gt;
To make it start automatically on boot:&lt;br /&gt;
&lt;br /&gt;
 rc-update add lighttpd default&lt;br /&gt;
 rc-update add mariadb default&lt;br /&gt;
 rc-update add php-fpm8 default&lt;br /&gt;
 rc-update add zoneminder default&lt;br /&gt;
&lt;br /&gt;
== Added notes to work with Nginx ==&lt;br /&gt;
Later to add some notes about running via nginx&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
You can enable debugging on lighttpd by uncommenting the debug options in /etc/lighttpd/lighttpd.conf (which in 3.20 were): &lt;br /&gt;
 debug.log-request-header   = &amp;quot;enable&amp;quot;&lt;br /&gt;
 debug.log-response-header  = &amp;quot;enable&amp;quot;&lt;br /&gt;
 debug.log-request-handling = &amp;quot;enable&amp;quot;&lt;br /&gt;
 debug.log-file-not-found   = &amp;quot;enable&amp;quot;&lt;br /&gt;
Note that since 3.14, mod_alias is now built into lighttpd and is not a module (.so file).&lt;br /&gt;
&lt;br /&gt;
For further troubleshooting, refer to the alpine build logs (https://pkgs.alpinelinux.org/package/v3.21/main/x86_64/lighttpd or https://pkgs.alpinelinux.org/package/v3.21/main/x86_64/zoneminder)  or alternatively, the lighttpd redmine wiki &amp;amp; forums. The ZoneMinder forum/discord/github issues tracker is also available for any errors related to ZoneMinder.&lt;br /&gt;
&lt;br /&gt;
[[Category:Software]]&lt;br /&gt;
[[Category:Security]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=28651</id>
		<title>ZoneMinder video camera security and surveillance</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=28651"/>
		<updated>2025-01-08T08:30:43Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* Added notes to work with Nginx */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://www.zoneminder.com/ ZoneMinder] usually runs with [[Apache]], but in this short how-to we use [[Lighttpd]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Base Install==&lt;br /&gt;
&lt;br /&gt;
ZoneMinder is found in the community repositories, please enable it by following the instructions [[Repositories#Enabling_the_community_repository|here]]&lt;br /&gt;
&lt;br /&gt;
Then, add the packages for zoneminder to our system&lt;br /&gt;
&lt;br /&gt;
 apk add zoneminder mariadb mysql-client lighttpd php-fpm php-pdo php-pdo_mysql php-intl php-session&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: You will need to adjust the above to use the appropriate php version. For example, in alpine 3.17 php 8.1 is used therefore you would enter php81-fpm. In alpine 3.20 php 8.3 is used so you would enter php83-fpm. You can look up the php version by typing apk search php and sorting through the results for your given release. This version suffix should be added to each php package.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Database===&lt;br /&gt;
&lt;br /&gt;
Initialize [https://www.mysql.com/ MySQL] database&lt;br /&gt;
&lt;br /&gt;
 rc-service mariadb setup&lt;br /&gt;
&lt;br /&gt;
Start the database&lt;br /&gt;
&lt;br /&gt;
 rc-service mariadb start&lt;br /&gt;
&lt;br /&gt;
Set root password for MySQL as instructed by MySQL setup&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mysqladmin -u root password &#039;your_secure_root_mysql_password&#039;&lt;br /&gt;
&lt;br /&gt;
You can log into MySQL as current root user with&lt;br /&gt;
 mysql&lt;br /&gt;
&lt;br /&gt;
Create a ZoneMinder MySQL database and user&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; create database zm;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; CREATE USER zmuser@localhost IDENTIFIED BY &#039;your_zm_password_as_set_in_config&#039;;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; grant ALL on zm.* to zmuser@localhost;&lt;br /&gt;
&lt;br /&gt;
===Web Server===&lt;br /&gt;
&lt;br /&gt;
We are running &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;, so let&#039;s run &amp;lt;code&amp;gt;php-fpm&amp;lt;/code&amp;gt; as lighttpd user/group&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php8/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: for php 8.1&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php81/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
Add this section to the bottom of the file:&lt;br /&gt;
&lt;br /&gt;
 ; Unix user/group of processes&lt;br /&gt;
 ; Note: The user is mandatory. If the group is not set, the default user&#039;s group&lt;br /&gt;
 ;       will be used.&lt;br /&gt;
 ;user = nobody&lt;br /&gt;
 ;group = nobody&lt;br /&gt;
 user = lighttpd&lt;br /&gt;
 group = lighttpd&lt;br /&gt;
&lt;br /&gt;
Enable the php cgi fpm config in &amp;lt;code&amp;gt;lighttpd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
Go down to the server modules section and uncomment &amp;lt;code&amp;gt;mod_alias&amp;lt;/code&amp;gt;, which is needed for the cgi-bin, and &amp;lt;code&amp;gt;mod_rewrite&amp;lt;/code&amp;gt;, for the api. It should look like:&lt;br /&gt;
&lt;br /&gt;
 # {{{ modules&lt;br /&gt;
 # At the very least, mod_access and mod_accesslog should be enabled.&lt;br /&gt;
 # All other modules should only be loaded if necessary.&lt;br /&gt;
 # NOTE: the order of modules is important.&lt;br /&gt;
 server.modules = (&lt;br /&gt;
      &amp;quot;mod_rewrite&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_redirect&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_alias&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_access&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_cml&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_trigger_b4_dl&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_auth&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_status&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_setenv&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_proxy&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_simple_vhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_evhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_userdir&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_deflate&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_ssi&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_usertrack&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_expire&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_secdownload&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_rrdtool&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_webdav&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_accesslog&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
Go down to the includes section, it should look like:&lt;br /&gt;
 # {{{ includes&lt;br /&gt;
 include &amp;quot;mime-types.conf&amp;quot;&lt;br /&gt;
 # uncomment for cgi support&lt;br /&gt;
    include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi support&lt;br /&gt;
 #   include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi fpm support&lt;br /&gt;
    include &amp;quot;mod_fastcgi_fpm.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
In order for video streaming to work in 1.36, you&#039;ll need the following&lt;br /&gt;
added to /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
 server.stream-response-body = 1&lt;br /&gt;
&lt;br /&gt;
In lighttpd.conf for the API, we will want to redirect any api+ requests to cakephp. Thus, add:&lt;br /&gt;
 url.rewrite = (&lt;br /&gt;
       &amp;quot;^/zm/api(.+)$&amp;quot;           =&amp;gt;              &amp;quot;/zm/api/index.php&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Edit lighttpd cgi config and add old style cgi support by adding to cgi.assign&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/mod_cgi.conf&lt;br /&gt;
&lt;br /&gt;
which should look like&lt;br /&gt;
&lt;br /&gt;
 cgi.assign = (&lt;br /&gt;
     &amp;quot;&amp;quot;      =&amp;gt;      &amp;quot;&amp;quot;,&lt;br /&gt;
     &amp;quot;.pl&amp;quot;   =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
     &amp;quot;.cgi&amp;quot;  =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Also add the following to alias.url in mod_cgi.conf so that it looks like&lt;br /&gt;
&lt;br /&gt;
 alias.url = (&lt;br /&gt;
     &amp;quot;/cgi-bin/&amp;quot;            =&amp;gt;      var.basedir + &amp;quot;/cgi-bin/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/api&amp;quot;              =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/api/app/webroot/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/&amp;quot;                 =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Remove the symlink in /var/www/localhost/htdocs (we will be using the alias, not the symlink). &lt;br /&gt;
 unlink /var/www/localhost/htdocs/zm&lt;br /&gt;
&lt;br /&gt;
Start php-fpm&lt;br /&gt;
&lt;br /&gt;
 rc-service php-fpm8 start&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; for php-fpm81, use the following command:&lt;br /&gt;
&lt;br /&gt;
 rc-service php-fpm81 start&lt;br /&gt;
&lt;br /&gt;
Start lighttpd&lt;br /&gt;
&lt;br /&gt;
 rc-service lighttpd start&lt;br /&gt;
&lt;br /&gt;
===Zoneminder===&lt;br /&gt;
&lt;br /&gt;
Set the MySQL hostname, username, password.&lt;br /&gt;
&lt;br /&gt;
Change the ZoneMinder user (&amp;lt;code&amp;gt;ZM_WEB_USER&amp;lt;/code&amp;gt;) and group (&amp;lt;code&amp;gt;ZM_WEB_GROUP&amp;lt;/code&amp;gt;) to lighttpd&lt;br /&gt;
&lt;br /&gt;
And set &amp;lt;code&amp;gt;ZM_SERVER_HOST&amp;lt;/code&amp;gt; to your ZoneMinder hostname/ipaddress&lt;br /&gt;
&lt;br /&gt;
 vi /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Which should look like:&lt;br /&gt;
&lt;br /&gt;
 # Username and group that web daemon (httpd/apache) runs as&lt;br /&gt;
 ZM_WEB_USER=lighttpd&lt;br /&gt;
 ZM_WEB_GROUP=lighttpd&lt;br /&gt;
 ZM_PATH_DATA=/usr/share/zoneminder&lt;br /&gt;
&lt;br /&gt;
 # ZoneMinder database type: so far only mysql is supported&lt;br /&gt;
 ZM_DB_TYPE=mysql&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database hostname or ip address&lt;br /&gt;
 ZM_DB_HOST=localhost&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database name&lt;br /&gt;
 ZM_DB_NAME=zm&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database user&lt;br /&gt;
 ZM_DB_USER=zmuser&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database password&lt;br /&gt;
 ZM_DB_PASS=your_zm_password_as_set_in_config&lt;br /&gt;
 &lt;br /&gt;
 # Host of this machine&lt;br /&gt;
 ZM_SERVER_HOST=yourserver&lt;br /&gt;
&lt;br /&gt;
Change ownership of &amp;lt;code&amp;gt;zm.conf&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 chown lighttpd.lighttpd /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Zoneminder will create a cache in &amp;lt;code&amp;gt;/var/cache/zoneminder&amp;lt;/code&amp;gt; which isn&#039;t created by default. Create this directory and allow lighttpd access to it. Note that if you are using a diskless install, you must lbu add /var/cache/zoneminder.&lt;br /&gt;
&lt;br /&gt;
 mkdir /var/cache/zoneminder&lt;br /&gt;
 chown lighttpd.lighttpd /var/cache/zoneminder&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Initialize the ZoneMinder database&lt;br /&gt;
&lt;br /&gt;
 rc-service zoneminder setup&lt;br /&gt;
&lt;br /&gt;
Start ZoneMinder&lt;br /&gt;
&lt;br /&gt;
 rc-service zoneminder start&lt;br /&gt;
&lt;br /&gt;
Profit!&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
To access ZoneMinder, browse to &amp;lt;nowiki&amp;gt;http://yourserver/zm/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To test the API, run&lt;br /&gt;
 curl -X GET  &amp;lt;nowiki&amp;gt;http://yourserver/zm/api/host/getVersion.json&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
(This assumes you aren&#039;t using authentication.)&lt;br /&gt;
&lt;br /&gt;
To make it start automatically on boot:&lt;br /&gt;
&lt;br /&gt;
 rc-update add lighttpd default&lt;br /&gt;
 rc-update add mariadb default&lt;br /&gt;
 rc-update add php-fpm8 default&lt;br /&gt;
 rc-update add zoneminder default&lt;br /&gt;
&lt;br /&gt;
== Added notes to work with Nginx ==&lt;br /&gt;
Later to add some notes about running via nginx&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
You can enable debugging on lighttpd by uncommenting the debug options in /etc/lighttpd/lighttpd.conf (which in 3.20 were):&lt;br /&gt;
 debug.log-request-header   = &amp;quot;enable&amp;quot;&lt;br /&gt;
 debug.log-response-header  = &amp;quot;enable&amp;quot;&lt;br /&gt;
 debug.log-request-handling = &amp;quot;enable&amp;quot;&lt;br /&gt;
 debug.log-file-not-found   = &amp;quot;enable&amp;quot;&lt;br /&gt;
Note that since 3.14, mod_alias is now built into lighttpd and is not a module (.so file).&lt;br /&gt;
&lt;br /&gt;
For further troubleshooting, refer to the alpine build logs (https://pkgs.alpinelinux.org/package/v3.21/main/x86_64/lighttpd or https://pkgs.alpinelinux.org/package/v3.21/main/x86_64/zoneminder)  or alternatively, the lighttpd redmine wiki &amp;amp; forums. The ZoneMinder forum/discord/github issues tracker is also available for any errors related to ZoneMinder.&lt;br /&gt;
&lt;br /&gt;
[[Category:Software]]&lt;br /&gt;
[[Category:Security]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=28650</id>
		<title>ZoneMinder video camera security and surveillance</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=28650"/>
		<updated>2025-01-08T08:26:14Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* Web Server */  Reverting change.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://www.zoneminder.com/ ZoneMinder] usually runs with [[Apache]], but in this short how-to we use [[Lighttpd]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Base Install==&lt;br /&gt;
&lt;br /&gt;
ZoneMinder is found in the community repositories, please enable it by following the instructions [[Repositories#Enabling_the_community_repository|here]]&lt;br /&gt;
&lt;br /&gt;
Then, add the packages for zoneminder to our system&lt;br /&gt;
&lt;br /&gt;
 apk add zoneminder mariadb mysql-client lighttpd php-fpm php-pdo php-pdo_mysql php-intl php-session&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: You will need to adjust the above to use the appropriate php version. For example, in alpine 3.17 php 8.1 is used therefore you would enter php81-fpm. In alpine 3.20 php 8.3 is used so you would enter php83-fpm. You can look up the php version by typing apk search php and sorting through the results for your given release. This version suffix should be added to each php package.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Database===&lt;br /&gt;
&lt;br /&gt;
Initialize [https://www.mysql.com/ MySQL] database&lt;br /&gt;
&lt;br /&gt;
 rc-service mariadb setup&lt;br /&gt;
&lt;br /&gt;
Start the database&lt;br /&gt;
&lt;br /&gt;
 rc-service mariadb start&lt;br /&gt;
&lt;br /&gt;
Set root password for MySQL as instructed by MySQL setup&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mysqladmin -u root password &#039;your_secure_root_mysql_password&#039;&lt;br /&gt;
&lt;br /&gt;
You can log into MySQL as current root user with&lt;br /&gt;
 mysql&lt;br /&gt;
&lt;br /&gt;
Create a ZoneMinder MySQL database and user&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; create database zm;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; CREATE USER zmuser@localhost IDENTIFIED BY &#039;your_zm_password_as_set_in_config&#039;;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; grant ALL on zm.* to zmuser@localhost;&lt;br /&gt;
&lt;br /&gt;
===Web Server===&lt;br /&gt;
&lt;br /&gt;
We are running &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;, so let&#039;s run &amp;lt;code&amp;gt;php-fpm&amp;lt;/code&amp;gt; as lighttpd user/group&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php8/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: for php 8.1&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php81/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
Add this section to the bottom of the file:&lt;br /&gt;
&lt;br /&gt;
 ; Unix user/group of processes&lt;br /&gt;
 ; Note: The user is mandatory. If the group is not set, the default user&#039;s group&lt;br /&gt;
 ;       will be used.&lt;br /&gt;
 ;user = nobody&lt;br /&gt;
 ;group = nobody&lt;br /&gt;
 user = lighttpd&lt;br /&gt;
 group = lighttpd&lt;br /&gt;
&lt;br /&gt;
Enable the php cgi fpm config in &amp;lt;code&amp;gt;lighttpd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
Go down to the server modules section and uncomment &amp;lt;code&amp;gt;mod_alias&amp;lt;/code&amp;gt;, which is needed for the cgi-bin, and &amp;lt;code&amp;gt;mod_rewrite&amp;lt;/code&amp;gt;, for the api. It should look like:&lt;br /&gt;
&lt;br /&gt;
 # {{{ modules&lt;br /&gt;
 # At the very least, mod_access and mod_accesslog should be enabled.&lt;br /&gt;
 # All other modules should only be loaded if necessary.&lt;br /&gt;
 # NOTE: the order of modules is important.&lt;br /&gt;
 server.modules = (&lt;br /&gt;
      &amp;quot;mod_rewrite&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_redirect&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_alias&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_access&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_cml&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_trigger_b4_dl&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_auth&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_status&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_setenv&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_proxy&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_simple_vhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_evhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_userdir&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_deflate&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_ssi&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_usertrack&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_expire&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_secdownload&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_rrdtool&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_webdav&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_accesslog&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
Go down to the includes section, it should look like:&lt;br /&gt;
 # {{{ includes&lt;br /&gt;
 include &amp;quot;mime-types.conf&amp;quot;&lt;br /&gt;
 # uncomment for cgi support&lt;br /&gt;
    include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi support&lt;br /&gt;
 #   include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi fpm support&lt;br /&gt;
    include &amp;quot;mod_fastcgi_fpm.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
In order for video streaming to work in 1.36, you&#039;ll need the following&lt;br /&gt;
added to /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
 server.stream-response-body = 1&lt;br /&gt;
&lt;br /&gt;
In lighttpd.conf for the API, we will want to redirect any api+ requests to cakephp. Thus, add:&lt;br /&gt;
 url.rewrite = (&lt;br /&gt;
       &amp;quot;^/zm/api(.+)$&amp;quot;           =&amp;gt;              &amp;quot;/zm/api/index.php&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Edit lighttpd cgi config and add old style cgi support by adding to cgi.assign&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/mod_cgi.conf&lt;br /&gt;
&lt;br /&gt;
which should look like&lt;br /&gt;
&lt;br /&gt;
 cgi.assign = (&lt;br /&gt;
     &amp;quot;&amp;quot;      =&amp;gt;      &amp;quot;&amp;quot;,&lt;br /&gt;
     &amp;quot;.pl&amp;quot;   =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
     &amp;quot;.cgi&amp;quot;  =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Also add the following to alias.url in mod_cgi.conf so that it looks like&lt;br /&gt;
&lt;br /&gt;
 alias.url = (&lt;br /&gt;
     &amp;quot;/cgi-bin/&amp;quot;            =&amp;gt;      var.basedir + &amp;quot;/cgi-bin/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/api&amp;quot;              =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/api/app/webroot/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/&amp;quot;                 =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Remove the symlink in /var/www/localhost/htdocs (we will be using the alias, not the symlink). &lt;br /&gt;
 unlink /var/www/localhost/htdocs/zm&lt;br /&gt;
&lt;br /&gt;
Start php-fpm&lt;br /&gt;
&lt;br /&gt;
 rc-service php-fpm8 start&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; for php-fpm81, use the following command:&lt;br /&gt;
&lt;br /&gt;
 rc-service php-fpm81 start&lt;br /&gt;
&lt;br /&gt;
Start lighttpd&lt;br /&gt;
&lt;br /&gt;
 rc-service lighttpd start&lt;br /&gt;
&lt;br /&gt;
===Zoneminder===&lt;br /&gt;
&lt;br /&gt;
Set the MySQL hostname, username, password.&lt;br /&gt;
&lt;br /&gt;
Change the ZoneMinder user (&amp;lt;code&amp;gt;ZM_WEB_USER&amp;lt;/code&amp;gt;) and group (&amp;lt;code&amp;gt;ZM_WEB_GROUP&amp;lt;/code&amp;gt;) to lighttpd&lt;br /&gt;
&lt;br /&gt;
And set &amp;lt;code&amp;gt;ZM_SERVER_HOST&amp;lt;/code&amp;gt; to your ZoneMinder hostname/ipaddress&lt;br /&gt;
&lt;br /&gt;
 vi /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Which should look like:&lt;br /&gt;
&lt;br /&gt;
 # Username and group that web daemon (httpd/apache) runs as&lt;br /&gt;
 ZM_WEB_USER=lighttpd&lt;br /&gt;
 ZM_WEB_GROUP=lighttpd&lt;br /&gt;
 ZM_PATH_DATA=/usr/share/zoneminder&lt;br /&gt;
&lt;br /&gt;
 # ZoneMinder database type: so far only mysql is supported&lt;br /&gt;
 ZM_DB_TYPE=mysql&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database hostname or ip address&lt;br /&gt;
 ZM_DB_HOST=localhost&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database name&lt;br /&gt;
 ZM_DB_NAME=zm&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database user&lt;br /&gt;
 ZM_DB_USER=zmuser&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database password&lt;br /&gt;
 ZM_DB_PASS=your_zm_password_as_set_in_config&lt;br /&gt;
 &lt;br /&gt;
 # Host of this machine&lt;br /&gt;
 ZM_SERVER_HOST=yourserver&lt;br /&gt;
&lt;br /&gt;
Change ownership of &amp;lt;code&amp;gt;zm.conf&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 chown lighttpd.lighttpd /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Zoneminder will create a cache in &amp;lt;code&amp;gt;/var/cache/zoneminder&amp;lt;/code&amp;gt; which isn&#039;t created by default. Create this directory and allow lighttpd access to it. Note that if you are using a diskless install, you must lbu add /var/cache/zoneminder.&lt;br /&gt;
&lt;br /&gt;
 mkdir /var/cache/zoneminder&lt;br /&gt;
 chown lighttpd.lighttpd /var/cache/zoneminder&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Initialize the ZoneMinder database&lt;br /&gt;
&lt;br /&gt;
 rc-service zoneminder setup&lt;br /&gt;
&lt;br /&gt;
Start ZoneMinder&lt;br /&gt;
&lt;br /&gt;
 rc-service zoneminder start&lt;br /&gt;
&lt;br /&gt;
Profit!&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
To access ZoneMinder, browse to &amp;lt;nowiki&amp;gt;http://yourserver/zm/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To test the API, run&lt;br /&gt;
 curl -X GET  &amp;lt;nowiki&amp;gt;http://yourserver/zm/api/host/getVersion.json&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
(This assumes you aren&#039;t using authentication.)&lt;br /&gt;
&lt;br /&gt;
To make it start automatically on boot:&lt;br /&gt;
&lt;br /&gt;
 rc-update add lighttpd default&lt;br /&gt;
 rc-update add mariadb default&lt;br /&gt;
 rc-update add php-fpm8 default&lt;br /&gt;
 rc-update add zoneminder default&lt;br /&gt;
&lt;br /&gt;
== Added notes to work with Nginx ==&lt;br /&gt;
Later to add some notes about running via nginx&lt;br /&gt;
&lt;br /&gt;
[[Category:Software]]&lt;br /&gt;
[[Category:Security]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=28649</id>
		<title>ZoneMinder video camera security and surveillance</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=28649"/>
		<updated>2025-01-08T08:25:44Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* Web Server */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://www.zoneminder.com/ ZoneMinder] usually runs with [[Apache]], but in this short how-to we use [[Lighttpd]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Base Install==&lt;br /&gt;
&lt;br /&gt;
ZoneMinder is found in the community repositories, please enable it by following the instructions [[Repositories#Enabling_the_community_repository|here]]&lt;br /&gt;
&lt;br /&gt;
Then, add the packages for zoneminder to our system&lt;br /&gt;
&lt;br /&gt;
 apk add zoneminder mariadb mysql-client lighttpd php-fpm php-pdo php-pdo_mysql php-intl php-session&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: You will need to adjust the above to use the appropriate php version. For example, in alpine 3.17 php 8.1 is used therefore you would enter php81-fpm. In alpine 3.20 php 8.3 is used so you would enter php83-fpm. You can look up the php version by typing apk search php and sorting through the results for your given release. This version suffix should be added to each php package.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Database===&lt;br /&gt;
&lt;br /&gt;
Initialize [https://www.mysql.com/ MySQL] database&lt;br /&gt;
&lt;br /&gt;
 rc-service mariadb setup&lt;br /&gt;
&lt;br /&gt;
Start the database&lt;br /&gt;
&lt;br /&gt;
 rc-service mariadb start&lt;br /&gt;
&lt;br /&gt;
Set root password for MySQL as instructed by MySQL setup&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mysqladmin -u root password &#039;your_secure_root_mysql_password&#039;&lt;br /&gt;
&lt;br /&gt;
You can log into MySQL as current root user with&lt;br /&gt;
 mysql&lt;br /&gt;
&lt;br /&gt;
Create a ZoneMinder MySQL database and user&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; create database zm;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; CREATE USER zmuser@localhost IDENTIFIED BY &#039;your_zm_password_as_set_in_config&#039;;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; grant ALL on zm.* to zmuser@localhost;&lt;br /&gt;
&lt;br /&gt;
===Web Server===&lt;br /&gt;
&lt;br /&gt;
We are running &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;, so let&#039;s run &amp;lt;code&amp;gt;php-fpm&amp;lt;/code&amp;gt; as lighttpd user/group&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php8/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: for php 8.3&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php83/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
Add this section to the bottom of the file:&lt;br /&gt;
&lt;br /&gt;
 ; Unix user/group of processes&lt;br /&gt;
 ; Note: The user is mandatory. If the group is not set, the default user&#039;s group&lt;br /&gt;
 ;       will be used.&lt;br /&gt;
 ;user = nobody&lt;br /&gt;
 ;group = nobody&lt;br /&gt;
 user = lighttpd&lt;br /&gt;
 group = lighttpd&lt;br /&gt;
&lt;br /&gt;
Enable the php cgi fpm config in &amp;lt;code&amp;gt;lighttpd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
Go down to the server modules section and uncomment &amp;lt;code&amp;gt;mod_alias&amp;lt;/code&amp;gt;, which is needed for the cgi-bin, and &amp;lt;code&amp;gt;mod_rewrite&amp;lt;/code&amp;gt;, for the api. It should look like:&lt;br /&gt;
&lt;br /&gt;
 # {{{ modules&lt;br /&gt;
 # At the very least, mod_access and mod_accesslog should be enabled.&lt;br /&gt;
 # All other modules should only be loaded if necessary.&lt;br /&gt;
 # NOTE: the order of modules is important.&lt;br /&gt;
 server.modules = (&lt;br /&gt;
      &amp;quot;mod_rewrite&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_redirect&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_alias&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_access&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_cml&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_trigger_b4_dl&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_auth&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_status&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_setenv&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_proxy&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_simple_vhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_evhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_userdir&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_deflate&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_ssi&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_usertrack&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_expire&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_secdownload&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_rrdtool&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_webdav&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_accesslog&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
Go down to the includes section, it should look like:&lt;br /&gt;
 # {{{ includes&lt;br /&gt;
 include &amp;quot;mime-types.conf&amp;quot;&lt;br /&gt;
 # uncomment for cgi support&lt;br /&gt;
    include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi support&lt;br /&gt;
 #   include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi fpm support&lt;br /&gt;
    include &amp;quot;mod_fastcgi_fpm.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
In order for video streaming to work in 1.36, you&#039;ll need the following&lt;br /&gt;
added to /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
 server.stream-response-body = 1&lt;br /&gt;
&lt;br /&gt;
In lighttpd.conf for the API, we will want to redirect any api+ requests to cakephp. Thus, add:&lt;br /&gt;
 url.rewrite = (&lt;br /&gt;
       &amp;quot;^/zm/api(.+)$&amp;quot;           =&amp;gt;              &amp;quot;/zm/api/index.php&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Edit lighttpd cgi config and add old style cgi support by adding to cgi.assign&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/mod_cgi.conf&lt;br /&gt;
&lt;br /&gt;
which should look like&lt;br /&gt;
&lt;br /&gt;
 cgi.assign = (&lt;br /&gt;
     &amp;quot;&amp;quot;      =&amp;gt;      &amp;quot;&amp;quot;,&lt;br /&gt;
     &amp;quot;.pl&amp;quot;   =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
     &amp;quot;.cgi&amp;quot;  =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Also add the following to alias.url in mod_cgi.conf so that it looks like&lt;br /&gt;
&lt;br /&gt;
 alias.url = (&lt;br /&gt;
     &amp;quot;/cgi-bin/&amp;quot;            =&amp;gt;      var.basedir + &amp;quot;/cgi-bin/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/api&amp;quot;              =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/api/app/webroot/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/&amp;quot;                 =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Remove the symlink in /var/www/localhost/htdocs (we will be using the alias, not the symlink). &lt;br /&gt;
 unlink /var/www/localhost/htdocs/zm&lt;br /&gt;
&lt;br /&gt;
Start php-fpm&lt;br /&gt;
&lt;br /&gt;
 rc-service php-fpm8 start&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; for php-fpm81, use the following command:&lt;br /&gt;
&lt;br /&gt;
 rc-service php-fpm81 start&lt;br /&gt;
&lt;br /&gt;
Start lighttpd&lt;br /&gt;
&lt;br /&gt;
 rc-service lighttpd start&lt;br /&gt;
&lt;br /&gt;
===Zoneminder===&lt;br /&gt;
&lt;br /&gt;
Set the MySQL hostname, username, password.&lt;br /&gt;
&lt;br /&gt;
Change the ZoneMinder user (&amp;lt;code&amp;gt;ZM_WEB_USER&amp;lt;/code&amp;gt;) and group (&amp;lt;code&amp;gt;ZM_WEB_GROUP&amp;lt;/code&amp;gt;) to lighttpd&lt;br /&gt;
&lt;br /&gt;
And set &amp;lt;code&amp;gt;ZM_SERVER_HOST&amp;lt;/code&amp;gt; to your ZoneMinder hostname/ipaddress&lt;br /&gt;
&lt;br /&gt;
 vi /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Which should look like:&lt;br /&gt;
&lt;br /&gt;
 # Username and group that web daemon (httpd/apache) runs as&lt;br /&gt;
 ZM_WEB_USER=lighttpd&lt;br /&gt;
 ZM_WEB_GROUP=lighttpd&lt;br /&gt;
 ZM_PATH_DATA=/usr/share/zoneminder&lt;br /&gt;
&lt;br /&gt;
 # ZoneMinder database type: so far only mysql is supported&lt;br /&gt;
 ZM_DB_TYPE=mysql&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database hostname or ip address&lt;br /&gt;
 ZM_DB_HOST=localhost&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database name&lt;br /&gt;
 ZM_DB_NAME=zm&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database user&lt;br /&gt;
 ZM_DB_USER=zmuser&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database password&lt;br /&gt;
 ZM_DB_PASS=your_zm_password_as_set_in_config&lt;br /&gt;
 &lt;br /&gt;
 # Host of this machine&lt;br /&gt;
 ZM_SERVER_HOST=yourserver&lt;br /&gt;
&lt;br /&gt;
Change ownership of &amp;lt;code&amp;gt;zm.conf&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 chown lighttpd.lighttpd /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Zoneminder will create a cache in &amp;lt;code&amp;gt;/var/cache/zoneminder&amp;lt;/code&amp;gt; which isn&#039;t created by default. Create this directory and allow lighttpd access to it. Note that if you are using a diskless install, you must lbu add /var/cache/zoneminder.&lt;br /&gt;
&lt;br /&gt;
 mkdir /var/cache/zoneminder&lt;br /&gt;
 chown lighttpd.lighttpd /var/cache/zoneminder&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Initialize the ZoneMinder database&lt;br /&gt;
&lt;br /&gt;
 rc-service zoneminder setup&lt;br /&gt;
&lt;br /&gt;
Start ZoneMinder&lt;br /&gt;
&lt;br /&gt;
 rc-service zoneminder start&lt;br /&gt;
&lt;br /&gt;
Profit!&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
To access ZoneMinder, browse to &amp;lt;nowiki&amp;gt;http://yourserver/zm/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To test the API, run&lt;br /&gt;
 curl -X GET  &amp;lt;nowiki&amp;gt;http://yourserver/zm/api/host/getVersion.json&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
(This assumes you aren&#039;t using authentication.)&lt;br /&gt;
&lt;br /&gt;
To make it start automatically on boot:&lt;br /&gt;
&lt;br /&gt;
 rc-update add lighttpd default&lt;br /&gt;
 rc-update add mariadb default&lt;br /&gt;
 rc-update add php-fpm8 default&lt;br /&gt;
 rc-update add zoneminder default&lt;br /&gt;
&lt;br /&gt;
== Added notes to work with Nginx ==&lt;br /&gt;
Later to add some notes about running via nginx&lt;br /&gt;
&lt;br /&gt;
[[Category:Software]]&lt;br /&gt;
[[Category:Security]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=28648</id>
		<title>ZoneMinder video camera security and surveillance</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=28648"/>
		<updated>2025-01-08T08:25:02Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* Base Install */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://www.zoneminder.com/ ZoneMinder] usually runs with [[Apache]], but in this short how-to we use [[Lighttpd]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Base Install==&lt;br /&gt;
&lt;br /&gt;
ZoneMinder is found in the community repositories, please enable it by following the instructions [[Repositories#Enabling_the_community_repository|here]]&lt;br /&gt;
&lt;br /&gt;
Then, add the packages for zoneminder to our system&lt;br /&gt;
&lt;br /&gt;
 apk add zoneminder mariadb mysql-client lighttpd php-fpm php-pdo php-pdo_mysql php-intl php-session&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: You will need to adjust the above to use the appropriate php version. For example, in alpine 3.17 php 8.1 is used therefore you would enter php81-fpm. In alpine 3.20 php 8.3 is used so you would enter php83-fpm. You can look up the php version by typing apk search php and sorting through the results for your given release. This version suffix should be added to each php package.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Database===&lt;br /&gt;
&lt;br /&gt;
Initialize [https://www.mysql.com/ MySQL] database&lt;br /&gt;
&lt;br /&gt;
 rc-service mariadb setup&lt;br /&gt;
&lt;br /&gt;
Start the database&lt;br /&gt;
&lt;br /&gt;
 rc-service mariadb start&lt;br /&gt;
&lt;br /&gt;
Set root password for MySQL as instructed by MySQL setup&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mysqladmin -u root password &#039;your_secure_root_mysql_password&#039;&lt;br /&gt;
&lt;br /&gt;
You can log into MySQL as current root user with&lt;br /&gt;
 mysql&lt;br /&gt;
&lt;br /&gt;
Create a ZoneMinder MySQL database and user&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; create database zm;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; CREATE USER zmuser@localhost IDENTIFIED BY &#039;your_zm_password_as_set_in_config&#039;;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; grant ALL on zm.* to zmuser@localhost;&lt;br /&gt;
&lt;br /&gt;
===Web Server===&lt;br /&gt;
&lt;br /&gt;
We are running &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;, so let&#039;s run &amp;lt;code&amp;gt;php-fpm&amp;lt;/code&amp;gt; as lighttpd user/group&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php8/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: for php 8.1&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php81/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
Add this section to the bottom of the file:&lt;br /&gt;
&lt;br /&gt;
 ; Unix user/group of processes&lt;br /&gt;
 ; Note: The user is mandatory. If the group is not set, the default user&#039;s group&lt;br /&gt;
 ;       will be used.&lt;br /&gt;
 ;user = nobody&lt;br /&gt;
 ;group = nobody&lt;br /&gt;
 user = lighttpd&lt;br /&gt;
 group = lighttpd&lt;br /&gt;
&lt;br /&gt;
Enable the php cgi fpm config in &amp;lt;code&amp;gt;lighttpd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
Go down to the server modules section and uncomment &amp;lt;code&amp;gt;mod_alias&amp;lt;/code&amp;gt;, which is needed for the cgi-bin, and &amp;lt;code&amp;gt;mod_rewrite&amp;lt;/code&amp;gt;, for the api. It should look like:&lt;br /&gt;
&lt;br /&gt;
 # {{{ modules&lt;br /&gt;
 # At the very least, mod_access and mod_accesslog should be enabled.&lt;br /&gt;
 # All other modules should only be loaded if necessary.&lt;br /&gt;
 # NOTE: the order of modules is important.&lt;br /&gt;
 server.modules = (&lt;br /&gt;
      &amp;quot;mod_rewrite&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_redirect&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_alias&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_access&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_cml&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_trigger_b4_dl&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_auth&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_status&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_setenv&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_proxy&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_simple_vhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_evhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_userdir&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_deflate&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_ssi&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_usertrack&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_expire&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_secdownload&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_rrdtool&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_webdav&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_accesslog&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
Go down to the includes section, it should look like:&lt;br /&gt;
 # {{{ includes&lt;br /&gt;
 include &amp;quot;mime-types.conf&amp;quot;&lt;br /&gt;
 # uncomment for cgi support&lt;br /&gt;
    include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi support&lt;br /&gt;
 #   include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi fpm support&lt;br /&gt;
    include &amp;quot;mod_fastcgi_fpm.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
In order for video streaming to work in 1.36, you&#039;ll need the following&lt;br /&gt;
added to /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
 server.stream-response-body = 1&lt;br /&gt;
&lt;br /&gt;
In lighttpd.conf for the API, we will want to redirect any api+ requests to cakephp. Thus, add:&lt;br /&gt;
 url.rewrite = (&lt;br /&gt;
       &amp;quot;^/zm/api(.+)$&amp;quot;           =&amp;gt;              &amp;quot;/zm/api/index.php&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Edit lighttpd cgi config and add old style cgi support by adding to cgi.assign&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/mod_cgi.conf&lt;br /&gt;
&lt;br /&gt;
which should look like&lt;br /&gt;
&lt;br /&gt;
 cgi.assign = (&lt;br /&gt;
     &amp;quot;&amp;quot;      =&amp;gt;      &amp;quot;&amp;quot;,&lt;br /&gt;
     &amp;quot;.pl&amp;quot;   =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
     &amp;quot;.cgi&amp;quot;  =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Also add the following to alias.url in mod_cgi.conf so that it looks like&lt;br /&gt;
&lt;br /&gt;
 alias.url = (&lt;br /&gt;
     &amp;quot;/cgi-bin/&amp;quot;            =&amp;gt;      var.basedir + &amp;quot;/cgi-bin/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/api&amp;quot;              =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/api/app/webroot/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/&amp;quot;                 =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Remove the symlink in /var/www/localhost/htdocs (we will be using the alias, not the symlink). &lt;br /&gt;
 unlink /var/www/localhost/htdocs/zm&lt;br /&gt;
&lt;br /&gt;
Start php-fpm&lt;br /&gt;
&lt;br /&gt;
 rc-service php-fpm8 start&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; for php-fpm81, use the following command:&lt;br /&gt;
&lt;br /&gt;
 rc-service php-fpm81 start&lt;br /&gt;
&lt;br /&gt;
Start lighttpd&lt;br /&gt;
&lt;br /&gt;
 rc-service lighttpd start&lt;br /&gt;
&lt;br /&gt;
===Zoneminder===&lt;br /&gt;
&lt;br /&gt;
Set the MySQL hostname, username, password.&lt;br /&gt;
&lt;br /&gt;
Change the ZoneMinder user (&amp;lt;code&amp;gt;ZM_WEB_USER&amp;lt;/code&amp;gt;) and group (&amp;lt;code&amp;gt;ZM_WEB_GROUP&amp;lt;/code&amp;gt;) to lighttpd&lt;br /&gt;
&lt;br /&gt;
And set &amp;lt;code&amp;gt;ZM_SERVER_HOST&amp;lt;/code&amp;gt; to your ZoneMinder hostname/ipaddress&lt;br /&gt;
&lt;br /&gt;
 vi /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Which should look like:&lt;br /&gt;
&lt;br /&gt;
 # Username and group that web daemon (httpd/apache) runs as&lt;br /&gt;
 ZM_WEB_USER=lighttpd&lt;br /&gt;
 ZM_WEB_GROUP=lighttpd&lt;br /&gt;
 ZM_PATH_DATA=/usr/share/zoneminder&lt;br /&gt;
&lt;br /&gt;
 # ZoneMinder database type: so far only mysql is supported&lt;br /&gt;
 ZM_DB_TYPE=mysql&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database hostname or ip address&lt;br /&gt;
 ZM_DB_HOST=localhost&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database name&lt;br /&gt;
 ZM_DB_NAME=zm&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database user&lt;br /&gt;
 ZM_DB_USER=zmuser&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database password&lt;br /&gt;
 ZM_DB_PASS=your_zm_password_as_set_in_config&lt;br /&gt;
 &lt;br /&gt;
 # Host of this machine&lt;br /&gt;
 ZM_SERVER_HOST=yourserver&lt;br /&gt;
&lt;br /&gt;
Change ownership of &amp;lt;code&amp;gt;zm.conf&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 chown lighttpd.lighttpd /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Zoneminder will create a cache in &amp;lt;code&amp;gt;/var/cache/zoneminder&amp;lt;/code&amp;gt; which isn&#039;t created by default. Create this directory and allow lighttpd access to it. Note that if you are using a diskless install, you must lbu add /var/cache/zoneminder.&lt;br /&gt;
&lt;br /&gt;
 mkdir /var/cache/zoneminder&lt;br /&gt;
 chown lighttpd.lighttpd /var/cache/zoneminder&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Initialize the ZoneMinder database&lt;br /&gt;
&lt;br /&gt;
 rc-service zoneminder setup&lt;br /&gt;
&lt;br /&gt;
Start ZoneMinder&lt;br /&gt;
&lt;br /&gt;
 rc-service zoneminder start&lt;br /&gt;
&lt;br /&gt;
Profit!&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
To access ZoneMinder, browse to &amp;lt;nowiki&amp;gt;http://yourserver/zm/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To test the API, run&lt;br /&gt;
 curl -X GET  &amp;lt;nowiki&amp;gt;http://yourserver/zm/api/host/getVersion.json&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
(This assumes you aren&#039;t using authentication.)&lt;br /&gt;
&lt;br /&gt;
To make it start automatically on boot:&lt;br /&gt;
&lt;br /&gt;
 rc-update add lighttpd default&lt;br /&gt;
 rc-update add mariadb default&lt;br /&gt;
 rc-update add php-fpm8 default&lt;br /&gt;
 rc-update add zoneminder default&lt;br /&gt;
&lt;br /&gt;
== Added notes to work with Nginx ==&lt;br /&gt;
Later to add some notes about running via nginx&lt;br /&gt;
&lt;br /&gt;
[[Category:Software]]&lt;br /&gt;
[[Category:Security]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=28647</id>
		<title>ZoneMinder video camera security and surveillance</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=28647"/>
		<updated>2025-01-08T08:24:27Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* Base Install */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://www.zoneminder.com/ ZoneMinder] usually runs with [[Apache]], but in this short how-to we use [[Lighttpd]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Base Install==&lt;br /&gt;
&lt;br /&gt;
ZoneMinder is found in the community repositories, please enable it by following the instructions [[Repositories#Enabling_the_community_repository|here]]&lt;br /&gt;
&lt;br /&gt;
Then, add the packages for zoneminder to our system&lt;br /&gt;
&lt;br /&gt;
 apk add zoneminder mariadb mysql-client lighttpd php-fpm php-pdo php-pdo_mysql php-intl php-session&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: You will need to adjust the above to use the appropriate php version. For example, in alpine 3.17 php 8.1 is used therefore you would enter php81-fpm. In alpine 3.20 php 8.3 is used so you would enter php83-fpm. You can look up the php version by typing apk search php and sorting through the results for your given release.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Database===&lt;br /&gt;
&lt;br /&gt;
Initialize [https://www.mysql.com/ MySQL] database&lt;br /&gt;
&lt;br /&gt;
 rc-service mariadb setup&lt;br /&gt;
&lt;br /&gt;
Start the database&lt;br /&gt;
&lt;br /&gt;
 rc-service mariadb start&lt;br /&gt;
&lt;br /&gt;
Set root password for MySQL as instructed by MySQL setup&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mysqladmin -u root password &#039;your_secure_root_mysql_password&#039;&lt;br /&gt;
&lt;br /&gt;
You can log into MySQL as current root user with&lt;br /&gt;
 mysql&lt;br /&gt;
&lt;br /&gt;
Create a ZoneMinder MySQL database and user&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; create database zm;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; CREATE USER zmuser@localhost IDENTIFIED BY &#039;your_zm_password_as_set_in_config&#039;;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; grant ALL on zm.* to zmuser@localhost;&lt;br /&gt;
&lt;br /&gt;
===Web Server===&lt;br /&gt;
&lt;br /&gt;
We are running &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;, so let&#039;s run &amp;lt;code&amp;gt;php-fpm&amp;lt;/code&amp;gt; as lighttpd user/group&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php8/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: for php 8.1&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php81/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
Add this section to the bottom of the file:&lt;br /&gt;
&lt;br /&gt;
 ; Unix user/group of processes&lt;br /&gt;
 ; Note: The user is mandatory. If the group is not set, the default user&#039;s group&lt;br /&gt;
 ;       will be used.&lt;br /&gt;
 ;user = nobody&lt;br /&gt;
 ;group = nobody&lt;br /&gt;
 user = lighttpd&lt;br /&gt;
 group = lighttpd&lt;br /&gt;
&lt;br /&gt;
Enable the php cgi fpm config in &amp;lt;code&amp;gt;lighttpd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
Go down to the server modules section and uncomment &amp;lt;code&amp;gt;mod_alias&amp;lt;/code&amp;gt;, which is needed for the cgi-bin, and &amp;lt;code&amp;gt;mod_rewrite&amp;lt;/code&amp;gt;, for the api. It should look like:&lt;br /&gt;
&lt;br /&gt;
 # {{{ modules&lt;br /&gt;
 # At the very least, mod_access and mod_accesslog should be enabled.&lt;br /&gt;
 # All other modules should only be loaded if necessary.&lt;br /&gt;
 # NOTE: the order of modules is important.&lt;br /&gt;
 server.modules = (&lt;br /&gt;
      &amp;quot;mod_rewrite&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_redirect&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_alias&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_access&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_cml&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_trigger_b4_dl&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_auth&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_status&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_setenv&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_proxy&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_simple_vhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_evhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_userdir&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_deflate&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_ssi&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_usertrack&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_expire&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_secdownload&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_rrdtool&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_webdav&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_accesslog&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
Go down to the includes section, it should look like:&lt;br /&gt;
 # {{{ includes&lt;br /&gt;
 include &amp;quot;mime-types.conf&amp;quot;&lt;br /&gt;
 # uncomment for cgi support&lt;br /&gt;
    include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi support&lt;br /&gt;
 #   include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi fpm support&lt;br /&gt;
    include &amp;quot;mod_fastcgi_fpm.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
In order for video streaming to work in 1.36, you&#039;ll need the following&lt;br /&gt;
added to /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
 server.stream-response-body = 1&lt;br /&gt;
&lt;br /&gt;
In lighttpd.conf for the API, we will want to redirect any api+ requests to cakephp. Thus, add:&lt;br /&gt;
 url.rewrite = (&lt;br /&gt;
       &amp;quot;^/zm/api(.+)$&amp;quot;           =&amp;gt;              &amp;quot;/zm/api/index.php&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Edit lighttpd cgi config and add old style cgi support by adding to cgi.assign&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/mod_cgi.conf&lt;br /&gt;
&lt;br /&gt;
which should look like&lt;br /&gt;
&lt;br /&gt;
 cgi.assign = (&lt;br /&gt;
     &amp;quot;&amp;quot;      =&amp;gt;      &amp;quot;&amp;quot;,&lt;br /&gt;
     &amp;quot;.pl&amp;quot;   =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
     &amp;quot;.cgi&amp;quot;  =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Also add the following to alias.url in mod_cgi.conf so that it looks like&lt;br /&gt;
&lt;br /&gt;
 alias.url = (&lt;br /&gt;
     &amp;quot;/cgi-bin/&amp;quot;            =&amp;gt;      var.basedir + &amp;quot;/cgi-bin/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/api&amp;quot;              =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/api/app/webroot/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/&amp;quot;                 =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Remove the symlink in /var/www/localhost/htdocs (we will be using the alias, not the symlink). &lt;br /&gt;
 unlink /var/www/localhost/htdocs/zm&lt;br /&gt;
&lt;br /&gt;
Start php-fpm&lt;br /&gt;
&lt;br /&gt;
 rc-service php-fpm8 start&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; for php-fpm81, use the following command:&lt;br /&gt;
&lt;br /&gt;
 rc-service php-fpm81 start&lt;br /&gt;
&lt;br /&gt;
Start lighttpd&lt;br /&gt;
&lt;br /&gt;
 rc-service lighttpd start&lt;br /&gt;
&lt;br /&gt;
===Zoneminder===&lt;br /&gt;
&lt;br /&gt;
Set the MySQL hostname, username, password.&lt;br /&gt;
&lt;br /&gt;
Change the ZoneMinder user (&amp;lt;code&amp;gt;ZM_WEB_USER&amp;lt;/code&amp;gt;) and group (&amp;lt;code&amp;gt;ZM_WEB_GROUP&amp;lt;/code&amp;gt;) to lighttpd&lt;br /&gt;
&lt;br /&gt;
And set &amp;lt;code&amp;gt;ZM_SERVER_HOST&amp;lt;/code&amp;gt; to your ZoneMinder hostname/ipaddress&lt;br /&gt;
&lt;br /&gt;
 vi /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Which should look like:&lt;br /&gt;
&lt;br /&gt;
 # Username and group that web daemon (httpd/apache) runs as&lt;br /&gt;
 ZM_WEB_USER=lighttpd&lt;br /&gt;
 ZM_WEB_GROUP=lighttpd&lt;br /&gt;
 ZM_PATH_DATA=/usr/share/zoneminder&lt;br /&gt;
&lt;br /&gt;
 # ZoneMinder database type: so far only mysql is supported&lt;br /&gt;
 ZM_DB_TYPE=mysql&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database hostname or ip address&lt;br /&gt;
 ZM_DB_HOST=localhost&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database name&lt;br /&gt;
 ZM_DB_NAME=zm&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database user&lt;br /&gt;
 ZM_DB_USER=zmuser&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database password&lt;br /&gt;
 ZM_DB_PASS=your_zm_password_as_set_in_config&lt;br /&gt;
 &lt;br /&gt;
 # Host of this machine&lt;br /&gt;
 ZM_SERVER_HOST=yourserver&lt;br /&gt;
&lt;br /&gt;
Change ownership of &amp;lt;code&amp;gt;zm.conf&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 chown lighttpd.lighttpd /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Zoneminder will create a cache in &amp;lt;code&amp;gt;/var/cache/zoneminder&amp;lt;/code&amp;gt; which isn&#039;t created by default. Create this directory and allow lighttpd access to it. Note that if you are using a diskless install, you must lbu add /var/cache/zoneminder.&lt;br /&gt;
&lt;br /&gt;
 mkdir /var/cache/zoneminder&lt;br /&gt;
 chown lighttpd.lighttpd /var/cache/zoneminder&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Initialize the ZoneMinder database&lt;br /&gt;
&lt;br /&gt;
 rc-service zoneminder setup&lt;br /&gt;
&lt;br /&gt;
Start ZoneMinder&lt;br /&gt;
&lt;br /&gt;
 rc-service zoneminder start&lt;br /&gt;
&lt;br /&gt;
Profit!&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
To access ZoneMinder, browse to &amp;lt;nowiki&amp;gt;http://yourserver/zm/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To test the API, run&lt;br /&gt;
 curl -X GET  &amp;lt;nowiki&amp;gt;http://yourserver/zm/api/host/getVersion.json&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
(This assumes you aren&#039;t using authentication.)&lt;br /&gt;
&lt;br /&gt;
To make it start automatically on boot:&lt;br /&gt;
&lt;br /&gt;
 rc-update add lighttpd default&lt;br /&gt;
 rc-update add mariadb default&lt;br /&gt;
 rc-update add php-fpm8 default&lt;br /&gt;
 rc-update add zoneminder default&lt;br /&gt;
&lt;br /&gt;
== Added notes to work with Nginx ==&lt;br /&gt;
Later to add some notes about running via nginx&lt;br /&gt;
&lt;br /&gt;
[[Category:Software]]&lt;br /&gt;
[[Category:Security]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=27817</id>
		<title>Raspberry Pi 3 - Browser Client</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=27817"/>
		<updated>2024-11-15T08:52:02Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;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.&lt;br /&gt;
&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
Note that this guide started out with an RPI3, has been used with x86, and currently runs with an RPI4, though the guide hasn&#039;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.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This guide uses the following:&lt;br /&gt;
* aarch64 img (though this guide is also tested to be roughly x86-compatible)&lt;br /&gt;
* Raspberry Pi3&lt;br /&gt;
* community repo.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
See https://pkgs.alpinelinux.org/packages?name=*firefox*&amp;amp;branch=v3.11&amp;amp;arch=aarch64&lt;br /&gt;
&lt;br /&gt;
Note: the aarch64 build is not compatible with all Raspberry Pi models. See [[Raspberry Pi]].&lt;br /&gt;
&lt;br /&gt;
==Steps==&lt;br /&gt;
===Base Install===&lt;br /&gt;
&lt;br /&gt;
These steps are duplicated from the [[Raspberry Pi]] page. (Note that for sake of this guide, it&#039;s assumed the RPI is a RAM only install. Although there is no requirement for it to be done this way).&lt;br /&gt;
&lt;br /&gt;
Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem. &lt;br /&gt;
e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Command (m for help): p&lt;br /&gt;
Disk /dev/sdb: 59.5 GiB, 63864569856 bytes, 124735488 sectors&lt;br /&gt;
Units: sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disklabel type: dos&lt;br /&gt;
Disk identifier: 0x00000000&lt;br /&gt;
&lt;br /&gt;
Device     Boot Start      End  Sectors Size Id Type&lt;br /&gt;
/dev/sdb1  *     2048 62916607 62914560  30G  b W95 FAT32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{cmd|# mkdosfs -F 32 /dev/sdX1}}&lt;br /&gt;
&lt;br /&gt;
untar onto mounted disk&lt;br /&gt;
&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# mount /dev/sdX1 /mnt/folder&lt;br /&gt;
# tar xvf archive.tar -C /mnt/folder/.&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other&lt;br /&gt;
config settings, do so in {{path|usercfg.txt}} now.&lt;br /&gt;
&lt;br /&gt;
Again, duplicating the [[Raspberry Pi]] page &lt;br /&gt;
&lt;br /&gt;
    Insert the SD card into the Raspberry Pi and turn it on&lt;br /&gt;
    Log in to Alpine as root. Leave the password empty.&lt;br /&gt;
    Type setup-alpine, hit enter.&lt;br /&gt;
    Once the installation is complete, commit the changes by typing lbu commit -d&lt;br /&gt;
&lt;br /&gt;
Things to keep in mind:&lt;br /&gt;
* 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. &lt;br /&gt;
* For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with &amp;quot;No disks available, try boot media /mmcblk0p1&amp;quot;. Select the default [n]. If you make a mistake during the install, you can always reimage and start over.&lt;br /&gt;
&lt;br /&gt;
Saving space: busybox instead of chronyd, dropbear instead of openssh&lt;br /&gt;
&lt;br /&gt;
After setup, make sure dropbear is installed&lt;br /&gt;
{{cmd|# apk add dropbear}}&lt;br /&gt;
&lt;br /&gt;
Start it:&lt;br /&gt;
{{cmd|# rc-service dropbear start}}&lt;br /&gt;
&lt;br /&gt;
Add it to the default runlevel:&lt;br /&gt;
{{cmd|# rc-update add dropbear}}&lt;br /&gt;
&lt;br /&gt;
If you need an accurate clock, enable software/ntp here. (this step is optional)&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# rc-update add swclock boot # enable the software clock &lt;br /&gt;
# rc-update del hwclock boot # disable the hardware clock&lt;br /&gt;
# setup-ntp&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
===Browser Client Install===&lt;br /&gt;
&lt;br /&gt;
Enable community repo ({{path|/etc/apk/repositories}}) (uncomment community)&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# nano /etc/apk/repositories&lt;br /&gt;
# apk update&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
install firefox dependencies:&lt;br /&gt;
{{cmd|# apk add libx11-dev libxft-dev libxinerama-dev font-dejavu}}&lt;br /&gt;
&amp;lt;small&amp;gt;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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the amount of RAM tmp fs available can be viewed while installing with: &amp;lt;code&amp;gt;watch df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
install firefox&lt;br /&gt;
{{cmd|# apk add firefox-esr}}&lt;br /&gt;
install X&lt;br /&gt;
{{cmd|# setup-xorg-base}}&lt;br /&gt;
The RPI also requires for X:&lt;br /&gt;
{{cmd|# apk add xf86-video-fbdev}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;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 &amp;quot;apk search libEGL.so&amp;quot; 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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, we have about 421MB of RAM used (if NTP was not set up).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
devtmpfs                 10.0M         0     10.0M   0% /dev&lt;br /&gt;
shm                     457.9M         0    457.9M   0% /dev/shm&lt;br /&gt;
/dev/mmcblk0p1           30.0G    259.4M     29.7G   1% /media/mmcblk0p1&lt;br /&gt;
tmpfs                   457.9M    420.0M     37.9M  92% /&lt;br /&gt;
tmpfs                    91.6M    188.0K     91.4M   0% /run&lt;br /&gt;
/dev/loop0               24.9M     24.9M         0 100% /.modloop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{cmd|# lbu_commit -d}}&lt;br /&gt;
&lt;br /&gt;
===AutoLogin, Startx automatically on Boot===&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to login as root, and run startx manually. Now we&#039;ll add configuration files to enable that without user interaction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;What is happening here from my understanding is:&lt;br /&gt;
 1) User logs in. {{path|/etc/profile}} is run (which includes a call to startx)&lt;br /&gt;
 2) Startx references any relevant xinitrc (user folder or {{path|/etc/X11}}), which calls {{path|/etc/startup.sh}}&lt;br /&gt;
 3) {{path|/etc/startup.sh}} runs any commands, such as dwm, firefox, or chromium.&lt;br /&gt;
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 &amp;quot;logger&amp;quot; in shell scripts.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{path|/root/}} doesn&#039;t save any files, so it&#039;s necessary to edit files in {{path|/etc/}} and run &amp;lt;code&amp;gt;lbu_commit -d&amp;lt;/code&amp;gt; after all changes. First let&#039;s add a file that we&#039;ll call firefox.&lt;br /&gt;
&amp;lt;small&amp;gt;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]]&lt;br /&gt;
also see: {{path|/etc/apk/protected_paths.d/lbu.list}}&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
create a file named {{path|/etc/startup.sh}}:&lt;br /&gt;
{{cat|/etc/startup.sh|#!/bin/sh&lt;br /&gt;
firefox-esr &amp;lt;nowiki&amp;gt;http://awebsite.com&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
!!!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.&lt;br /&gt;
&lt;br /&gt;
Make sure the file is executable.&lt;br /&gt;
{{cmd|# chmod +x /etc/startup.sh}}&lt;br /&gt;
&lt;br /&gt;
We have to edit xinitrc, and the profile configs. Normally, this would be done in the user&#039;s directory, but here we will use the globals for simplicity. Note that here we are &#039;moving&#039; 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).&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK&lt;br /&gt;
# nano /etc/X11/xinit/xinitrc&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
In this file, insert:&lt;br /&gt;
{{cat|/etc/X11/xinit/xinitrc|...&lt;br /&gt;
/etc/startup.sh}}&lt;br /&gt;
At the end of {{path|/etc/profile}} (leave the existing file) append&lt;br /&gt;
{{cat|/etc/profile|...&lt;br /&gt;
startx}}&lt;br /&gt;
Remember to run &amp;lt;code&amp;gt;lbu_commit -d&amp;lt;/code&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
For autologin, alpine uses busybox, which has an alias to {{path|/sbin/getty}} as well as {{path|/bin/login}}. It&#039;s possible to navigate to {{path|/sbin/}} or {{path|/bin/}} and run &amp;lt;code&amp;gt;/sbin/getty -h&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
{{cat|/etc/inittab|&amp;lt;nowiki&amp;gt;# Set up a couple of gettys&lt;br /&gt;
#tty1::respawn:/sbin/getty 38400 tty1&lt;br /&gt;
tty2::respawn:/sbin/getty 38400 tty2&lt;br /&gt;
tty3::respawn:/sbin/getty 38400 tty3&lt;br /&gt;
tty4::respawn:/sbin/getty 38400 tty4&lt;br /&gt;
tty5::respawn:/sbin/getty 38400 tty5&lt;br /&gt;
tty6::respawn:/sbin/getty 38400 tty6&lt;br /&gt;
&lt;br /&gt;
tty1::respawn:/bin/login -f root&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Disable Screensaver, and refresh webpage (optional)===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/X11/xorg.conf|&lt;br /&gt;
Section &amp;quot;Extensions&amp;quot;&lt;br /&gt;
    Option      &amp;quot;DPMS&amp;quot; &amp;quot;Disable&amp;quot;&lt;br /&gt;
EndSection}} &lt;br /&gt;
&lt;br /&gt;
{{cmd|# apk add {{pkg|xdotool|arch=a*}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# crontab -u root -e &lt;br /&gt;
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Note: xset is not an option here as it&#039;s not included by default. It can be installed from the repositories, if needed.&amp;lt;/small&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
That&#039;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&#039;ll have even more resources available.&lt;br /&gt;
&lt;br /&gt;
==Digital Signage==&lt;br /&gt;
It&#039;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? &lt;br /&gt;
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd). &lt;br /&gt;
# There is no requirement to use &#039;cloud&#039; services, or an internet connection. &lt;br /&gt;
# You have full control over the build and design (all kiosk build steps are documented &amp;amp; have a small learning curve, compared to some of the more complex projects mentioned above).&lt;br /&gt;
# Free software. No recurring costs (outside of optional maintenance). &lt;br /&gt;
# No ties to external infrastructure / frameworks. Full freedom.&lt;br /&gt;
&lt;br /&gt;
In this addition to the guide above, we&#039;ll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we&#039;ll also run a web server with PHP, which hosts the resources we want to display on the sign.&lt;br /&gt;
Make sure community apk is enabled in {{path|/etc/apk/repositories}}&lt;br /&gt;
{{cmd|# apk add {{pkg|chromium|arch=a*}}}}&lt;br /&gt;
In {{path|/etc/startup.sh}} add chromium instead of firefox:&lt;br /&gt;
{{cat|/etc/startup.sh|&amp;lt;nowiki&amp;gt;...&lt;br /&gt;
chromium-browser --home-page http://127.0.0.1/resource --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you deploy the device on a TV, and you&#039;re unsure what resolution it is, you can access the resolution from the terminal (not in X), by using &lt;br /&gt;
{{cmd|# xrandr -d :0}}&lt;br /&gt;
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&#039;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&#039;s config.h, But a WM is not required.&lt;br /&gt;
&lt;br /&gt;
Make sure to run &amp;lt;code&amp;gt;lbu_commit -d&amp;lt;/code&amp;gt;, in order to save any changes as needed in the apkvol on the SD or HDD storage.&lt;br /&gt;
&lt;br /&gt;
===Install Apache/PHP===&lt;br /&gt;
See [[Apache]].&lt;br /&gt;
&lt;br /&gt;
===Install xset to disable screensaver===&lt;br /&gt;
{{cmd|# apk add {{pkg|xset|arch=a*}}&lt;br /&gt;
&amp;amp;num; xset q&lt;br /&gt;
&amp;amp;num; xset s off&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Hide Scrollbars of Browser===&lt;br /&gt;
This can be done with CSS.&lt;br /&gt;
 body {&lt;br /&gt;
   overflow: hidden; /* Hide scrollbars */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
===Why was this setup used? Why not Awesome, or dwm?===&lt;br /&gt;
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&#039;t have this limitation. It should be possible to get more RAM via {{path|/boot/config.txt}}&lt;br /&gt;
&lt;br /&gt;
If your application doesn&#039;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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Width &amp;amp; height of firefox doesn&#039;t fit the monitor===&lt;br /&gt;
Firefox can be called with -height and -width flags, e.g. &lt;br /&gt;
{{cmd|firefox -width 480 -height 640 example.org}}&lt;br /&gt;
&lt;br /&gt;
===Periodic Firefox Crashes on RPI3 due to Low Memory===&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
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 &amp;gt;1GB ram which may eliminate the need for a nightly reboot.&lt;br /&gt;
&lt;br /&gt;
===Firefox-esr segmentation fault on x86 for 3.17===&lt;br /&gt;
In running firefox on an old intel atom netbook, I see firefox having a &#039;segmentation fault&#039; 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.&lt;br /&gt;
&lt;br /&gt;
===How do I easily backup my diskless system?===&lt;br /&gt;
You should backup the apkvol which is located in /media/mmc (the location of the sd card).&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* [[dwm]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=27816</id>
		<title>Raspberry Pi 3 - Browser Client</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=27816"/>
		<updated>2024-11-15T08:50:03Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;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.&lt;br /&gt;
&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This guide uses the following:&lt;br /&gt;
* aarch64 img (though this guide is also tested to be roughly x86-compatible)&lt;br /&gt;
* Raspberry Pi3&lt;br /&gt;
* community repo.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
See https://pkgs.alpinelinux.org/packages?name=*firefox*&amp;amp;branch=v3.11&amp;amp;arch=aarch64&lt;br /&gt;
&lt;br /&gt;
Note: the aarch64 build is not compatible with all Raspberry Pi models. See [[Raspberry Pi]].&lt;br /&gt;
&lt;br /&gt;
==Steps==&lt;br /&gt;
===Base Install===&lt;br /&gt;
&lt;br /&gt;
These steps are duplicated from the [[Raspberry Pi]] page. (Note that for sake of this guide, it&#039;s assumed the RPI is a RAM only install. Although there is no requirement for it to be done this way).&lt;br /&gt;
&lt;br /&gt;
Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem. &lt;br /&gt;
e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Command (m for help): p&lt;br /&gt;
Disk /dev/sdb: 59.5 GiB, 63864569856 bytes, 124735488 sectors&lt;br /&gt;
Units: sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disklabel type: dos&lt;br /&gt;
Disk identifier: 0x00000000&lt;br /&gt;
&lt;br /&gt;
Device     Boot Start      End  Sectors Size Id Type&lt;br /&gt;
/dev/sdb1  *     2048 62916607 62914560  30G  b W95 FAT32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{cmd|# mkdosfs -F 32 /dev/sdX1}}&lt;br /&gt;
&lt;br /&gt;
untar onto mounted disk&lt;br /&gt;
&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# mount /dev/sdX1 /mnt/folder&lt;br /&gt;
# tar xvf archive.tar -C /mnt/folder/.&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other&lt;br /&gt;
config settings, do so in {{path|usercfg.txt}} now.&lt;br /&gt;
&lt;br /&gt;
Again, duplicating the [[Raspberry Pi]] page &lt;br /&gt;
&lt;br /&gt;
    Insert the SD card into the Raspberry Pi and turn it on&lt;br /&gt;
    Log in to Alpine as root. Leave the password empty.&lt;br /&gt;
    Type setup-alpine, hit enter.&lt;br /&gt;
    Once the installation is complete, commit the changes by typing lbu commit -d&lt;br /&gt;
&lt;br /&gt;
Things to keep in mind:&lt;br /&gt;
* 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. &lt;br /&gt;
* For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with &amp;quot;No disks available, try boot media /mmcblk0p1&amp;quot;. Select the default [n]. If you make a mistake during the install, you can always reimage and start over.&lt;br /&gt;
&lt;br /&gt;
Saving space: busybox instead of chronyd, dropbear instead of openssh&lt;br /&gt;
&lt;br /&gt;
After setup, make sure dropbear is installed&lt;br /&gt;
{{cmd|# apk add dropbear}}&lt;br /&gt;
&lt;br /&gt;
Start it:&lt;br /&gt;
{{cmd|# rc-service dropbear start}}&lt;br /&gt;
&lt;br /&gt;
Add it to the default runlevel:&lt;br /&gt;
{{cmd|# rc-update add dropbear}}&lt;br /&gt;
&lt;br /&gt;
If you need an accurate clock, enable software/ntp here. (this step is optional)&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# rc-update add swclock boot # enable the software clock &lt;br /&gt;
# rc-update del hwclock boot # disable the hardware clock&lt;br /&gt;
# setup-ntp&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
===Browser Client Install===&lt;br /&gt;
&lt;br /&gt;
Enable community repo ({{path|/etc/apk/repositories}}) (uncomment community)&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# nano /etc/apk/repositories&lt;br /&gt;
# apk update&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
install firefox dependencies:&lt;br /&gt;
{{cmd|# apk add libx11-dev libxft-dev libxinerama-dev font-dejavu}}&lt;br /&gt;
&amp;lt;small&amp;gt;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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the amount of RAM tmp fs available can be viewed while installing with: &amp;lt;code&amp;gt;watch df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
install firefox&lt;br /&gt;
{{cmd|# apk add firefox-esr}}&lt;br /&gt;
install X&lt;br /&gt;
{{cmd|# setup-xorg-base}}&lt;br /&gt;
The RPI also requires for X:&lt;br /&gt;
{{cmd|# apk add xf86-video-fbdev}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;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 &amp;quot;apk search libEGL.so&amp;quot; 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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, we have about 421MB of RAM used (if NTP was not set up).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
devtmpfs                 10.0M         0     10.0M   0% /dev&lt;br /&gt;
shm                     457.9M         0    457.9M   0% /dev/shm&lt;br /&gt;
/dev/mmcblk0p1           30.0G    259.4M     29.7G   1% /media/mmcblk0p1&lt;br /&gt;
tmpfs                   457.9M    420.0M     37.9M  92% /&lt;br /&gt;
tmpfs                    91.6M    188.0K     91.4M   0% /run&lt;br /&gt;
/dev/loop0               24.9M     24.9M         0 100% /.modloop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{cmd|# lbu_commit -d}}&lt;br /&gt;
&lt;br /&gt;
===AutoLogin, Startx automatically on Boot===&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to login as root, and run startx manually. Now we&#039;ll add configuration files to enable that without user interaction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;What is happening here from my understanding is:&lt;br /&gt;
 1) User logs in. {{path|/etc/profile}} is run (which includes a call to startx)&lt;br /&gt;
 2) Startx references any relevant xinitrc (user folder or {{path|/etc/X11}}), which calls {{path|/etc/startup.sh}}&lt;br /&gt;
 3) {{path|/etc/startup.sh}} runs any commands, such as dwm, firefox, or chromium.&lt;br /&gt;
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 &amp;quot;logger&amp;quot; in shell scripts.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{path|/root/}} doesn&#039;t save any files, so it&#039;s necessary to edit files in {{path|/etc/}} and run &amp;lt;code&amp;gt;lbu_commit -d&amp;lt;/code&amp;gt; after all changes. First let&#039;s add a file that we&#039;ll call firefox.&lt;br /&gt;
&amp;lt;small&amp;gt;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]]&lt;br /&gt;
also see: {{path|/etc/apk/protected_paths.d/lbu.list}}&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
create a file named {{path|/etc/startup.sh}}:&lt;br /&gt;
{{cat|/etc/startup.sh|#!/bin/sh&lt;br /&gt;
firefox-esr &amp;lt;nowiki&amp;gt;http://awebsite.com&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
!!!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.&lt;br /&gt;
&lt;br /&gt;
Make sure the file is executable.&lt;br /&gt;
{{cmd|# chmod +x /etc/startup.sh}}&lt;br /&gt;
&lt;br /&gt;
We have to edit xinitrc, and the profile configs. Normally, this would be done in the user&#039;s directory, but here we will use the globals for simplicity. Note that here we are &#039;moving&#039; 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).&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK&lt;br /&gt;
# nano /etc/X11/xinit/xinitrc&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
In this file, insert:&lt;br /&gt;
{{cat|/etc/X11/xinit/xinitrc|...&lt;br /&gt;
/etc/startup.sh}}&lt;br /&gt;
At the end of {{path|/etc/profile}} (leave the existing file) append&lt;br /&gt;
{{cat|/etc/profile|...&lt;br /&gt;
startx}}&lt;br /&gt;
Remember to run &amp;lt;code&amp;gt;lbu_commit -d&amp;lt;/code&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
For autologin, alpine uses busybox, which has an alias to {{path|/sbin/getty}} as well as {{path|/bin/login}}. It&#039;s possible to navigate to {{path|/sbin/}} or {{path|/bin/}} and run &amp;lt;code&amp;gt;/sbin/getty -h&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
{{cat|/etc/inittab|&amp;lt;nowiki&amp;gt;# Set up a couple of gettys&lt;br /&gt;
#tty1::respawn:/sbin/getty 38400 tty1&lt;br /&gt;
tty2::respawn:/sbin/getty 38400 tty2&lt;br /&gt;
tty3::respawn:/sbin/getty 38400 tty3&lt;br /&gt;
tty4::respawn:/sbin/getty 38400 tty4&lt;br /&gt;
tty5::respawn:/sbin/getty 38400 tty5&lt;br /&gt;
tty6::respawn:/sbin/getty 38400 tty6&lt;br /&gt;
&lt;br /&gt;
tty1::respawn:/bin/login -f root&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Disable Screensaver, and refresh webpage (optional)===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/X11/xorg.conf|&lt;br /&gt;
Section &amp;quot;Extensions&amp;quot;&lt;br /&gt;
    Option      &amp;quot;DPMS&amp;quot; &amp;quot;Disable&amp;quot;&lt;br /&gt;
EndSection}} &lt;br /&gt;
&lt;br /&gt;
{{cmd|# apk add {{pkg|xdotool|arch=a*}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# crontab -u root -e &lt;br /&gt;
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Note: xset is not an option here as it&#039;s not included by default. It can be installed from the repositories, if needed.&amp;lt;/small&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
That&#039;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&#039;ll have even more resources available.&lt;br /&gt;
&lt;br /&gt;
==Digital Signage==&lt;br /&gt;
It&#039;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? &lt;br /&gt;
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd). &lt;br /&gt;
# There is no requirement to use &#039;cloud&#039; services, or an internet connection. &lt;br /&gt;
# You have full control over the build and design (all kiosk build steps are documented &amp;amp; have a small learning curve, compared to some of the more complex projects mentioned above).&lt;br /&gt;
# Free software. No recurring costs (outside of optional maintenance). &lt;br /&gt;
# No ties to external infrastructure / frameworks. Full freedom.&lt;br /&gt;
&lt;br /&gt;
In this addition to the guide above, we&#039;ll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we&#039;ll also run a web server with PHP, which hosts the resources we want to display on the sign.&lt;br /&gt;
Make sure community apk is enabled in {{path|/etc/apk/repositories}}&lt;br /&gt;
{{cmd|# apk add {{pkg|chromium|arch=a*}}}}&lt;br /&gt;
In {{path|/etc/startup.sh}} add chromium instead of firefox:&lt;br /&gt;
{{cat|/etc/startup.sh|&amp;lt;nowiki&amp;gt;...&lt;br /&gt;
chromium-browser --home-page http://127.0.0.1/resource --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you deploy the device on a TV, and you&#039;re unsure what resolution it is, you can access the resolution from the terminal (not in X), by using &lt;br /&gt;
{{cmd|# xrandr -d :0}}&lt;br /&gt;
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&#039;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&#039;s config.h, But a WM is not required.&lt;br /&gt;
&lt;br /&gt;
Make sure to run &amp;lt;code&amp;gt;lbu_commit -d&amp;lt;/code&amp;gt;, in order to save any changes as needed in the apkvol on the SD or HDD storage.&lt;br /&gt;
&lt;br /&gt;
===Install Apache/PHP===&lt;br /&gt;
See [[Apache]].&lt;br /&gt;
&lt;br /&gt;
===Install xset to disable screensaver===&lt;br /&gt;
{{cmd|# apk add {{pkg|xset|arch=a*}}&lt;br /&gt;
&amp;amp;num; xset q&lt;br /&gt;
&amp;amp;num; xset s off&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Hide Scrollbars of Browser===&lt;br /&gt;
This can be done with CSS.&lt;br /&gt;
 body {&lt;br /&gt;
   overflow: hidden; /* Hide scrollbars */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
===Why was this setup used? Why not Awesome, or dwm?===&lt;br /&gt;
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&#039;t have this limitation. It should be possible to get more RAM via {{path|/boot/config.txt}}&lt;br /&gt;
&lt;br /&gt;
If your application doesn&#039;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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Width &amp;amp; height of firefox doesn&#039;t fit the monitor===&lt;br /&gt;
Firefox can be called with -height and -width flags, e.g. &lt;br /&gt;
{{cmd|firefox -width 480 -height 640 example.org}}&lt;br /&gt;
&lt;br /&gt;
===Periodic Firefox Crashes on RPI3 due to Low Memory===&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
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 &amp;gt;1GB ram which may eliminate the need for a nightly reboot.&lt;br /&gt;
&lt;br /&gt;
===Firefox-esr segmentation fault on x86 for 3.17===&lt;br /&gt;
In running firefox on an old intel atom netbook, I see firefox having a &#039;segmentation fault&#039; 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.&lt;br /&gt;
&lt;br /&gt;
===How do I easily backup my diskless system?===&lt;br /&gt;
You should backup the apkvol which is located in /media/mmc (the location of the sd card).&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* [[dwm]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=27815</id>
		<title>Raspberry Pi 3 - Browser Client</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=27815"/>
		<updated>2024-11-15T08:49:00Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;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.&lt;br /&gt;
&lt;br /&gt;
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).&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This guide uses the following:&lt;br /&gt;
* aarch64 img (though this guide is also tested to be roughly x86-compatible)&lt;br /&gt;
* Raspberry Pi3&lt;br /&gt;
* community repo.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
See https://pkgs.alpinelinux.org/packages?name=*firefox*&amp;amp;branch=v3.11&amp;amp;arch=aarch64&lt;br /&gt;
&lt;br /&gt;
Note: the aarch64 build is not compatible with all Raspberry Pi models. See [[Raspberry Pi]].&lt;br /&gt;
&lt;br /&gt;
==Steps==&lt;br /&gt;
===Base Install===&lt;br /&gt;
&lt;br /&gt;
These steps are duplicated from the [[Raspberry Pi]] page. (Note that for sake of this guide, it&#039;s assumed the RPI is a RAM only install. Although there is no requirement for it to be done this way).&lt;br /&gt;
&lt;br /&gt;
Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem. &lt;br /&gt;
e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Command (m for help): p&lt;br /&gt;
Disk /dev/sdb: 59.5 GiB, 63864569856 bytes, 124735488 sectors&lt;br /&gt;
Units: sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disklabel type: dos&lt;br /&gt;
Disk identifier: 0x00000000&lt;br /&gt;
&lt;br /&gt;
Device     Boot Start      End  Sectors Size Id Type&lt;br /&gt;
/dev/sdb1  *     2048 62916607 62914560  30G  b W95 FAT32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{cmd|# mkdosfs -F 32 /dev/sdX1}}&lt;br /&gt;
&lt;br /&gt;
untar onto mounted disk&lt;br /&gt;
&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# mount /dev/sdX1 /mnt/folder&lt;br /&gt;
# tar xvf archive.tar -C /mnt/folder/.&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other&lt;br /&gt;
config settings, do so in {{path|usercfg.txt}} now.&lt;br /&gt;
&lt;br /&gt;
Again, duplicating the [[Raspberry Pi]] page &lt;br /&gt;
&lt;br /&gt;
    Insert the SD card into the Raspberry Pi and turn it on&lt;br /&gt;
    Log in to Alpine as root. Leave the password empty.&lt;br /&gt;
    Type setup-alpine, hit enter.&lt;br /&gt;
    Once the installation is complete, commit the changes by typing lbu commit -d&lt;br /&gt;
&lt;br /&gt;
Things to keep in mind:&lt;br /&gt;
* 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. &lt;br /&gt;
* For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with &amp;quot;No disks available, try boot media /mmcblk0p1&amp;quot;. Select the default [n]. If you make a mistake during the install, you can always reimage and start over.&lt;br /&gt;
&lt;br /&gt;
Saving space: busybox instead of chronyd, dropbear instead of openssh&lt;br /&gt;
&lt;br /&gt;
After setup, make sure dropbear is installed&lt;br /&gt;
{{cmd|# apk add dropbear}}&lt;br /&gt;
&lt;br /&gt;
Start it:&lt;br /&gt;
{{cmd|# rc-service dropbear start}}&lt;br /&gt;
&lt;br /&gt;
Add it to the default runlevel:&lt;br /&gt;
{{cmd|# rc-update add dropbear}}&lt;br /&gt;
&lt;br /&gt;
If you need an accurate clock, enable software/ntp here. (this step is optional)&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# rc-update add swclock boot # enable the software clock &lt;br /&gt;
# rc-update del hwclock boot # disable the hardware clock&lt;br /&gt;
# setup-ntp&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
===Browser Client Install===&lt;br /&gt;
&lt;br /&gt;
Enable community repo ({{path|/etc/apk/repositories}}) (uncomment community)&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# nano /etc/apk/repositories&lt;br /&gt;
# apk update&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
install firefox dependencies:&lt;br /&gt;
{{cmd|# apk add libx11-dev libxft-dev libxinerama-dev font-dejavu}}&lt;br /&gt;
&amp;lt;small&amp;gt;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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the amount of RAM tmp fs available can be viewed while installing with: &amp;lt;code&amp;gt;watch df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
install firefox&lt;br /&gt;
{{cmd|# apk add firefox-esr}}&lt;br /&gt;
install X&lt;br /&gt;
{{cmd|# setup-xorg-base}}&lt;br /&gt;
The RPI also requires for X:&lt;br /&gt;
{{cmd|# apk add xf86-video-fbdev}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;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 &amp;quot;apk search libEGL.so&amp;quot; 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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, we have about 421MB of RAM used (if NTP was not set up).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
devtmpfs                 10.0M         0     10.0M   0% /dev&lt;br /&gt;
shm                     457.9M         0    457.9M   0% /dev/shm&lt;br /&gt;
/dev/mmcblk0p1           30.0G    259.4M     29.7G   1% /media/mmcblk0p1&lt;br /&gt;
tmpfs                   457.9M    420.0M     37.9M  92% /&lt;br /&gt;
tmpfs                    91.6M    188.0K     91.4M   0% /run&lt;br /&gt;
/dev/loop0               24.9M     24.9M         0 100% /.modloop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{cmd|# lbu_commit -d}}&lt;br /&gt;
&lt;br /&gt;
===AutoLogin, Startx automatically on Boot===&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to login as root, and run startx manually. Now we&#039;ll add configuration files to enable that without user interaction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;What is happening here from my understanding is:&lt;br /&gt;
 1) User logs in. {{path|/etc/profile}} is run (which includes a call to startx)&lt;br /&gt;
 2) Startx references any relevant xinitrc (user folder or {{path|/etc/X11}}), which calls {{path|/etc/startup.sh}}&lt;br /&gt;
 3) {{path|/etc/startup.sh}} runs any commands, such as dwm, firefox, or chromium.&lt;br /&gt;
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 &amp;quot;logger&amp;quot; in shell scripts.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{path|/root/}} doesn&#039;t save any files, so it&#039;s necessary to edit files in {{path|/etc/}} and run &amp;lt;code&amp;gt;lbu_commit -d&amp;lt;/code&amp;gt; after all changes. First let&#039;s add a file that we&#039;ll call firefox.&lt;br /&gt;
&amp;lt;small&amp;gt;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]]&lt;br /&gt;
also see: {{path|/etc/apk/protected_paths.d/lbu.list}}&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
create a file named {{path|/etc/startup.sh}}:&lt;br /&gt;
{{cat|/etc/startup.sh|#!/bin/sh&lt;br /&gt;
firefox-esr &amp;lt;nowiki&amp;gt;http://awebsite.com&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
!!!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.&lt;br /&gt;
&lt;br /&gt;
Make sure the file is executable.&lt;br /&gt;
{{cmd|# chmod +x /etc/startup.sh}}&lt;br /&gt;
&lt;br /&gt;
We have to edit xinitrc, and the profile configs. Normally, this would be done in the user&#039;s directory, but here we will use the globals for simplicity. Note that here we are &#039;moving&#039; 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).&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK&lt;br /&gt;
# nano /etc/X11/xinit/xinitrc&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
In this file, insert:&lt;br /&gt;
{{cat|/etc/X11/xinit/xinitrc|...&lt;br /&gt;
/etc/startup.sh}}&lt;br /&gt;
At the end of {{path|/etc/profile}} (leave the existing file) append&lt;br /&gt;
{{cat|/etc/profile|...&lt;br /&gt;
startx}}&lt;br /&gt;
Remember to run &amp;lt;code&amp;gt;lbu_commit -d&amp;lt;/code&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
For autologin, alpine uses busybox, which has an alias to {{path|/sbin/getty}} as well as {{path|/bin/login}}. It&#039;s possible to navigate to {{path|/sbin/}} or {{path|/bin/}} and run &amp;lt;code&amp;gt;/sbin/getty -h&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
{{cat|/etc/inittab|&amp;lt;nowiki&amp;gt;# Set up a couple of gettys&lt;br /&gt;
#tty1::respawn:/sbin/getty 38400 tty1&lt;br /&gt;
tty2::respawn:/sbin/getty 38400 tty2&lt;br /&gt;
tty3::respawn:/sbin/getty 38400 tty3&lt;br /&gt;
tty4::respawn:/sbin/getty 38400 tty4&lt;br /&gt;
tty5::respawn:/sbin/getty 38400 tty5&lt;br /&gt;
tty6::respawn:/sbin/getty 38400 tty6&lt;br /&gt;
&lt;br /&gt;
tty1::respawn:/bin/login -f root&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Disable Screensaver, and refresh webpage (optional)===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/X11/xorg.conf|&lt;br /&gt;
Section &amp;quot;Extensions&amp;quot;&lt;br /&gt;
    Option      &amp;quot;DPMS&amp;quot; &amp;quot;Disable&amp;quot;&lt;br /&gt;
EndSection}} &lt;br /&gt;
&lt;br /&gt;
{{cmd|# apk add {{pkg|xdotool|arch=a*}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# crontab -u root -e &lt;br /&gt;
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Note: xset is not an option here as it&#039;s not included by default. It can be installed from the repositories, if needed.&amp;lt;/small&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
That&#039;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&#039;ll have even more resources available.&lt;br /&gt;
&lt;br /&gt;
==Digital Signage==&lt;br /&gt;
It&#039;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? &lt;br /&gt;
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd). &lt;br /&gt;
# There is no requirement to use &#039;cloud&#039; services, or an internet connection. &lt;br /&gt;
# You have full control over the build and design (all kiosk build steps are documented &amp;amp; have a small learning curve, compared to some of the more complex projects mentioned above).&lt;br /&gt;
# Free software. No recurring costs (outside of optional maintenance). &lt;br /&gt;
# No ties to external infrastructure / frameworks. Full freedom.&lt;br /&gt;
&lt;br /&gt;
In this addition to the guide above, we&#039;ll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we&#039;ll also run a web server with PHP, which hosts the resources we want to display on the sign.&lt;br /&gt;
Make sure community apk is enabled in {{path|/etc/apk/repositories}}&lt;br /&gt;
{{cmd|# apk add {{pkg|chromium|arch=a*}}}}&lt;br /&gt;
In {{path|/etc/startup.sh}} add chromium instead of firefox:&lt;br /&gt;
{{cat|/etc/startup.sh|&amp;lt;nowiki&amp;gt;...&lt;br /&gt;
chromium-browser --home-page http://127.0.0.1/resource --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you deploy the device on a TV, and you&#039;re unsure what resolution it is, you can access the resolution from the terminal (not in X), by using &lt;br /&gt;
{{cmd|# xrandr -d :0}}&lt;br /&gt;
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&#039;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&#039;s config.h, But a WM is not required.&lt;br /&gt;
&lt;br /&gt;
Make sure to run &amp;lt;code&amp;gt;lbu_commit -d&amp;lt;/code&amp;gt;, in order to save any changes as needed in the apkvol on the SD or HDD storage.&lt;br /&gt;
&lt;br /&gt;
===Install Apache/PHP===&lt;br /&gt;
See [[Apache]].&lt;br /&gt;
&lt;br /&gt;
===Install xset to disable screensaver===&lt;br /&gt;
{{cmd|# apk add {{pkg|xset|arch=a*}}&lt;br /&gt;
&amp;amp;num; xset q&lt;br /&gt;
&amp;amp;num; xset s off&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Hide Scrollbars of Browser===&lt;br /&gt;
This can be done with CSS.&lt;br /&gt;
 body {&lt;br /&gt;
   overflow: hidden; /* Hide scrollbars */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
===Why was this setup used? Why not Awesome, or dwm?===&lt;br /&gt;
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&#039;t have this limitation. It should be possible to get more RAM via {{path|/boot/config.txt}}&lt;br /&gt;
&lt;br /&gt;
If your application doesn&#039;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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Width &amp;amp; height of firefox doesn&#039;t fit the monitor===&lt;br /&gt;
Firefox can be called with -height and -width flags, e.g. &lt;br /&gt;
{{cmd|firefox -width 480 -height 640 example.org}}&lt;br /&gt;
&lt;br /&gt;
===Periodic Firefox Crashes on RPI3 due to Low Memory===&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
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 &amp;gt;1GB ram which may eliminate the need for a nightly reboot.&lt;br /&gt;
&lt;br /&gt;
===Firefox-esr segmentation fault on x86 for 3.17===&lt;br /&gt;
In running firefox on an old intel atom netbook, I see firefox having a &#039;segmentation fault&#039; 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.&lt;br /&gt;
&lt;br /&gt;
===How do I easily backup my diskless system?===&lt;br /&gt;
You should backup the apkvol which is located in /media/mmc (the location of the sd card).&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* [[dwm]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=27814</id>
		<title>Raspberry Pi 3 - Browser Client</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=27814"/>
		<updated>2024-11-15T08:36:33Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* Firefox-esr segmentation fault on x86 for 3.17 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;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.&lt;br /&gt;
&lt;br /&gt;
Current revision rough tested with 3.17 (on x86). For earlier releases, please see history.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This guide uses the following:&lt;br /&gt;
* aarch64 img (though this guide is also tested to be roughly x86-compatible)&lt;br /&gt;
* Raspberry Pi3 &lt;br /&gt;
* community repo.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
See https://pkgs.alpinelinux.org/packages?name=*firefox*&amp;amp;branch=v3.11&amp;amp;arch=aarch64&lt;br /&gt;
&lt;br /&gt;
Note: the aarch64 build is not compatible with all Raspberry Pi models. See [[Raspberry Pi]].&lt;br /&gt;
&lt;br /&gt;
==Steps==&lt;br /&gt;
===Base Install===&lt;br /&gt;
&lt;br /&gt;
These steps are duplicated from the [[Raspberry Pi]] page. (Note that for sake of this guide, it&#039;s assumed the RPI is a RAM only install. Although there is no requirement for it to be done this way).&lt;br /&gt;
&lt;br /&gt;
Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem. &lt;br /&gt;
e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Command (m for help): p&lt;br /&gt;
Disk /dev/sdb: 59.5 GiB, 63864569856 bytes, 124735488 sectors&lt;br /&gt;
Units: sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disklabel type: dos&lt;br /&gt;
Disk identifier: 0x00000000&lt;br /&gt;
&lt;br /&gt;
Device     Boot Start      End  Sectors Size Id Type&lt;br /&gt;
/dev/sdb1  *     2048 62916607 62914560  30G  b W95 FAT32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{cmd|# mkdosfs -F 32 /dev/sdX1}}&lt;br /&gt;
&lt;br /&gt;
untar onto mounted disk&lt;br /&gt;
&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# mount /dev/sdX1 /mnt/folder&lt;br /&gt;
# tar xvf archive.tar -C /mnt/folder/.&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other&lt;br /&gt;
config settings, do so in {{path|usercfg.txt}} now.&lt;br /&gt;
&lt;br /&gt;
Again, duplicating the [[Raspberry Pi]] page &lt;br /&gt;
&lt;br /&gt;
    Insert the SD card into the Raspberry Pi and turn it on&lt;br /&gt;
    Log in to Alpine as root. Leave the password empty.&lt;br /&gt;
    Type setup-alpine, hit enter.&lt;br /&gt;
    Once the installation is complete, commit the changes by typing lbu commit -d&lt;br /&gt;
&lt;br /&gt;
Things to keep in mind:&lt;br /&gt;
* 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. &lt;br /&gt;
* For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with &amp;quot;No disks available, try boot media /mmcblk0p1&amp;quot;. Select the default [n]. If you make a mistake during the install, you can always reimage and start over.&lt;br /&gt;
&lt;br /&gt;
Saving space: busybox instead of chronyd, dropbear instead of openssh&lt;br /&gt;
&lt;br /&gt;
After setup, make sure dropbear is installed&lt;br /&gt;
{{cmd|# apk add dropbear}}&lt;br /&gt;
&lt;br /&gt;
Start it:&lt;br /&gt;
{{cmd|# rc-service dropbear start}}&lt;br /&gt;
&lt;br /&gt;
Add it to the default runlevel:&lt;br /&gt;
{{cmd|# rc-update add dropbear}}&lt;br /&gt;
&lt;br /&gt;
If you need an accurate clock, enable software/ntp here. (this step is optional)&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# rc-update add swclock boot # enable the software clock &lt;br /&gt;
# rc-update del hwclock boot # disable the hardware clock&lt;br /&gt;
# setup-ntp&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
===Browser Client Install===&lt;br /&gt;
&lt;br /&gt;
Enable community repo ({{path|/etc/apk/repositories}}) (uncomment community)&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# nano /etc/apk/repositories&lt;br /&gt;
# apk update&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
install firefox dependencies:&lt;br /&gt;
{{cmd|# apk add libx11-dev libxft-dev libxinerama-dev font-dejavu}}&lt;br /&gt;
&amp;lt;small&amp;gt;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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the amount of RAM tmp fs available can be viewed while installing with: &amp;lt;code&amp;gt;watch df -h&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
install firefox&lt;br /&gt;
{{cmd|# apk add firefox-esr}}&lt;br /&gt;
install X&lt;br /&gt;
{{cmd|# setup-xorg-base}}&lt;br /&gt;
The RPI also requires for X:&lt;br /&gt;
{{cmd|# apk add xf86-video-fbdev}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;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 &amp;quot;apk search libEGL.so&amp;quot; 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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, we have about 421MB of RAM used (if NTP was not set up).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
devtmpfs                 10.0M         0     10.0M   0% /dev&lt;br /&gt;
shm                     457.9M         0    457.9M   0% /dev/shm&lt;br /&gt;
/dev/mmcblk0p1           30.0G    259.4M     29.7G   1% /media/mmcblk0p1&lt;br /&gt;
tmpfs                   457.9M    420.0M     37.9M  92% /&lt;br /&gt;
tmpfs                    91.6M    188.0K     91.4M   0% /run&lt;br /&gt;
/dev/loop0               24.9M     24.9M         0 100% /.modloop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{cmd|# lbu_commit -d}}&lt;br /&gt;
&lt;br /&gt;
===AutoLogin, Startx automatically on Boot===&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to login as root, and run startx manually. Now we&#039;ll add configuration files to enable that without user interaction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;What is happening here from my understanding is:&lt;br /&gt;
 1) User logs in. {{path|/etc/profile}} is run (which includes a call to startx)&lt;br /&gt;
 2) Startx references any relevant xinitrc (user folder or {{path|/etc/X11}}), which calls {{path|/etc/startup.sh}}&lt;br /&gt;
 3) {{path|/etc/startup.sh}} runs any commands, such as dwm, firefox, or chromium.&lt;br /&gt;
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 &amp;quot;logger&amp;quot; in shell scripts.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{path|/root/}} doesn&#039;t save any files, so it&#039;s necessary to edit files in {{path|/etc/}} and run &amp;lt;code&amp;gt;lbu_commit -d&amp;lt;/code&amp;gt; after all changes. First let&#039;s add a file that we&#039;ll call firefox.&lt;br /&gt;
&amp;lt;small&amp;gt;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]]&lt;br /&gt;
also see: {{path|/etc/apk/protected_paths.d/lbu.list}}&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
create a file named {{path|/etc/startup.sh}}:&lt;br /&gt;
{{cat|/etc/startup.sh|#!/bin/sh&lt;br /&gt;
firefox-esr &amp;lt;nowiki&amp;gt;http://awebsite.com&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
!!!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.&lt;br /&gt;
&lt;br /&gt;
Make sure the file is executable.&lt;br /&gt;
{{cmd|# chmod +x /etc/startup.sh}}&lt;br /&gt;
&lt;br /&gt;
We have to edit xinitrc, and the profile configs. Normally, this would be done in the user&#039;s directory, but here we will use the globals for simplicity. Note that here we are &#039;moving&#039; 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).&lt;br /&gt;
{{cmd|&amp;lt;nowiki&amp;gt;# mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK&lt;br /&gt;
# nano /etc/X11/xinit/xinitrc&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
In this file, insert:&lt;br /&gt;
{{cat|/etc/X11/xinit/xinitrc|...&lt;br /&gt;
/etc/startup.sh}}&lt;br /&gt;
At the end of {{path|/etc/profile}} (leave the existing file) append&lt;br /&gt;
{{cat|/etc/profile|...&lt;br /&gt;
startx}}&lt;br /&gt;
Remember to run &amp;lt;code&amp;gt;lbu_commit -d&amp;lt;/code&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
For autologin, alpine uses busybox, which has an alias to {{path|/sbin/getty}} as well as {{path|/bin/login}}. It&#039;s possible to navigate to {{path|/sbin/}} or {{path|/bin/}} and run &amp;lt;code&amp;gt;/sbin/getty -h&amp;lt;/code&amp;gt; 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:&lt;br /&gt;
{{cat|/etc/inittab|&amp;lt;nowiki&amp;gt;# Set up a couple of gettys&lt;br /&gt;
#tty1::respawn:/sbin/getty 38400 tty1&lt;br /&gt;
tty2::respawn:/sbin/getty 38400 tty2&lt;br /&gt;
tty3::respawn:/sbin/getty 38400 tty3&lt;br /&gt;
tty4::respawn:/sbin/getty 38400 tty4&lt;br /&gt;
tty5::respawn:/sbin/getty 38400 tty5&lt;br /&gt;
tty6::respawn:/sbin/getty 38400 tty6&lt;br /&gt;
&lt;br /&gt;
tty1::respawn:/bin/login -f root&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Disable Screensaver, and refresh webpage (optional)===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/X11/xorg.conf|&lt;br /&gt;
Section &amp;quot;Extensions&amp;quot;&lt;br /&gt;
    Option      &amp;quot;DPMS&amp;quot; &amp;quot;Disable&amp;quot;&lt;br /&gt;
EndSection}} &lt;br /&gt;
&lt;br /&gt;
{{cmd|# apk add {{pkg|xdotool|arch=a*}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# crontab -u root -e &lt;br /&gt;
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Note: xset is not an option here as it&#039;s not included by default. It can be installed from the repositories, if needed.&amp;lt;/small&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
That&#039;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&#039;ll have even more resources available.&lt;br /&gt;
&lt;br /&gt;
==Digital Signage==&lt;br /&gt;
It&#039;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? &lt;br /&gt;
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd). &lt;br /&gt;
# There is no requirement to use &#039;cloud&#039; services, or an internet connection. &lt;br /&gt;
# You have full control over the build and design (all kiosk build steps are documented &amp;amp; have a small learning curve, compared to some of the more complex projects mentioned above).&lt;br /&gt;
# Free software. No recurring costs (outside of optional maintenance). &lt;br /&gt;
# No ties to external infrastructure / frameworks. Full freedom.&lt;br /&gt;
&lt;br /&gt;
In this addition to the guide above, we&#039;ll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we&#039;ll also run a web server with PHP, which hosts the resources we want to display on the sign.&lt;br /&gt;
Make sure community apk is enabled in {{path|/etc/apk/repositories}}&lt;br /&gt;
{{cmd|# apk add {{pkg|chromium|arch=a*}}}}&lt;br /&gt;
In {{path|/etc/startup.sh}} add chromium instead of firefox:&lt;br /&gt;
{{cat|/etc/startup.sh|&amp;lt;nowiki&amp;gt;...&lt;br /&gt;
chromium-browser --home-page http://127.0.0.1/resource --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you deploy the device on a TV, and you&#039;re unsure what resolution it is, you can access the resolution from the terminal (not in X), by using &lt;br /&gt;
{{cmd|# xrandr -d :0}}&lt;br /&gt;
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&#039;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&#039;s config.h, But a WM is not required.&lt;br /&gt;
&lt;br /&gt;
Make sure to run &amp;lt;code&amp;gt;lbu_commit -d&amp;lt;/code&amp;gt;, in order to save any changes as needed in the apkvol on the SD or HDD storage.&lt;br /&gt;
&lt;br /&gt;
===Install Apache/PHP===&lt;br /&gt;
See [[Apache]].&lt;br /&gt;
&lt;br /&gt;
===Install xset to disable screensaver===&lt;br /&gt;
{{cmd|# apk add {{pkg|xset|arch=a*}}&lt;br /&gt;
&amp;amp;num; xset q&lt;br /&gt;
&amp;amp;num; xset s off&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Hide Scrollbars of Browser===&lt;br /&gt;
This can be done with CSS.&lt;br /&gt;
 body {&lt;br /&gt;
   overflow: hidden; /* Hide scrollbars */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
===Why was this setup used? Why not Awesome, or dwm?===&lt;br /&gt;
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&#039;t have this limitation. It should be possible to get more RAM via {{path|/boot/config.txt}}&lt;br /&gt;
&lt;br /&gt;
If your application doesn&#039;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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Width &amp;amp; height of firefox doesn&#039;t fit the monitor===&lt;br /&gt;
Firefox can be called with -height and -width flags, e.g. &lt;br /&gt;
{{cmd|firefox -width 480 -height 640 example.org}}&lt;br /&gt;
&lt;br /&gt;
===Periodic Firefox Crashes on RPI3 due to Low Memory===&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
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 &amp;gt;1GB ram which may eliminate the need for a nightly reboot.&lt;br /&gt;
&lt;br /&gt;
===Firefox-esr segmentation fault on x86 for 3.17===&lt;br /&gt;
In running firefox on an old intel atom netbook, I see firefox having a &#039;segmentation fault&#039; 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.&lt;br /&gt;
===How do I easily backup my diskless system?===&lt;br /&gt;
You should backup the apkvol which is located in /media/mmc (the location of the sd card).&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* [[dwm]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=27631</id>
		<title>ZoneMinder video camera security and surveillance</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=27631"/>
		<updated>2024-10-24T11:43:43Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* Related Links */ I didn&amp;#039;t need to add this link before.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://www.zoneminder.com/ ZoneMinder] usually runs with [[Apache]], but in this short how-to we use [[Lighttpd]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Base Install==&lt;br /&gt;
&lt;br /&gt;
ZoneMinder is found in the community repositories, please enable it by following the instructions [[Repositories#Enabling_the_community_repository|here]]&lt;br /&gt;
&lt;br /&gt;
Then, add the needed packages to our system&lt;br /&gt;
&lt;br /&gt;
 apk add zoneminder mariadb mysql-client lighttpd php8-fpm php8-pdo php8-pdo_mysql&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: In Alpine 3.17, php 8.1 replaces php8.0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 apk add zoneminder mariadb mysql-client lighttpd php81-fpm php81-pdo php81-pdo_mysql&lt;br /&gt;
&lt;br /&gt;
===Database===&lt;br /&gt;
&lt;br /&gt;
Initialize [https://www.mysql.com/ MySQL] database&lt;br /&gt;
&lt;br /&gt;
 rc-service mariadb setup&lt;br /&gt;
&lt;br /&gt;
Start the database&lt;br /&gt;
&lt;br /&gt;
 rc-service mariadb start&lt;br /&gt;
&lt;br /&gt;
Set root password for MySQL as instructed by MySQL setup&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mysqladmin -u root password &#039;your_secure_root_mysql_password&#039;&lt;br /&gt;
&lt;br /&gt;
You can log into MySQL as current root user with&lt;br /&gt;
 mysql&lt;br /&gt;
&lt;br /&gt;
Create a ZoneMinder MySQL database and user&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; create database zm;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; CREATE USER zmuser@localhost IDENTIFIED BY &#039;your_zm_password_as_set_in_config&#039;;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; grant ALL on zm.* to zmuser@localhost;&lt;br /&gt;
&lt;br /&gt;
===Web Server===&lt;br /&gt;
&lt;br /&gt;
We are running &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;, so let&#039;s run &amp;lt;code&amp;gt;php-fpm&amp;lt;/code&amp;gt; as lighttpd user/group&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php8/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: for php 8.1&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php81/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
Add this section to the bottom of the file:&lt;br /&gt;
&lt;br /&gt;
 ; Unix user/group of processes&lt;br /&gt;
 ; Note: The user is mandatory. If the group is not set, the default user&#039;s group&lt;br /&gt;
 ;       will be used.&lt;br /&gt;
 ;user = nobody&lt;br /&gt;
 ;group = nobody&lt;br /&gt;
 user = lighttpd&lt;br /&gt;
 group = lighttpd&lt;br /&gt;
&lt;br /&gt;
Enable the php cgi fpm config in &amp;lt;code&amp;gt;lighttpd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
Go down to the server modules section and uncomment &amp;lt;code&amp;gt;mod_alias&amp;lt;/code&amp;gt;, which is needed for the cgi-bin, and &amp;lt;code&amp;gt;mod_rewrite&amp;lt;/code&amp;gt;, for the api. It should look like:&lt;br /&gt;
&lt;br /&gt;
 # {{{ modules&lt;br /&gt;
 # At the very least, mod_access and mod_accesslog should be enabled.&lt;br /&gt;
 # All other modules should only be loaded if necessary.&lt;br /&gt;
 # NOTE: the order of modules is important.&lt;br /&gt;
 server.modules = (&lt;br /&gt;
      &amp;quot;mod_rewrite&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_redirect&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_alias&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_access&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_cml&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_trigger_b4_dl&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_auth&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_status&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_setenv&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_proxy&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_simple_vhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_evhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_userdir&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_deflate&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_ssi&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_usertrack&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_expire&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_secdownload&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_rrdtool&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_webdav&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_accesslog&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
Go down to the includes section, it should look like:&lt;br /&gt;
 # {{{ includes&lt;br /&gt;
 include &amp;quot;mime-types.conf&amp;quot;&lt;br /&gt;
 # uncomment for cgi support&lt;br /&gt;
    include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi support&lt;br /&gt;
 #   include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi fpm support&lt;br /&gt;
    include &amp;quot;mod_fastcgi_fpm.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
In order for video streaming to work in 1.36, you&#039;ll need the following&lt;br /&gt;
added to /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
 server.stream-response-body = 1&lt;br /&gt;
&lt;br /&gt;
In lighttpd.conf for the API, we will want to redirect any api+ requests to cakephp. Thus, add:&lt;br /&gt;
 url.rewrite = (&lt;br /&gt;
       &amp;quot;^/zm/api(.+)$&amp;quot;           =&amp;gt;              &amp;quot;/zm/api/index.php&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Edit lighttpd cgi config and add old style cgi support by adding to cgi.assign&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/mod_cgi.conf&lt;br /&gt;
&lt;br /&gt;
which should look like&lt;br /&gt;
&lt;br /&gt;
 cgi.assign = (&lt;br /&gt;
     &amp;quot;&amp;quot;      =&amp;gt;      &amp;quot;&amp;quot;,&lt;br /&gt;
     &amp;quot;.pl&amp;quot;   =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
     &amp;quot;.cgi&amp;quot;  =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Also add the following to alias.url in mod_cgi.conf so that it looks like&lt;br /&gt;
&lt;br /&gt;
 alias.url = (&lt;br /&gt;
     &amp;quot;/cgi-bin/&amp;quot;            =&amp;gt;      var.basedir + &amp;quot;/cgi-bin/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/api&amp;quot;              =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/api/app/webroot/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/&amp;quot;                 =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Remove the symlink in /var/www/localhost/htdocs (we will be using the alias, not the symlink). &lt;br /&gt;
 unlink /var/www/localhost/htdocs/zm&lt;br /&gt;
&lt;br /&gt;
Start php-fpm&lt;br /&gt;
&lt;br /&gt;
 rc-service php-fpm8 start&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note:&#039;&#039; for php-fpm81, use the following command:&lt;br /&gt;
&lt;br /&gt;
 rc-service php-fpm81 start&lt;br /&gt;
&lt;br /&gt;
Start lighttpd&lt;br /&gt;
&lt;br /&gt;
 rc-service lighttpd start&lt;br /&gt;
&lt;br /&gt;
===Zoneminder===&lt;br /&gt;
&lt;br /&gt;
Set the MySQL hostname, username, password.&lt;br /&gt;
&lt;br /&gt;
Change the ZoneMinder user (&amp;lt;code&amp;gt;ZM_WEB_USER&amp;lt;/code&amp;gt;) and group (&amp;lt;code&amp;gt;ZM_WEB_GROUP&amp;lt;/code&amp;gt;) to lighttpd&lt;br /&gt;
&lt;br /&gt;
And set &amp;lt;code&amp;gt;ZM_SERVER_HOST&amp;lt;/code&amp;gt; to your ZoneMinder hostname/ipaddress&lt;br /&gt;
&lt;br /&gt;
 vi /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Which should look like:&lt;br /&gt;
&lt;br /&gt;
 # Username and group that web daemon (httpd/apache) runs as&lt;br /&gt;
 ZM_WEB_USER=lighttpd&lt;br /&gt;
 ZM_WEB_GROUP=lighttpd&lt;br /&gt;
 ZM_PATH_DATA=/usr/share/zoneminder&lt;br /&gt;
&lt;br /&gt;
 # ZoneMinder database type: so far only mysql is supported&lt;br /&gt;
 ZM_DB_TYPE=mysql&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database hostname or ip address&lt;br /&gt;
 ZM_DB_HOST=localhost&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database name&lt;br /&gt;
 ZM_DB_NAME=zm&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database user&lt;br /&gt;
 ZM_DB_USER=zmuser&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database password&lt;br /&gt;
 ZM_DB_PASS=your_zm_password_as_set_in_config&lt;br /&gt;
 &lt;br /&gt;
 # Host of this machine&lt;br /&gt;
 ZM_SERVER_HOST=yourserver&lt;br /&gt;
&lt;br /&gt;
Change ownership of &amp;lt;code&amp;gt;zm.conf&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 chown lighttpd.lighttpd /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Zoneminder will create a cache in &amp;lt;code&amp;gt;/var/cache/zoneminder&amp;lt;/code&amp;gt; which isn&#039;t created by default. Create this directory and allow lighttpd access to it. Note that if you are using a diskless install, you must lbu add /var/cache/zoneminder.&lt;br /&gt;
&lt;br /&gt;
 mkdir /var/cache/zoneminder&lt;br /&gt;
 chown lighttpd.lighttpd /var/cache/zoneminder&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Initialize the ZoneMinder database&lt;br /&gt;
&lt;br /&gt;
 rc-service zoneminder setup&lt;br /&gt;
&lt;br /&gt;
Start ZoneMinder&lt;br /&gt;
&lt;br /&gt;
 rc-service zoneminder start&lt;br /&gt;
&lt;br /&gt;
Profit!&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
To access ZoneMinder, browse to &amp;lt;nowiki&amp;gt;http://yourserver/zm/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To test the API, run&lt;br /&gt;
 curl -X GET  &amp;lt;nowiki&amp;gt;http://yourserver/zm/api/host/getVersion.json&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
(This assumes you aren&#039;t using authentication.)&lt;br /&gt;
&lt;br /&gt;
To make it start automatically on boot:&lt;br /&gt;
&lt;br /&gt;
 rc-update add lighttpd default&lt;br /&gt;
 rc-update add mariadb default&lt;br /&gt;
 rc-update add php-fpm8 default&lt;br /&gt;
 rc-update add zoneminder default&lt;br /&gt;
&lt;br /&gt;
== Added notes to work with Nginx ==&lt;br /&gt;
Later to add some notes about running via nginx&lt;br /&gt;
&lt;br /&gt;
[[Category:Software]]&lt;br /&gt;
[[Category:Security]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22821</id>
		<title>Raspberry Pi 3 - Browser Client</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22821"/>
		<updated>2022-12-28T09:21:42Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* Disable Screensaver, and refresh webpage (optional) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;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.&lt;br /&gt;
&lt;br /&gt;
Current revision rough tested with 3.17 (on x86). For earlier releases, please see history.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This guide uses the following:&lt;br /&gt;
* aarch64 img (though this guide is also tested to be roughly x86-compatible)&lt;br /&gt;
* Raspberry Pi3 &lt;br /&gt;
* community repo.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
See https://pkgs.alpinelinux.org/packages?name=*firefox*&amp;amp;branch=v3.11&amp;amp;arch=aarch64&lt;br /&gt;
&lt;br /&gt;
Note: the aarch64 build is not compatible with all Raspberry Pi models. See [[Raspberry Pi]].&lt;br /&gt;
&lt;br /&gt;
==Steps==&lt;br /&gt;
===Base Install===&lt;br /&gt;
&lt;br /&gt;
These steps are duplicated from the [[Raspberry_Pi]] page. (Note that for sake of this guide, it&#039;s assumed the RPI is a RAM only install. Although there is no requirement for it to be done this way).&lt;br /&gt;
&lt;br /&gt;
Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem. &lt;br /&gt;
e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Command (m for help): p&lt;br /&gt;
Disk /dev/sdb: 59.5 GiB, 63864569856 bytes, 124735488 sectors&lt;br /&gt;
Units: sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disklabel type: dos&lt;br /&gt;
Disk identifier: 0x00000000&lt;br /&gt;
&lt;br /&gt;
Device     Boot Start      End  Sectors Size Id Type&lt;br /&gt;
/dev/sdb1  *     2048 62916607 62914560  30G  b W95 FAT32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 mkdosfs -F 32 /dev/sdX1&lt;br /&gt;
&lt;br /&gt;
untar onto mounted disk&lt;br /&gt;
&lt;br /&gt;
 mount /dev/sdX1 /mnt/folder&lt;br /&gt;
 tar xvf archive.tar -C /mnt/folder/.&lt;br /&gt;
&lt;br /&gt;
If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other&lt;br /&gt;
config settings, do so in usercfg.txt now.&lt;br /&gt;
&lt;br /&gt;
Again, duplicating the [[Raspberry Pi]] page &lt;br /&gt;
&lt;br /&gt;
    Insert the SD card into the Raspberry Pi and turn it on&lt;br /&gt;
    Log in to Alpine as root. Leave the password empty.&lt;br /&gt;
    Type setup-alpine, hit enter.&lt;br /&gt;
    Once the installation is complete, commit the changes by typing lbu commit -d&lt;br /&gt;
&lt;br /&gt;
Things to keep in mind:&lt;br /&gt;
* 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. &lt;br /&gt;
* For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with &amp;quot;No disks available, try boot media /mmcblk0p1&amp;quot;. Select the default [n]. If you make a mistake during the install, you can always reimage and start over.&lt;br /&gt;
&lt;br /&gt;
Saving space: busybox instead of chronyd, dropbear instead of openssh&lt;br /&gt;
&lt;br /&gt;
After setup, make sure dropbear is installed&lt;br /&gt;
 apk add dropbear&lt;br /&gt;
&lt;br /&gt;
Start it:&lt;br /&gt;
 rc-service dropbear start&lt;br /&gt;
&lt;br /&gt;
Add it to the default runlevel:&lt;br /&gt;
 rc-update add dropbear&lt;br /&gt;
&lt;br /&gt;
If you need an accurate clock, enable software/ntp here. (this step is optional)&lt;br /&gt;
 rc-update add swclock boot # enable the software clock &lt;br /&gt;
 rc-update del hwclock boot # disable the hardware clock&lt;br /&gt;
 setup-ntp&lt;br /&gt;
&lt;br /&gt;
===Browser Client Install===&lt;br /&gt;
&lt;br /&gt;
Enable community repo (/etc/apk/repositories) (uncomment community)&lt;br /&gt;
 nano /etc/apk/repositories&lt;br /&gt;
 apk update&lt;br /&gt;
&lt;br /&gt;
install firefox dependencies:&lt;br /&gt;
 apk add libx11-dev libxft-dev libxinerama-dev ttf-dejavu&lt;br /&gt;
&amp;lt;small&amp;gt;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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the amount of RAM tmp fs available can be viewed while installing with: watch df -h&lt;br /&gt;
&lt;br /&gt;
install firefox&lt;br /&gt;
 apk add firefox-esr&lt;br /&gt;
install X&lt;br /&gt;
 setup-xorg-base&lt;br /&gt;
The RPI also requires for X:&lt;br /&gt;
 apk add xf86-video-fbdev&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;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 &amp;quot;apk search libEGL.so&amp;quot; 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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, we have about 421MB of RAM used (if NTP was not set up).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
devtmpfs                 10.0M         0     10.0M   0% /dev&lt;br /&gt;
shm                     457.9M         0    457.9M   0% /dev/shm&lt;br /&gt;
/dev/mmcblk0p1           30.0G    259.4M     29.7G   1% /media/mmcblk0p1&lt;br /&gt;
tmpfs                   457.9M    420.0M     37.9M  92% /&lt;br /&gt;
tmpfs                    91.6M    188.0K     91.4M   0% /run&lt;br /&gt;
/dev/loop0               24.9M     24.9M         0 100% /.modloop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 lbu_commit -d&lt;br /&gt;
&lt;br /&gt;
===AutoLogin, Startx automatically on Boot===&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to login as root, and run startx manually. Now we&#039;ll add configuration files to enable that without user interaction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;What is happening here from my understanding is:&lt;br /&gt;
 1) User logs in. /etc/profile is run (which includes a call to startx)&lt;br /&gt;
 2) Startx references any relevant xinitrc (user folder or /etc/X11), which calls /etc/startup.sh&lt;br /&gt;
 3) /etc/startup.sh runs any commands, such as dwm, firefox, or chromium.&lt;br /&gt;
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 &amp;quot;logger&amp;quot; in shell scripts.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/root/ doesn&#039;t save any files, so it&#039;s necessary to edit files in /etc/ and run lbu_commit -d after all changes. First let&#039;s add a file that we&#039;ll call firefox.&lt;br /&gt;
&amp;lt;small&amp;gt;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&lt;br /&gt;
also see: /etc/apk/protected_paths.d/lbu.list&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
create a file named /etc/startup.sh:&lt;br /&gt;
 #!/bin/ash&lt;br /&gt;
 firefox-esr &amp;lt;nowiki&amp;gt;http://awebsite.com&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!!!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.&lt;br /&gt;
&lt;br /&gt;
Make sure the file is executable.&lt;br /&gt;
 chmod +x /etc/startup.sh&lt;br /&gt;
&lt;br /&gt;
We have to edit xinitrc, and the profile configs. Normally, this would be done in the user&#039;s directory, but here we will use the globals for simplicity. Note that here we are &#039;moving&#039; 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).&lt;br /&gt;
 mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK&lt;br /&gt;
 nano /etc/X11/xinit/xinitrc&lt;br /&gt;
In this file, insert:&lt;br /&gt;
 /etc/startup.sh&lt;br /&gt;
At the end of /etc/profile (leave the existing file) append&lt;br /&gt;
 startx&lt;br /&gt;
Remember to run lbu_commit -d&amp;lt;BR&amp;gt;&lt;br /&gt;
For autologin, alpine uses busybox, which has an alias to /sbin/getty as well as /bin/login. It&#039;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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Set up a couple of gettys&lt;br /&gt;
#tty1::respawn:/sbin/getty 38400 tty1&lt;br /&gt;
tty2::respawn:/sbin/getty 38400 tty2&lt;br /&gt;
tty3::respawn:/sbin/getty 38400 tty3&lt;br /&gt;
tty4::respawn:/sbin/getty 38400 tty4&lt;br /&gt;
tty5::respawn:/sbin/getty 38400 tty5&lt;br /&gt;
tty6::respawn:/sbin/getty 38400 tty6&lt;br /&gt;
&lt;br /&gt;
tty1::respawn:/bin/login -f root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Disable Screensaver, and refresh webpage (optional)===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/X11/xorg.conf|&lt;br /&gt;
Section &amp;quot;Extensions&amp;quot;&lt;br /&gt;
    Option      &amp;quot;DPMS&amp;quot; &amp;quot;Disable&amp;quot;&lt;br /&gt;
EndSection}} &lt;br /&gt;
&lt;br /&gt;
{{cmd|# apk add xdotool}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# crontab -u root -e &lt;br /&gt;
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Note: xset is not an option here as it&#039;s not included by default. It can be installed from the repositories, if needed.&amp;lt;/small&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
That&#039;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&#039;ll have even more resources available.&lt;br /&gt;
&lt;br /&gt;
==Digital Signage==&lt;br /&gt;
It&#039;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? &lt;br /&gt;
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd). &lt;br /&gt;
# There is no requirement to use &#039;cloud&#039; services, or an internet connection. &lt;br /&gt;
# You have full control over the build and design (all kiosk build steps are documented &amp;amp; have a small learning curve, compared to some of the more complex projects mentioned above).&lt;br /&gt;
# Free software. No recurring costs (outside of optional maintenance). &lt;br /&gt;
# No ties to external infrastructure / frameworks. Full freedom.&lt;br /&gt;
&lt;br /&gt;
In this addition to the guide above, we&#039;ll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we&#039;ll also run a web server with PHP, which hosts the resources we want to display on the sign.&lt;br /&gt;
Make sure community apk is enabled in /etc/apk/repositories&lt;br /&gt;
 apk add chromium&lt;br /&gt;
In /etc/startup.sh add chromium instead of firefox:&lt;br /&gt;
  chromium-browser --home-page &amp;lt;nowiki&amp;gt;http://127.0.0.1/resource&amp;lt;/nowiki&amp;gt; --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you deploy the device on a TV, and you&#039;re unsure what resolution it is, you can access the resolution from the terminal (not in X), by using &lt;br /&gt;
 xrandr -d :0&lt;br /&gt;
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&#039;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&#039;s config.h, But a WM is not required.&lt;br /&gt;
&lt;br /&gt;
Make sure to run lbu_commit -d, in order to save any changes as needed in the apkvol on the SD or HDD storage.&lt;br /&gt;
&lt;br /&gt;
===Install Apache/PHP===&lt;br /&gt;
See [[Apache]].&lt;br /&gt;
&lt;br /&gt;
===Install xset to disable screensaver===&lt;br /&gt;
 apk add xset&lt;br /&gt;
 xset q&lt;br /&gt;
 xset s off&lt;br /&gt;
&lt;br /&gt;
===Hide Scrollbars of Browser===&lt;br /&gt;
This can be done with CSS.&lt;br /&gt;
 body {&lt;br /&gt;
   overflow: hidden; /* Hide scrollbars */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
===Why was this setup used? Why not Awesome, or dwm?===&lt;br /&gt;
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&#039;t have this limitation. It should be possible to get more RAM via /boot/config.txt&lt;br /&gt;
&lt;br /&gt;
If your application doesn&#039;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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Width &amp;amp; height of firefox doesn&#039;t fit the monitor===&lt;br /&gt;
Firefox can be called with -height and -width flags, e.g. &lt;br /&gt;
{{cmd|firefox -width 480 -height 640 example.org}}&lt;br /&gt;
&lt;br /&gt;
===Periodic Firefox Crashes on RPI3 due to Low Memory===&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
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 &amp;gt;1GB ram which may eliminate the need for a nightly reboot.&lt;br /&gt;
&lt;br /&gt;
===Firefox-esr segmentation fault on x86 for 3.17===&lt;br /&gt;
In running firefox on an old intel atom netbook, I see firefox having a &#039;segmentation fault&#039; 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.&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* [[dwm]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22820</id>
		<title>Raspberry Pi 3 - Browser Client</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22820"/>
		<updated>2022-12-28T09:20:52Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* AutoLogin, Startx automatically on Boot */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;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.&lt;br /&gt;
&lt;br /&gt;
Current revision rough tested with 3.17 (on x86). For earlier releases, please see history.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This guide uses the following:&lt;br /&gt;
* aarch64 img (though this guide is also tested to be roughly x86-compatible)&lt;br /&gt;
* Raspberry Pi3 &lt;br /&gt;
* community repo.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
See https://pkgs.alpinelinux.org/packages?name=*firefox*&amp;amp;branch=v3.11&amp;amp;arch=aarch64&lt;br /&gt;
&lt;br /&gt;
Note: the aarch64 build is not compatible with all Raspberry Pi models. See [[Raspberry Pi]].&lt;br /&gt;
&lt;br /&gt;
==Steps==&lt;br /&gt;
===Base Install===&lt;br /&gt;
&lt;br /&gt;
These steps are duplicated from the [[Raspberry_Pi]] page. (Note that for sake of this guide, it&#039;s assumed the RPI is a RAM only install. Although there is no requirement for it to be done this way).&lt;br /&gt;
&lt;br /&gt;
Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem. &lt;br /&gt;
e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Command (m for help): p&lt;br /&gt;
Disk /dev/sdb: 59.5 GiB, 63864569856 bytes, 124735488 sectors&lt;br /&gt;
Units: sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disklabel type: dos&lt;br /&gt;
Disk identifier: 0x00000000&lt;br /&gt;
&lt;br /&gt;
Device     Boot Start      End  Sectors Size Id Type&lt;br /&gt;
/dev/sdb1  *     2048 62916607 62914560  30G  b W95 FAT32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 mkdosfs -F 32 /dev/sdX1&lt;br /&gt;
&lt;br /&gt;
untar onto mounted disk&lt;br /&gt;
&lt;br /&gt;
 mount /dev/sdX1 /mnt/folder&lt;br /&gt;
 tar xvf archive.tar -C /mnt/folder/.&lt;br /&gt;
&lt;br /&gt;
If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other&lt;br /&gt;
config settings, do so in usercfg.txt now.&lt;br /&gt;
&lt;br /&gt;
Again, duplicating the [[Raspberry Pi]] page &lt;br /&gt;
&lt;br /&gt;
    Insert the SD card into the Raspberry Pi and turn it on&lt;br /&gt;
    Log in to Alpine as root. Leave the password empty.&lt;br /&gt;
    Type setup-alpine, hit enter.&lt;br /&gt;
    Once the installation is complete, commit the changes by typing lbu commit -d&lt;br /&gt;
&lt;br /&gt;
Things to keep in mind:&lt;br /&gt;
* 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. &lt;br /&gt;
* For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with &amp;quot;No disks available, try boot media /mmcblk0p1&amp;quot;. Select the default [n]. If you make a mistake during the install, you can always reimage and start over.&lt;br /&gt;
&lt;br /&gt;
Saving space: busybox instead of chronyd, dropbear instead of openssh&lt;br /&gt;
&lt;br /&gt;
After setup, make sure dropbear is installed&lt;br /&gt;
 apk add dropbear&lt;br /&gt;
&lt;br /&gt;
Start it:&lt;br /&gt;
 rc-service dropbear start&lt;br /&gt;
&lt;br /&gt;
Add it to the default runlevel:&lt;br /&gt;
 rc-update add dropbear&lt;br /&gt;
&lt;br /&gt;
If you need an accurate clock, enable software/ntp here. (this step is optional)&lt;br /&gt;
 rc-update add swclock boot # enable the software clock &lt;br /&gt;
 rc-update del hwclock boot # disable the hardware clock&lt;br /&gt;
 setup-ntp&lt;br /&gt;
&lt;br /&gt;
===Browser Client Install===&lt;br /&gt;
&lt;br /&gt;
Enable community repo (/etc/apk/repositories) (uncomment community)&lt;br /&gt;
 nano /etc/apk/repositories&lt;br /&gt;
 apk update&lt;br /&gt;
&lt;br /&gt;
install firefox dependencies:&lt;br /&gt;
 apk add libx11-dev libxft-dev libxinerama-dev ttf-dejavu&lt;br /&gt;
&amp;lt;small&amp;gt;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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the amount of RAM tmp fs available can be viewed while installing with: watch df -h&lt;br /&gt;
&lt;br /&gt;
install firefox&lt;br /&gt;
 apk add firefox-esr&lt;br /&gt;
install X&lt;br /&gt;
 setup-xorg-base&lt;br /&gt;
The RPI also requires for X:&lt;br /&gt;
 apk add xf86-video-fbdev&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;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 &amp;quot;apk search libEGL.so&amp;quot; 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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, we have about 421MB of RAM used (if NTP was not set up).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
devtmpfs                 10.0M         0     10.0M   0% /dev&lt;br /&gt;
shm                     457.9M         0    457.9M   0% /dev/shm&lt;br /&gt;
/dev/mmcblk0p1           30.0G    259.4M     29.7G   1% /media/mmcblk0p1&lt;br /&gt;
tmpfs                   457.9M    420.0M     37.9M  92% /&lt;br /&gt;
tmpfs                    91.6M    188.0K     91.4M   0% /run&lt;br /&gt;
/dev/loop0               24.9M     24.9M         0 100% /.modloop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 lbu_commit -d&lt;br /&gt;
&lt;br /&gt;
===AutoLogin, Startx automatically on Boot===&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to login as root, and run startx manually. Now we&#039;ll add configuration files to enable that without user interaction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;What is happening here from my understanding is:&lt;br /&gt;
 1) User logs in. /etc/profile is run (which includes a call to startx)&lt;br /&gt;
 2) Startx references any relevant xinitrc (user folder or /etc/X11), which calls /etc/startup.sh&lt;br /&gt;
 3) /etc/startup.sh runs any commands, such as dwm, firefox, or chromium.&lt;br /&gt;
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 &amp;quot;logger&amp;quot; in shell scripts.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/root/ doesn&#039;t save any files, so it&#039;s necessary to edit files in /etc/ and run lbu_commit -d after all changes. First let&#039;s add a file that we&#039;ll call firefox.&lt;br /&gt;
&amp;lt;small&amp;gt;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&lt;br /&gt;
also see: /etc/apk/protected_paths.d/lbu.list&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
create a file named /etc/startup.sh:&lt;br /&gt;
 #!/bin/ash&lt;br /&gt;
 firefox-esr &amp;lt;nowiki&amp;gt;http://awebsite.com&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!!!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.&lt;br /&gt;
&lt;br /&gt;
Make sure the file is executable.&lt;br /&gt;
 chmod +x /etc/startup.sh&lt;br /&gt;
&lt;br /&gt;
We have to edit xinitrc, and the profile configs. Normally, this would be done in the user&#039;s directory, but here we will use the globals for simplicity. Note that here we are &#039;moving&#039; 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).&lt;br /&gt;
 mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK&lt;br /&gt;
 nano /etc/X11/xinit/xinitrc&lt;br /&gt;
In this file, insert:&lt;br /&gt;
 /etc/startup.sh&lt;br /&gt;
At the end of /etc/profile (leave the existing file) append&lt;br /&gt;
 startx&lt;br /&gt;
Remember to run lbu_commit -d&amp;lt;BR&amp;gt;&lt;br /&gt;
For autologin, alpine uses busybox, which has an alias to /sbin/getty as well as /bin/login. It&#039;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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Set up a couple of gettys&lt;br /&gt;
#tty1::respawn:/sbin/getty 38400 tty1&lt;br /&gt;
tty2::respawn:/sbin/getty 38400 tty2&lt;br /&gt;
tty3::respawn:/sbin/getty 38400 tty3&lt;br /&gt;
tty4::respawn:/sbin/getty 38400 tty4&lt;br /&gt;
tty5::respawn:/sbin/getty 38400 tty5&lt;br /&gt;
tty6::respawn:/sbin/getty 38400 tty6&lt;br /&gt;
&lt;br /&gt;
tty1::respawn:/bin/login -f root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Disable Screensaver, and refresh webpage (optional)===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/X11/xorg.conf|&lt;br /&gt;
Section &amp;quot;Extensions&amp;quot;&lt;br /&gt;
    Option      &amp;quot;DPMS&amp;quot; &amp;quot;Disable&amp;quot;&lt;br /&gt;
EndSection}} &lt;br /&gt;
&lt;br /&gt;
{{cmd|# apk add xdotool}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# crontab -u root -e &lt;br /&gt;
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Note: xset is not an option here as it&#039;s not included by default. It can be installed from the repositories, if needed.&amp;lt;/small&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
That&#039;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.&lt;br /&gt;
&lt;br /&gt;
==Digital Signage==&lt;br /&gt;
It&#039;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? &lt;br /&gt;
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd). &lt;br /&gt;
# There is no requirement to use &#039;cloud&#039; services, or an internet connection. &lt;br /&gt;
# You have full control over the build and design (all kiosk build steps are documented &amp;amp; have a small learning curve, compared to some of the more complex projects mentioned above).&lt;br /&gt;
# Free software. No recurring costs (outside of optional maintenance). &lt;br /&gt;
# No ties to external infrastructure / frameworks. Full freedom.&lt;br /&gt;
&lt;br /&gt;
In this addition to the guide above, we&#039;ll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we&#039;ll also run a web server with PHP, which hosts the resources we want to display on the sign.&lt;br /&gt;
Make sure community apk is enabled in /etc/apk/repositories&lt;br /&gt;
 apk add chromium&lt;br /&gt;
In /etc/startup.sh add chromium instead of firefox:&lt;br /&gt;
  chromium-browser --home-page &amp;lt;nowiki&amp;gt;http://127.0.0.1/resource&amp;lt;/nowiki&amp;gt; --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you deploy the device on a TV, and you&#039;re unsure what resolution it is, you can access the resolution from the terminal (not in X), by using &lt;br /&gt;
 xrandr -d :0&lt;br /&gt;
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&#039;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&#039;s config.h, But a WM is not required.&lt;br /&gt;
&lt;br /&gt;
Make sure to run lbu_commit -d, in order to save any changes as needed in the apkvol on the SD or HDD storage.&lt;br /&gt;
&lt;br /&gt;
===Install Apache/PHP===&lt;br /&gt;
See [[Apache]].&lt;br /&gt;
&lt;br /&gt;
===Install xset to disable screensaver===&lt;br /&gt;
 apk add xset&lt;br /&gt;
 xset q&lt;br /&gt;
 xset s off&lt;br /&gt;
&lt;br /&gt;
===Hide Scrollbars of Browser===&lt;br /&gt;
This can be done with CSS.&lt;br /&gt;
 body {&lt;br /&gt;
   overflow: hidden; /* Hide scrollbars */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
===Why was this setup used? Why not Awesome, or dwm?===&lt;br /&gt;
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&#039;t have this limitation. It should be possible to get more RAM via /boot/config.txt&lt;br /&gt;
&lt;br /&gt;
If your application doesn&#039;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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Width &amp;amp; height of firefox doesn&#039;t fit the monitor===&lt;br /&gt;
Firefox can be called with -height and -width flags, e.g. &lt;br /&gt;
{{cmd|firefox -width 480 -height 640 example.org}}&lt;br /&gt;
&lt;br /&gt;
===Periodic Firefox Crashes on RPI3 due to Low Memory===&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
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 &amp;gt;1GB ram which may eliminate the need for a nightly reboot.&lt;br /&gt;
&lt;br /&gt;
===Firefox-esr segmentation fault on x86 for 3.17===&lt;br /&gt;
In running firefox on an old intel atom netbook, I see firefox having a &#039;segmentation fault&#039; 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.&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* [[dwm]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22819</id>
		<title>Raspberry Pi 3 - Browser Client</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22819"/>
		<updated>2022-12-28T09:20:27Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* AutoLogin, Startx automatically on Boot */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;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.&lt;br /&gt;
&lt;br /&gt;
Current revision rough tested with 3.17 (on x86). For earlier releases, please see history.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This guide uses the following:&lt;br /&gt;
* aarch64 img (though this guide is also tested to be roughly x86-compatible)&lt;br /&gt;
* Raspberry Pi3 &lt;br /&gt;
* community repo.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
See https://pkgs.alpinelinux.org/packages?name=*firefox*&amp;amp;branch=v3.11&amp;amp;arch=aarch64&lt;br /&gt;
&lt;br /&gt;
Note: the aarch64 build is not compatible with all Raspberry Pi models. See [[Raspberry Pi]].&lt;br /&gt;
&lt;br /&gt;
==Steps==&lt;br /&gt;
===Base Install===&lt;br /&gt;
&lt;br /&gt;
These steps are duplicated from the [[Raspberry_Pi]] page. (Note that for sake of this guide, it&#039;s assumed the RPI is a RAM only install. Although there is no requirement for it to be done this way).&lt;br /&gt;
&lt;br /&gt;
Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem. &lt;br /&gt;
e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Command (m for help): p&lt;br /&gt;
Disk /dev/sdb: 59.5 GiB, 63864569856 bytes, 124735488 sectors&lt;br /&gt;
Units: sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disklabel type: dos&lt;br /&gt;
Disk identifier: 0x00000000&lt;br /&gt;
&lt;br /&gt;
Device     Boot Start      End  Sectors Size Id Type&lt;br /&gt;
/dev/sdb1  *     2048 62916607 62914560  30G  b W95 FAT32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 mkdosfs -F 32 /dev/sdX1&lt;br /&gt;
&lt;br /&gt;
untar onto mounted disk&lt;br /&gt;
&lt;br /&gt;
 mount /dev/sdX1 /mnt/folder&lt;br /&gt;
 tar xvf archive.tar -C /mnt/folder/.&lt;br /&gt;
&lt;br /&gt;
If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other&lt;br /&gt;
config settings, do so in usercfg.txt now.&lt;br /&gt;
&lt;br /&gt;
Again, duplicating the [[Raspberry Pi]] page &lt;br /&gt;
&lt;br /&gt;
    Insert the SD card into the Raspberry Pi and turn it on&lt;br /&gt;
    Log in to Alpine as root. Leave the password empty.&lt;br /&gt;
    Type setup-alpine, hit enter.&lt;br /&gt;
    Once the installation is complete, commit the changes by typing lbu commit -d&lt;br /&gt;
&lt;br /&gt;
Things to keep in mind:&lt;br /&gt;
* 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. &lt;br /&gt;
* For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with &amp;quot;No disks available, try boot media /mmcblk0p1&amp;quot;. Select the default [n]. If you make a mistake during the install, you can always reimage and start over.&lt;br /&gt;
&lt;br /&gt;
Saving space: busybox instead of chronyd, dropbear instead of openssh&lt;br /&gt;
&lt;br /&gt;
After setup, make sure dropbear is installed&lt;br /&gt;
 apk add dropbear&lt;br /&gt;
&lt;br /&gt;
Start it:&lt;br /&gt;
 rc-service dropbear start&lt;br /&gt;
&lt;br /&gt;
Add it to the default runlevel:&lt;br /&gt;
 rc-update add dropbear&lt;br /&gt;
&lt;br /&gt;
If you need an accurate clock, enable software/ntp here. (this step is optional)&lt;br /&gt;
 rc-update add swclock boot # enable the software clock &lt;br /&gt;
 rc-update del hwclock boot # disable the hardware clock&lt;br /&gt;
 setup-ntp&lt;br /&gt;
&lt;br /&gt;
===Browser Client Install===&lt;br /&gt;
&lt;br /&gt;
Enable community repo (/etc/apk/repositories) (uncomment community)&lt;br /&gt;
 nano /etc/apk/repositories&lt;br /&gt;
 apk update&lt;br /&gt;
&lt;br /&gt;
install firefox dependencies:&lt;br /&gt;
 apk add libx11-dev libxft-dev libxinerama-dev ttf-dejavu&lt;br /&gt;
&amp;lt;small&amp;gt;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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the amount of RAM tmp fs available can be viewed while installing with: watch df -h&lt;br /&gt;
&lt;br /&gt;
install firefox&lt;br /&gt;
 apk add firefox-esr&lt;br /&gt;
install X&lt;br /&gt;
 setup-xorg-base&lt;br /&gt;
The RPI also requires for X:&lt;br /&gt;
 apk add xf86-video-fbdev&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;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 &amp;quot;apk search libEGL.so&amp;quot; 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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, we have about 421MB of RAM used (if NTP was not set up).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
devtmpfs                 10.0M         0     10.0M   0% /dev&lt;br /&gt;
shm                     457.9M         0    457.9M   0% /dev/shm&lt;br /&gt;
/dev/mmcblk0p1           30.0G    259.4M     29.7G   1% /media/mmcblk0p1&lt;br /&gt;
tmpfs                   457.9M    420.0M     37.9M  92% /&lt;br /&gt;
tmpfs                    91.6M    188.0K     91.4M   0% /run&lt;br /&gt;
/dev/loop0               24.9M     24.9M         0 100% /.modloop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 lbu_commit -d&lt;br /&gt;
&lt;br /&gt;
===AutoLogin, Startx automatically on Boot===&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to login as root, and run startx manually. Now we&#039;ll add configuration files to enable that without user interaction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;What is happening here from my understanding is:&lt;br /&gt;
 1) User logs in. /etc/profile is run (which includes a call to startx)&lt;br /&gt;
 2) Startx references any relevant xinitrc (user folder or /etc/X11), which calls /etc/startup.sh&lt;br /&gt;
 3) /etc/startup.sh runs any commands, such as dwm, firefox, or chromium.&lt;br /&gt;
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 commands to logger in shell scripts.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/root/ doesn&#039;t save any files, so it&#039;s necessary to edit files in /etc/ and run lbu_commit -d after all changes. First let&#039;s add a file that we&#039;ll call firefox.&lt;br /&gt;
&amp;lt;small&amp;gt;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&lt;br /&gt;
also see: /etc/apk/protected_paths.d/lbu.list&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
create a file named /etc/startup.sh:&lt;br /&gt;
 #!/bin/ash&lt;br /&gt;
 firefox-esr &amp;lt;nowiki&amp;gt;http://awebsite.com&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!!!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.&lt;br /&gt;
&lt;br /&gt;
Make sure the file is executable.&lt;br /&gt;
 chmod +x /etc/startup.sh&lt;br /&gt;
&lt;br /&gt;
We have to edit xinitrc, and the profile configs. Normally, this would be done in the user&#039;s directory, but here we will use the globals for simplicity. Note that here we are &#039;moving&#039; 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).&lt;br /&gt;
 mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK&lt;br /&gt;
 nano /etc/X11/xinit/xinitrc&lt;br /&gt;
In this file, insert:&lt;br /&gt;
 /etc/startup.sh&lt;br /&gt;
At the end of /etc/profile (leave the existing file) append&lt;br /&gt;
 startx&lt;br /&gt;
Remember to run lbu_commit -d&amp;lt;BR&amp;gt;&lt;br /&gt;
For autologin, alpine uses busybox, which has an alias to /sbin/getty as well as /bin/login. It&#039;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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Set up a couple of gettys&lt;br /&gt;
#tty1::respawn:/sbin/getty 38400 tty1&lt;br /&gt;
tty2::respawn:/sbin/getty 38400 tty2&lt;br /&gt;
tty3::respawn:/sbin/getty 38400 tty3&lt;br /&gt;
tty4::respawn:/sbin/getty 38400 tty4&lt;br /&gt;
tty5::respawn:/sbin/getty 38400 tty5&lt;br /&gt;
tty6::respawn:/sbin/getty 38400 tty6&lt;br /&gt;
&lt;br /&gt;
tty1::respawn:/bin/login -f root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Disable Screensaver, and refresh webpage (optional)===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/X11/xorg.conf|&lt;br /&gt;
Section &amp;quot;Extensions&amp;quot;&lt;br /&gt;
    Option      &amp;quot;DPMS&amp;quot; &amp;quot;Disable&amp;quot;&lt;br /&gt;
EndSection}} &lt;br /&gt;
&lt;br /&gt;
{{cmd|# apk add xdotool}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# crontab -u root -e &lt;br /&gt;
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Note: xset is not an option here as it&#039;s not included by default. It can be installed from the repositories, if needed.&amp;lt;/small&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
That&#039;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.&lt;br /&gt;
&lt;br /&gt;
==Digital Signage==&lt;br /&gt;
It&#039;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? &lt;br /&gt;
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd). &lt;br /&gt;
# There is no requirement to use &#039;cloud&#039; services, or an internet connection. &lt;br /&gt;
# You have full control over the build and design (all kiosk build steps are documented &amp;amp; have a small learning curve, compared to some of the more complex projects mentioned above).&lt;br /&gt;
# Free software. No recurring costs (outside of optional maintenance). &lt;br /&gt;
# No ties to external infrastructure / frameworks. Full freedom.&lt;br /&gt;
&lt;br /&gt;
In this addition to the guide above, we&#039;ll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we&#039;ll also run a web server with PHP, which hosts the resources we want to display on the sign.&lt;br /&gt;
Make sure community apk is enabled in /etc/apk/repositories&lt;br /&gt;
 apk add chromium&lt;br /&gt;
In /etc/startup.sh add chromium instead of firefox:&lt;br /&gt;
  chromium-browser --home-page &amp;lt;nowiki&amp;gt;http://127.0.0.1/resource&amp;lt;/nowiki&amp;gt; --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you deploy the device on a TV, and you&#039;re unsure what resolution it is, you can access the resolution from the terminal (not in X), by using &lt;br /&gt;
 xrandr -d :0&lt;br /&gt;
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&#039;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&#039;s config.h, But a WM is not required.&lt;br /&gt;
&lt;br /&gt;
Make sure to run lbu_commit -d, in order to save any changes as needed in the apkvol on the SD or HDD storage.&lt;br /&gt;
&lt;br /&gt;
===Install Apache/PHP===&lt;br /&gt;
See [[Apache]].&lt;br /&gt;
&lt;br /&gt;
===Install xset to disable screensaver===&lt;br /&gt;
 apk add xset&lt;br /&gt;
 xset q&lt;br /&gt;
 xset s off&lt;br /&gt;
&lt;br /&gt;
===Hide Scrollbars of Browser===&lt;br /&gt;
This can be done with CSS.&lt;br /&gt;
 body {&lt;br /&gt;
   overflow: hidden; /* Hide scrollbars */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
===Why was this setup used? Why not Awesome, or dwm?===&lt;br /&gt;
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&#039;t have this limitation. It should be possible to get more RAM via /boot/config.txt&lt;br /&gt;
&lt;br /&gt;
If your application doesn&#039;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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Width &amp;amp; height of firefox doesn&#039;t fit the monitor===&lt;br /&gt;
Firefox can be called with -height and -width flags, e.g. &lt;br /&gt;
{{cmd|firefox -width 480 -height 640 example.org}}&lt;br /&gt;
&lt;br /&gt;
===Periodic Firefox Crashes on RPI3 due to Low Memory===&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
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 &amp;gt;1GB ram which may eliminate the need for a nightly reboot.&lt;br /&gt;
&lt;br /&gt;
===Firefox-esr segmentation fault on x86 for 3.17===&lt;br /&gt;
In running firefox on an old intel atom netbook, I see firefox having a &#039;segmentation fault&#039; 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.&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* [[dwm]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22818</id>
		<title>Raspberry Pi 3 - Browser Client</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22818"/>
		<updated>2022-12-28T09:19:27Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* Firefox-esr segmentation fault on x86 for 3.17 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;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.&lt;br /&gt;
&lt;br /&gt;
Current revision rough tested with 3.17 (on x86). For earlier releases, please see history.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This guide uses the following:&lt;br /&gt;
* aarch64 img (though this guide is also tested to be roughly x86-compatible)&lt;br /&gt;
* Raspberry Pi3 &lt;br /&gt;
* community repo.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
See https://pkgs.alpinelinux.org/packages?name=*firefox*&amp;amp;branch=v3.11&amp;amp;arch=aarch64&lt;br /&gt;
&lt;br /&gt;
Note: the aarch64 build is not compatible with all Raspberry Pi models. See [[Raspberry Pi]].&lt;br /&gt;
&lt;br /&gt;
==Steps==&lt;br /&gt;
===Base Install===&lt;br /&gt;
&lt;br /&gt;
These steps are duplicated from the [[Raspberry_Pi]] page. (Note that for sake of this guide, it&#039;s assumed the RPI is a RAM only install. Although there is no requirement for it to be done this way).&lt;br /&gt;
&lt;br /&gt;
Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem. &lt;br /&gt;
e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Command (m for help): p&lt;br /&gt;
Disk /dev/sdb: 59.5 GiB, 63864569856 bytes, 124735488 sectors&lt;br /&gt;
Units: sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disklabel type: dos&lt;br /&gt;
Disk identifier: 0x00000000&lt;br /&gt;
&lt;br /&gt;
Device     Boot Start      End  Sectors Size Id Type&lt;br /&gt;
/dev/sdb1  *     2048 62916607 62914560  30G  b W95 FAT32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 mkdosfs -F 32 /dev/sdX1&lt;br /&gt;
&lt;br /&gt;
untar onto mounted disk&lt;br /&gt;
&lt;br /&gt;
 mount /dev/sdX1 /mnt/folder&lt;br /&gt;
 tar xvf archive.tar -C /mnt/folder/.&lt;br /&gt;
&lt;br /&gt;
If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other&lt;br /&gt;
config settings, do so in usercfg.txt now.&lt;br /&gt;
&lt;br /&gt;
Again, duplicating the [[Raspberry Pi]] page &lt;br /&gt;
&lt;br /&gt;
    Insert the SD card into the Raspberry Pi and turn it on&lt;br /&gt;
    Log in to Alpine as root. Leave the password empty.&lt;br /&gt;
    Type setup-alpine, hit enter.&lt;br /&gt;
    Once the installation is complete, commit the changes by typing lbu commit -d&lt;br /&gt;
&lt;br /&gt;
Things to keep in mind:&lt;br /&gt;
* 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. &lt;br /&gt;
* For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with &amp;quot;No disks available, try boot media /mmcblk0p1&amp;quot;. Select the default [n]. If you make a mistake during the install, you can always reimage and start over.&lt;br /&gt;
&lt;br /&gt;
Saving space: busybox instead of chronyd, dropbear instead of openssh&lt;br /&gt;
&lt;br /&gt;
After setup, make sure dropbear is installed&lt;br /&gt;
 apk add dropbear&lt;br /&gt;
&lt;br /&gt;
Start it:&lt;br /&gt;
 rc-service dropbear start&lt;br /&gt;
&lt;br /&gt;
Add it to the default runlevel:&lt;br /&gt;
 rc-update add dropbear&lt;br /&gt;
&lt;br /&gt;
If you need an accurate clock, enable software/ntp here. (this step is optional)&lt;br /&gt;
 rc-update add swclock boot # enable the software clock &lt;br /&gt;
 rc-update del hwclock boot # disable the hardware clock&lt;br /&gt;
 setup-ntp&lt;br /&gt;
&lt;br /&gt;
===Browser Client Install===&lt;br /&gt;
&lt;br /&gt;
Enable community repo (/etc/apk/repositories) (uncomment community)&lt;br /&gt;
 nano /etc/apk/repositories&lt;br /&gt;
 apk update&lt;br /&gt;
&lt;br /&gt;
install firefox dependencies:&lt;br /&gt;
 apk add libx11-dev libxft-dev libxinerama-dev ttf-dejavu&lt;br /&gt;
&amp;lt;small&amp;gt;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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the amount of RAM tmp fs available can be viewed while installing with: watch df -h&lt;br /&gt;
&lt;br /&gt;
install firefox&lt;br /&gt;
 apk add firefox-esr&lt;br /&gt;
install X&lt;br /&gt;
 setup-xorg-base&lt;br /&gt;
The RPI also requires for X:&lt;br /&gt;
 apk add xf86-video-fbdev&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;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 &amp;quot;apk search libEGL.so&amp;quot; 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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, we have about 421MB of RAM used (if NTP was not set up).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
devtmpfs                 10.0M         0     10.0M   0% /dev&lt;br /&gt;
shm                     457.9M         0    457.9M   0% /dev/shm&lt;br /&gt;
/dev/mmcblk0p1           30.0G    259.4M     29.7G   1% /media/mmcblk0p1&lt;br /&gt;
tmpfs                   457.9M    420.0M     37.9M  92% /&lt;br /&gt;
tmpfs                    91.6M    188.0K     91.4M   0% /run&lt;br /&gt;
/dev/loop0               24.9M     24.9M         0 100% /.modloop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 lbu_commit -d&lt;br /&gt;
&lt;br /&gt;
===AutoLogin, Startx automatically on Boot===&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to login as root, and run startx manually. Now we&#039;ll add configuration files to enable that without user interaction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;What is happening here from my understanding is:&lt;br /&gt;
 1) User logs in. /etc/profile is run (which includes a call to startx)&lt;br /&gt;
 2) Startx references any relevant xinitrc (user folder or /etc/X11), which calls /etc/startup.sh&lt;br /&gt;
 3) /etc/startup.sh runs any commands, such as dwm, firefox, or chromium.&lt;br /&gt;
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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/root/ doesn&#039;t save any files, so it&#039;s necessary to edit files in /etc/ and run lbu_commit -d after all changes. First let&#039;s add a file that we&#039;ll call firefox.&lt;br /&gt;
&amp;lt;small&amp;gt;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&lt;br /&gt;
also see: /etc/apk/protected_paths.d/lbu.list&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
create a file named /etc/startup.sh:&lt;br /&gt;
 #!/bin/ash&lt;br /&gt;
 firefox-esr &amp;lt;nowiki&amp;gt;http://awebsite.com&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!!!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.&lt;br /&gt;
&lt;br /&gt;
Make sure the file is executable.&lt;br /&gt;
 chmod +x /etc/startup.sh&lt;br /&gt;
&lt;br /&gt;
We have to edit xinitrc, and the profile configs. Normally, this would be done in the user&#039;s directory, but here we will use the globals for simplicity. Note that here we are &#039;moving&#039; 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).&lt;br /&gt;
 mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK&lt;br /&gt;
 nano /etc/X11/xinit/xinitrc&lt;br /&gt;
In this file, insert:&lt;br /&gt;
 /etc/startup.sh&lt;br /&gt;
At the end of /etc/profile (leave the existing file) append&lt;br /&gt;
 startx&lt;br /&gt;
Remember to run lbu_commit -d&amp;lt;BR&amp;gt;&lt;br /&gt;
For autologin, alpine uses busybox, which has an alias to /sbin/getty as well as /bin/login. It&#039;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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Set up a couple of gettys&lt;br /&gt;
#tty1::respawn:/sbin/getty 38400 tty1&lt;br /&gt;
tty2::respawn:/sbin/getty 38400 tty2&lt;br /&gt;
tty3::respawn:/sbin/getty 38400 tty3&lt;br /&gt;
tty4::respawn:/sbin/getty 38400 tty4&lt;br /&gt;
tty5::respawn:/sbin/getty 38400 tty5&lt;br /&gt;
tty6::respawn:/sbin/getty 38400 tty6&lt;br /&gt;
&lt;br /&gt;
tty1::respawn:/bin/login -f root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Disable Screensaver, and refresh webpage (optional)===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/X11/xorg.conf|&lt;br /&gt;
Section &amp;quot;Extensions&amp;quot;&lt;br /&gt;
    Option      &amp;quot;DPMS&amp;quot; &amp;quot;Disable&amp;quot;&lt;br /&gt;
EndSection}} &lt;br /&gt;
&lt;br /&gt;
{{cmd|# apk add xdotool}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# crontab -u root -e &lt;br /&gt;
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Note: xset is not an option here as it&#039;s not included by default. It can be installed from the repositories, if needed.&amp;lt;/small&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
That&#039;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.&lt;br /&gt;
&lt;br /&gt;
==Digital Signage==&lt;br /&gt;
It&#039;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? &lt;br /&gt;
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd). &lt;br /&gt;
# There is no requirement to use &#039;cloud&#039; services, or an internet connection. &lt;br /&gt;
# You have full control over the build and design (all kiosk build steps are documented &amp;amp; have a small learning curve, compared to some of the more complex projects mentioned above).&lt;br /&gt;
# Free software. No recurring costs (outside of optional maintenance). &lt;br /&gt;
# No ties to external infrastructure / frameworks. Full freedom.&lt;br /&gt;
&lt;br /&gt;
In this addition to the guide above, we&#039;ll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we&#039;ll also run a web server with PHP, which hosts the resources we want to display on the sign.&lt;br /&gt;
Make sure community apk is enabled in /etc/apk/repositories&lt;br /&gt;
 apk add chromium&lt;br /&gt;
In /etc/startup.sh add chromium instead of firefox:&lt;br /&gt;
  chromium-browser --home-page &amp;lt;nowiki&amp;gt;http://127.0.0.1/resource&amp;lt;/nowiki&amp;gt; --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you deploy the device on a TV, and you&#039;re unsure what resolution it is, you can access the resolution from the terminal (not in X), by using &lt;br /&gt;
 xrandr -d :0&lt;br /&gt;
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&#039;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&#039;s config.h, But a WM is not required.&lt;br /&gt;
&lt;br /&gt;
Make sure to run lbu_commit -d, in order to save any changes as needed in the apkvol on the SD or HDD storage.&lt;br /&gt;
&lt;br /&gt;
===Install Apache/PHP===&lt;br /&gt;
See [[Apache]].&lt;br /&gt;
&lt;br /&gt;
===Install xset to disable screensaver===&lt;br /&gt;
 apk add xset&lt;br /&gt;
 xset q&lt;br /&gt;
 xset s off&lt;br /&gt;
&lt;br /&gt;
===Hide Scrollbars of Browser===&lt;br /&gt;
This can be done with CSS.&lt;br /&gt;
 body {&lt;br /&gt;
   overflow: hidden; /* Hide scrollbars */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
===Why was this setup used? Why not Awesome, or dwm?===&lt;br /&gt;
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&#039;t have this limitation. It should be possible to get more RAM via /boot/config.txt&lt;br /&gt;
&lt;br /&gt;
If your application doesn&#039;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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Width &amp;amp; height of firefox doesn&#039;t fit the monitor===&lt;br /&gt;
Firefox can be called with -height and -width flags, e.g. &lt;br /&gt;
{{cmd|firefox -width 480 -height 640 example.org}}&lt;br /&gt;
&lt;br /&gt;
===Periodic Firefox Crashes on RPI3 due to Low Memory===&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
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 &amp;gt;1GB ram which may eliminate the need for a nightly reboot.&lt;br /&gt;
&lt;br /&gt;
===Firefox-esr segmentation fault on x86 for 3.17===&lt;br /&gt;
In running firefox on an old intel atom netbook, I see firefox having a &#039;segmentation fault&#039; 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.&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* [[dwm]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22817</id>
		<title>Raspberry Pi 3 - Browser Client</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22817"/>
		<updated>2022-12-28T09:18:57Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* Tips/Troubleshooting */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;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.&lt;br /&gt;
&lt;br /&gt;
Current revision rough tested with 3.17 (on x86). For earlier releases, please see history.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This guide uses the following:&lt;br /&gt;
* aarch64 img (though this guide is also tested to be roughly x86-compatible)&lt;br /&gt;
* Raspberry Pi3 &lt;br /&gt;
* community repo.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
See https://pkgs.alpinelinux.org/packages?name=*firefox*&amp;amp;branch=v3.11&amp;amp;arch=aarch64&lt;br /&gt;
&lt;br /&gt;
Note: the aarch64 build is not compatible with all Raspberry Pi models. See [[Raspberry Pi]].&lt;br /&gt;
&lt;br /&gt;
==Steps==&lt;br /&gt;
===Base Install===&lt;br /&gt;
&lt;br /&gt;
These steps are duplicated from the [[Raspberry_Pi]] page. (Note that for sake of this guide, it&#039;s assumed the RPI is a RAM only install. Although there is no requirement for it to be done this way).&lt;br /&gt;
&lt;br /&gt;
Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem. &lt;br /&gt;
e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Command (m for help): p&lt;br /&gt;
Disk /dev/sdb: 59.5 GiB, 63864569856 bytes, 124735488 sectors&lt;br /&gt;
Units: sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disklabel type: dos&lt;br /&gt;
Disk identifier: 0x00000000&lt;br /&gt;
&lt;br /&gt;
Device     Boot Start      End  Sectors Size Id Type&lt;br /&gt;
/dev/sdb1  *     2048 62916607 62914560  30G  b W95 FAT32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 mkdosfs -F 32 /dev/sdX1&lt;br /&gt;
&lt;br /&gt;
untar onto mounted disk&lt;br /&gt;
&lt;br /&gt;
 mount /dev/sdX1 /mnt/folder&lt;br /&gt;
 tar xvf archive.tar -C /mnt/folder/.&lt;br /&gt;
&lt;br /&gt;
If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other&lt;br /&gt;
config settings, do so in usercfg.txt now.&lt;br /&gt;
&lt;br /&gt;
Again, duplicating the [[Raspberry Pi]] page &lt;br /&gt;
&lt;br /&gt;
    Insert the SD card into the Raspberry Pi and turn it on&lt;br /&gt;
    Log in to Alpine as root. Leave the password empty.&lt;br /&gt;
    Type setup-alpine, hit enter.&lt;br /&gt;
    Once the installation is complete, commit the changes by typing lbu commit -d&lt;br /&gt;
&lt;br /&gt;
Things to keep in mind:&lt;br /&gt;
* 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. &lt;br /&gt;
* For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with &amp;quot;No disks available, try boot media /mmcblk0p1&amp;quot;. Select the default [n]. If you make a mistake during the install, you can always reimage and start over.&lt;br /&gt;
&lt;br /&gt;
Saving space: busybox instead of chronyd, dropbear instead of openssh&lt;br /&gt;
&lt;br /&gt;
After setup, make sure dropbear is installed&lt;br /&gt;
 apk add dropbear&lt;br /&gt;
&lt;br /&gt;
Start it:&lt;br /&gt;
 rc-service dropbear start&lt;br /&gt;
&lt;br /&gt;
Add it to the default runlevel:&lt;br /&gt;
 rc-update add dropbear&lt;br /&gt;
&lt;br /&gt;
If you need an accurate clock, enable software/ntp here. (this step is optional)&lt;br /&gt;
 rc-update add swclock boot # enable the software clock &lt;br /&gt;
 rc-update del hwclock boot # disable the hardware clock&lt;br /&gt;
 setup-ntp&lt;br /&gt;
&lt;br /&gt;
===Browser Client Install===&lt;br /&gt;
&lt;br /&gt;
Enable community repo (/etc/apk/repositories) (uncomment community)&lt;br /&gt;
 nano /etc/apk/repositories&lt;br /&gt;
 apk update&lt;br /&gt;
&lt;br /&gt;
install firefox dependencies:&lt;br /&gt;
 apk add libx11-dev libxft-dev libxinerama-dev ttf-dejavu&lt;br /&gt;
&amp;lt;small&amp;gt;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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the amount of RAM tmp fs available can be viewed while installing with: watch df -h&lt;br /&gt;
&lt;br /&gt;
install firefox&lt;br /&gt;
 apk add firefox-esr&lt;br /&gt;
install X&lt;br /&gt;
 setup-xorg-base&lt;br /&gt;
The RPI also requires for X:&lt;br /&gt;
 apk add xf86-video-fbdev&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;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 &amp;quot;apk search libEGL.so&amp;quot; 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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, we have about 421MB of RAM used (if NTP was not set up).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
devtmpfs                 10.0M         0     10.0M   0% /dev&lt;br /&gt;
shm                     457.9M         0    457.9M   0% /dev/shm&lt;br /&gt;
/dev/mmcblk0p1           30.0G    259.4M     29.7G   1% /media/mmcblk0p1&lt;br /&gt;
tmpfs                   457.9M    420.0M     37.9M  92% /&lt;br /&gt;
tmpfs                    91.6M    188.0K     91.4M   0% /run&lt;br /&gt;
/dev/loop0               24.9M     24.9M         0 100% /.modloop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 lbu_commit -d&lt;br /&gt;
&lt;br /&gt;
===AutoLogin, Startx automatically on Boot===&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to login as root, and run startx manually. Now we&#039;ll add configuration files to enable that without user interaction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;What is happening here from my understanding is:&lt;br /&gt;
 1) User logs in. /etc/profile is run (which includes a call to startx)&lt;br /&gt;
 2) Startx references any relevant xinitrc (user folder or /etc/X11), which calls /etc/startup.sh&lt;br /&gt;
 3) /etc/startup.sh runs any commands, such as dwm, firefox, or chromium.&lt;br /&gt;
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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/root/ doesn&#039;t save any files, so it&#039;s necessary to edit files in /etc/ and run lbu_commit -d after all changes. First let&#039;s add a file that we&#039;ll call firefox.&lt;br /&gt;
&amp;lt;small&amp;gt;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&lt;br /&gt;
also see: /etc/apk/protected_paths.d/lbu.list&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
create a file named /etc/startup.sh:&lt;br /&gt;
 #!/bin/ash&lt;br /&gt;
 firefox-esr &amp;lt;nowiki&amp;gt;http://awebsite.com&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!!!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.&lt;br /&gt;
&lt;br /&gt;
Make sure the file is executable.&lt;br /&gt;
 chmod +x /etc/startup.sh&lt;br /&gt;
&lt;br /&gt;
We have to edit xinitrc, and the profile configs. Normally, this would be done in the user&#039;s directory, but here we will use the globals for simplicity. Note that here we are &#039;moving&#039; 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).&lt;br /&gt;
 mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK&lt;br /&gt;
 nano /etc/X11/xinit/xinitrc&lt;br /&gt;
In this file, insert:&lt;br /&gt;
 /etc/startup.sh&lt;br /&gt;
At the end of /etc/profile (leave the existing file) append&lt;br /&gt;
 startx&lt;br /&gt;
Remember to run lbu_commit -d&amp;lt;BR&amp;gt;&lt;br /&gt;
For autologin, alpine uses busybox, which has an alias to /sbin/getty as well as /bin/login. It&#039;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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Set up a couple of gettys&lt;br /&gt;
#tty1::respawn:/sbin/getty 38400 tty1&lt;br /&gt;
tty2::respawn:/sbin/getty 38400 tty2&lt;br /&gt;
tty3::respawn:/sbin/getty 38400 tty3&lt;br /&gt;
tty4::respawn:/sbin/getty 38400 tty4&lt;br /&gt;
tty5::respawn:/sbin/getty 38400 tty5&lt;br /&gt;
tty6::respawn:/sbin/getty 38400 tty6&lt;br /&gt;
&lt;br /&gt;
tty1::respawn:/bin/login -f root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Disable Screensaver, and refresh webpage (optional)===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/X11/xorg.conf|&lt;br /&gt;
Section &amp;quot;Extensions&amp;quot;&lt;br /&gt;
    Option      &amp;quot;DPMS&amp;quot; &amp;quot;Disable&amp;quot;&lt;br /&gt;
EndSection}} &lt;br /&gt;
&lt;br /&gt;
{{cmd|# apk add xdotool}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# crontab -u root -e &lt;br /&gt;
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Note: xset is not an option here as it&#039;s not included by default. It can be installed from the repositories, if needed.&amp;lt;/small&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
That&#039;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.&lt;br /&gt;
&lt;br /&gt;
==Digital Signage==&lt;br /&gt;
It&#039;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? &lt;br /&gt;
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd). &lt;br /&gt;
# There is no requirement to use &#039;cloud&#039; services, or an internet connection. &lt;br /&gt;
# You have full control over the build and design (all kiosk build steps are documented &amp;amp; have a small learning curve, compared to some of the more complex projects mentioned above).&lt;br /&gt;
# Free software. No recurring costs (outside of optional maintenance). &lt;br /&gt;
# No ties to external infrastructure / frameworks. Full freedom.&lt;br /&gt;
&lt;br /&gt;
In this addition to the guide above, we&#039;ll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we&#039;ll also run a web server with PHP, which hosts the resources we want to display on the sign.&lt;br /&gt;
Make sure community apk is enabled in /etc/apk/repositories&lt;br /&gt;
 apk add chromium&lt;br /&gt;
In /etc/startup.sh add chromium instead of firefox:&lt;br /&gt;
  chromium-browser --home-page &amp;lt;nowiki&amp;gt;http://127.0.0.1/resource&amp;lt;/nowiki&amp;gt; --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you deploy the device on a TV, and you&#039;re unsure what resolution it is, you can access the resolution from the terminal (not in X), by using &lt;br /&gt;
 xrandr -d :0&lt;br /&gt;
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&#039;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&#039;s config.h, But a WM is not required.&lt;br /&gt;
&lt;br /&gt;
Make sure to run lbu_commit -d, in order to save any changes as needed in the apkvol on the SD or HDD storage.&lt;br /&gt;
&lt;br /&gt;
===Install Apache/PHP===&lt;br /&gt;
See [[Apache]].&lt;br /&gt;
&lt;br /&gt;
===Install xset to disable screensaver===&lt;br /&gt;
 apk add xset&lt;br /&gt;
 xset q&lt;br /&gt;
 xset s off&lt;br /&gt;
&lt;br /&gt;
===Hide Scrollbars of Browser===&lt;br /&gt;
This can be done with CSS.&lt;br /&gt;
 body {&lt;br /&gt;
   overflow: hidden; /* Hide scrollbars */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
===Why was this setup used? Why not Awesome, or dwm?===&lt;br /&gt;
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&#039;t have this limitation. It should be possible to get more RAM via /boot/config.txt&lt;br /&gt;
&lt;br /&gt;
If your application doesn&#039;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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Width &amp;amp; height of firefox doesn&#039;t fit the monitor===&lt;br /&gt;
Firefox can be called with -height and -width flags, e.g. &lt;br /&gt;
{{cmd|firefox -width 480 -height 640 example.org}}&lt;br /&gt;
&lt;br /&gt;
===Periodic Firefox Crashes on RPI3 due to Low Memory===&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
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 &amp;gt;1GB ram which may eliminate the need for a nightly reboot.&lt;br /&gt;
&lt;br /&gt;
===Firefox-esr segmentation fault on x86 for 3.17===&lt;br /&gt;
In running firefox on an old intel atom netbook, I see firefox having a &#039;segmentation fault&#039; when trying to run. However dwm works. This may be due to the netbook being x86. Chromium is x86-64 only in pkgs.alpinelinux.org so something to keep in mind when allocating for a given setup.&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* [[dwm]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22816</id>
		<title>Raspberry Pi 3 - Browser Client</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22816"/>
		<updated>2022-12-28T09:16:54Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;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.&lt;br /&gt;
&lt;br /&gt;
Current revision rough tested with 3.17 (on x86). For earlier releases, please see history.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This guide uses the following:&lt;br /&gt;
* aarch64 img (though this guide is also tested to be roughly x86-compatible)&lt;br /&gt;
* Raspberry Pi3 &lt;br /&gt;
* community repo.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
See https://pkgs.alpinelinux.org/packages?name=*firefox*&amp;amp;branch=v3.11&amp;amp;arch=aarch64&lt;br /&gt;
&lt;br /&gt;
Note: the aarch64 build is not compatible with all Raspberry Pi models. See [[Raspberry Pi]].&lt;br /&gt;
&lt;br /&gt;
==Steps==&lt;br /&gt;
===Base Install===&lt;br /&gt;
&lt;br /&gt;
These steps are duplicated from the [[Raspberry_Pi]] page. (Note that for sake of this guide, it&#039;s assumed the RPI is a RAM only install. Although there is no requirement for it to be done this way).&lt;br /&gt;
&lt;br /&gt;
Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem. &lt;br /&gt;
e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Command (m for help): p&lt;br /&gt;
Disk /dev/sdb: 59.5 GiB, 63864569856 bytes, 124735488 sectors&lt;br /&gt;
Units: sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disklabel type: dos&lt;br /&gt;
Disk identifier: 0x00000000&lt;br /&gt;
&lt;br /&gt;
Device     Boot Start      End  Sectors Size Id Type&lt;br /&gt;
/dev/sdb1  *     2048 62916607 62914560  30G  b W95 FAT32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 mkdosfs -F 32 /dev/sdX1&lt;br /&gt;
&lt;br /&gt;
untar onto mounted disk&lt;br /&gt;
&lt;br /&gt;
 mount /dev/sdX1 /mnt/folder&lt;br /&gt;
 tar xvf archive.tar -C /mnt/folder/.&lt;br /&gt;
&lt;br /&gt;
If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other&lt;br /&gt;
config settings, do so in usercfg.txt now.&lt;br /&gt;
&lt;br /&gt;
Again, duplicating the [[Raspberry Pi]] page &lt;br /&gt;
&lt;br /&gt;
    Insert the SD card into the Raspberry Pi and turn it on&lt;br /&gt;
    Log in to Alpine as root. Leave the password empty.&lt;br /&gt;
    Type setup-alpine, hit enter.&lt;br /&gt;
    Once the installation is complete, commit the changes by typing lbu commit -d&lt;br /&gt;
&lt;br /&gt;
Things to keep in mind:&lt;br /&gt;
* 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. &lt;br /&gt;
* For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with &amp;quot;No disks available, try boot media /mmcblk0p1&amp;quot;. Select the default [n]. If you make a mistake during the install, you can always reimage and start over.&lt;br /&gt;
&lt;br /&gt;
Saving space: busybox instead of chronyd, dropbear instead of openssh&lt;br /&gt;
&lt;br /&gt;
After setup, make sure dropbear is installed&lt;br /&gt;
 apk add dropbear&lt;br /&gt;
&lt;br /&gt;
Start it:&lt;br /&gt;
 rc-service dropbear start&lt;br /&gt;
&lt;br /&gt;
Add it to the default runlevel:&lt;br /&gt;
 rc-update add dropbear&lt;br /&gt;
&lt;br /&gt;
If you need an accurate clock, enable software/ntp here. (this step is optional)&lt;br /&gt;
 rc-update add swclock boot # enable the software clock &lt;br /&gt;
 rc-update del hwclock boot # disable the hardware clock&lt;br /&gt;
 setup-ntp&lt;br /&gt;
&lt;br /&gt;
===Browser Client Install===&lt;br /&gt;
&lt;br /&gt;
Enable community repo (/etc/apk/repositories) (uncomment community)&lt;br /&gt;
 nano /etc/apk/repositories&lt;br /&gt;
 apk update&lt;br /&gt;
&lt;br /&gt;
install firefox dependencies:&lt;br /&gt;
 apk add libx11-dev libxft-dev libxinerama-dev ttf-dejavu&lt;br /&gt;
&amp;lt;small&amp;gt;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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the amount of RAM tmp fs available can be viewed while installing with: watch df -h&lt;br /&gt;
&lt;br /&gt;
install firefox&lt;br /&gt;
 apk add firefox-esr&lt;br /&gt;
install X&lt;br /&gt;
 setup-xorg-base&lt;br /&gt;
The RPI also requires for X:&lt;br /&gt;
 apk add xf86-video-fbdev&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;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 &amp;quot;apk search libEGL.so&amp;quot; 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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, we have about 421MB of RAM used (if NTP was not set up).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
devtmpfs                 10.0M         0     10.0M   0% /dev&lt;br /&gt;
shm                     457.9M         0    457.9M   0% /dev/shm&lt;br /&gt;
/dev/mmcblk0p1           30.0G    259.4M     29.7G   1% /media/mmcblk0p1&lt;br /&gt;
tmpfs                   457.9M    420.0M     37.9M  92% /&lt;br /&gt;
tmpfs                    91.6M    188.0K     91.4M   0% /run&lt;br /&gt;
/dev/loop0               24.9M     24.9M         0 100% /.modloop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 lbu_commit -d&lt;br /&gt;
&lt;br /&gt;
===AutoLogin, Startx automatically on Boot===&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to login as root, and run startx manually. Now we&#039;ll add configuration files to enable that without user interaction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;What is happening here from my understanding is:&lt;br /&gt;
 1) User logs in. /etc/profile is run (which includes a call to startx)&lt;br /&gt;
 2) Startx references any relevant xinitrc (user folder or /etc/X11), which calls /etc/startup.sh&lt;br /&gt;
 3) /etc/startup.sh runs any commands, such as dwm, firefox, or chromium.&lt;br /&gt;
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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/root/ doesn&#039;t save any files, so it&#039;s necessary to edit files in /etc/ and run lbu_commit -d after all changes. First let&#039;s add a file that we&#039;ll call firefox.&lt;br /&gt;
&amp;lt;small&amp;gt;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&lt;br /&gt;
also see: /etc/apk/protected_paths.d/lbu.list&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
create a file named /etc/startup.sh:&lt;br /&gt;
 #!/bin/ash&lt;br /&gt;
 firefox-esr &amp;lt;nowiki&amp;gt;http://awebsite.com&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!!!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.&lt;br /&gt;
&lt;br /&gt;
Make sure the file is executable.&lt;br /&gt;
 chmod +x /etc/startup.sh&lt;br /&gt;
&lt;br /&gt;
We have to edit xinitrc, and the profile configs. Normally, this would be done in the user&#039;s directory, but here we will use the globals for simplicity. Note that here we are &#039;moving&#039; 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).&lt;br /&gt;
 mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK&lt;br /&gt;
 nano /etc/X11/xinit/xinitrc&lt;br /&gt;
In this file, insert:&lt;br /&gt;
 /etc/startup.sh&lt;br /&gt;
At the end of /etc/profile (leave the existing file) append&lt;br /&gt;
 startx&lt;br /&gt;
Remember to run lbu_commit -d&amp;lt;BR&amp;gt;&lt;br /&gt;
For autologin, alpine uses busybox, which has an alias to /sbin/getty as well as /bin/login. It&#039;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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Set up a couple of gettys&lt;br /&gt;
#tty1::respawn:/sbin/getty 38400 tty1&lt;br /&gt;
tty2::respawn:/sbin/getty 38400 tty2&lt;br /&gt;
tty3::respawn:/sbin/getty 38400 tty3&lt;br /&gt;
tty4::respawn:/sbin/getty 38400 tty4&lt;br /&gt;
tty5::respawn:/sbin/getty 38400 tty5&lt;br /&gt;
tty6::respawn:/sbin/getty 38400 tty6&lt;br /&gt;
&lt;br /&gt;
tty1::respawn:/bin/login -f root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Disable Screensaver, and refresh webpage (optional)===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/X11/xorg.conf|&lt;br /&gt;
Section &amp;quot;Extensions&amp;quot;&lt;br /&gt;
    Option      &amp;quot;DPMS&amp;quot; &amp;quot;Disable&amp;quot;&lt;br /&gt;
EndSection}} &lt;br /&gt;
&lt;br /&gt;
{{cmd|# apk add xdotool}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# crontab -u root -e &lt;br /&gt;
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Note: xset is not an option here as it&#039;s not included by default. It can be installed from the repositories, if needed.&amp;lt;/small&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
That&#039;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.&lt;br /&gt;
&lt;br /&gt;
==Digital Signage==&lt;br /&gt;
It&#039;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? &lt;br /&gt;
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd). &lt;br /&gt;
# There is no requirement to use &#039;cloud&#039; services, or an internet connection. &lt;br /&gt;
# You have full control over the build and design (all kiosk build steps are documented &amp;amp; have a small learning curve, compared to some of the more complex projects mentioned above).&lt;br /&gt;
# Free software. No recurring costs (outside of optional maintenance). &lt;br /&gt;
# No ties to external infrastructure / frameworks. Full freedom.&lt;br /&gt;
&lt;br /&gt;
In this addition to the guide above, we&#039;ll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we&#039;ll also run a web server with PHP, which hosts the resources we want to display on the sign.&lt;br /&gt;
Make sure community apk is enabled in /etc/apk/repositories&lt;br /&gt;
 apk add chromium&lt;br /&gt;
In /etc/startup.sh add chromium instead of firefox:&lt;br /&gt;
  chromium-browser --home-page &amp;lt;nowiki&amp;gt;http://127.0.0.1/resource&amp;lt;/nowiki&amp;gt; --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you deploy the device on a TV, and you&#039;re unsure what resolution it is, you can access the resolution from the terminal (not in X), by using &lt;br /&gt;
 xrandr -d :0&lt;br /&gt;
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&#039;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&#039;s config.h, But a WM is not required.&lt;br /&gt;
&lt;br /&gt;
Make sure to run lbu_commit -d, in order to save any changes as needed in the apkvol on the SD or HDD storage.&lt;br /&gt;
&lt;br /&gt;
===Install Apache/PHP===&lt;br /&gt;
See [[Apache]].&lt;br /&gt;
&lt;br /&gt;
===Install xset to disable screensaver===&lt;br /&gt;
 apk add xset&lt;br /&gt;
 xset q&lt;br /&gt;
 xset s off&lt;br /&gt;
&lt;br /&gt;
===Hide Scrollbars of Browser===&lt;br /&gt;
This can be done with CSS.&lt;br /&gt;
 body {&lt;br /&gt;
   overflow: hidden; /* Hide scrollbars */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
===Why was this setup used? Why not Awesome, or dwm?===&lt;br /&gt;
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&#039;t have this limitation. It should be possible to get more RAM via /boot/config.txt&lt;br /&gt;
&lt;br /&gt;
If your application doesn&#039;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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Width &amp;amp; height of firefox doesn&#039;t fit the monitor===&lt;br /&gt;
Firefox can be called with -height and -width flags, e.g. &lt;br /&gt;
{{cmd|firefox -width 480 -height 640 example.org}}&lt;br /&gt;
&lt;br /&gt;
===Periodic Firefox Crashes on RPI3 due to Low Memory===&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
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 &amp;gt;1GB ram which may eliminate the need for a nightly reboot.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* [[dwm]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22815</id>
		<title>Raspberry Pi 3 - Browser Client</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22815"/>
		<updated>2022-12-27T14:03:35Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;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.&lt;br /&gt;
&lt;br /&gt;
This guide has been tested with earlier alpine releases, but 3.17 and this guide is a WIP. Use at your own risk.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This guide uses the following:&lt;br /&gt;
* aarch64 img (though this guide is also tested to be roughly x86-compatible)&lt;br /&gt;
* Raspberry Pi3 &lt;br /&gt;
* community repo.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
See https://pkgs.alpinelinux.org/packages?name=*firefox*&amp;amp;branch=v3.11&amp;amp;arch=aarch64&lt;br /&gt;
&lt;br /&gt;
Note: the aarch64 build is not compatible with all Raspberry Pi models. See [[Raspberry Pi]].&lt;br /&gt;
&lt;br /&gt;
==Steps==&lt;br /&gt;
===Base Install===&lt;br /&gt;
&lt;br /&gt;
These steps are duplicated from the [[Raspberry_Pi]] page. (Note that for sake of this guide, it&#039;s assumed the RPI is a RAM only install. Although there is no requirement for it to be done this way).&lt;br /&gt;
&lt;br /&gt;
Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem. &lt;br /&gt;
e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Command (m for help): p&lt;br /&gt;
Disk /dev/sdb: 59.5 GiB, 63864569856 bytes, 124735488 sectors&lt;br /&gt;
Units: sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disklabel type: dos&lt;br /&gt;
Disk identifier: 0x00000000&lt;br /&gt;
&lt;br /&gt;
Device     Boot Start      End  Sectors Size Id Type&lt;br /&gt;
/dev/sdb1  *     2048 62916607 62914560  30G  b W95 FAT32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 mkdosfs -F 32 /dev/sdX1&lt;br /&gt;
&lt;br /&gt;
untar onto mounted disk&lt;br /&gt;
&lt;br /&gt;
 mount /dev/sdX1 /mnt/folder&lt;br /&gt;
 tar xvf archive.tar -C /mnt/folder/.&lt;br /&gt;
&lt;br /&gt;
If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other&lt;br /&gt;
config settings, do so in usercfg.txt now.&lt;br /&gt;
&lt;br /&gt;
Again, duplicating the [[Raspberry Pi]] page &lt;br /&gt;
&lt;br /&gt;
    Insert the SD card into the Raspberry Pi and turn it on&lt;br /&gt;
    Log in to Alpine as root. Leave the password empty.&lt;br /&gt;
    Type setup-alpine, hit enter.&lt;br /&gt;
    Once the installation is complete, commit the changes by typing lbu commit -d&lt;br /&gt;
&lt;br /&gt;
Things to keep in mind:&lt;br /&gt;
* 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. &lt;br /&gt;
* For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with &amp;quot;No disks available, try boot media /mmcblk0p1&amp;quot;. Select the default [n]. If you make a mistake during the install, you can always reimage and start over.&lt;br /&gt;
&lt;br /&gt;
Saving space: busybox instead of chronyd, dropbear instead of openssh&lt;br /&gt;
&lt;br /&gt;
After setup, make sure dropbear is installed&lt;br /&gt;
 apk add dropbear&lt;br /&gt;
&lt;br /&gt;
Start it:&lt;br /&gt;
 rc-service dropbear start&lt;br /&gt;
&lt;br /&gt;
Add it to the default runlevel:&lt;br /&gt;
 rc-update add dropbear&lt;br /&gt;
&lt;br /&gt;
If you need an accurate clock, enable software/ntp here. (this step is optional)&lt;br /&gt;
 rc-update add swclock boot # enable the software clock &lt;br /&gt;
 rc-update del hwclock boot # disable the hardware clock&lt;br /&gt;
 setup-ntp&lt;br /&gt;
&lt;br /&gt;
===Browser Client Install===&lt;br /&gt;
&lt;br /&gt;
Enable community repo (/etc/apk/repositories) (uncomment community)&lt;br /&gt;
 nano /etc/apk/repositories&lt;br /&gt;
 apk update&lt;br /&gt;
&lt;br /&gt;
install firefox dependencies:&lt;br /&gt;
 apk add libx11-dev libxft-dev libxinerama-dev ttf-dejavu&lt;br /&gt;
&amp;lt;small&amp;gt;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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the amount of RAM tmp fs available can be viewed while installing with: watch df -h&lt;br /&gt;
&lt;br /&gt;
install firefox&lt;br /&gt;
 apk add firefox-esr&lt;br /&gt;
install X&lt;br /&gt;
 setup-xorg-base&lt;br /&gt;
The RPI also requires for X:&lt;br /&gt;
 apk add xf86-video-fbdev&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;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 &amp;quot;apk search libEGL.so&amp;quot; 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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, we have about 421MB of RAM used (if NTP was not set up).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
devtmpfs                 10.0M         0     10.0M   0% /dev&lt;br /&gt;
shm                     457.9M         0    457.9M   0% /dev/shm&lt;br /&gt;
/dev/mmcblk0p1           30.0G    259.4M     29.7G   1% /media/mmcblk0p1&lt;br /&gt;
tmpfs                   457.9M    420.0M     37.9M  92% /&lt;br /&gt;
tmpfs                    91.6M    188.0K     91.4M   0% /run&lt;br /&gt;
/dev/loop0               24.9M     24.9M         0 100% /.modloop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 lbu_commit -d&lt;br /&gt;
&lt;br /&gt;
===AutoLogin, Startx automatically on Boot===&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to login as root, and run startx manually. Now we&#039;ll add configuration files to enable that without user interaction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;What is happening here from my understanding is:&lt;br /&gt;
 1) User logs in. /etc/profile is run (which includes a call to startx)&lt;br /&gt;
 2) Startx references any relevant xinitrc (user folder or /etc/X11), which calls /etc/startup.sh&lt;br /&gt;
 3) /etc/startup.sh runs any commands, such as dwm, firefox, or chromium.&lt;br /&gt;
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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/root/ doesn&#039;t save any files, so it&#039;s necessary to edit files in /etc/ and run lbu_commit -d after all changes. First let&#039;s add a file that we&#039;ll call firefox.&lt;br /&gt;
&amp;lt;small&amp;gt;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&lt;br /&gt;
also see: /etc/apk/protected_paths.d/lbu.list&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
create a file named /etc/startup.sh:&lt;br /&gt;
 #!/bin/ash&lt;br /&gt;
 firefox-esr &amp;lt;nowiki&amp;gt;http://awebsite.com&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!!!NOTE: This is ash, not bash. By default, alpine ships with the ash shell. Bash is available in the repositories.&lt;br /&gt;
&lt;br /&gt;
We have to edit xinitrc, and the profile configs. Normally, this would be done in the user&#039;s directory, but here we will use the globals for simplicity.&lt;br /&gt;
 mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK&lt;br /&gt;
 nano /etc/X11/xinit/xinitrc&lt;br /&gt;
In this file, insert:&lt;br /&gt;
 /etc/startup.sh&lt;br /&gt;
At the end of /etc/profile (leave the existing file) append&lt;br /&gt;
 exec startx&lt;br /&gt;
Remember to run lbu_commit -d&amp;lt;BR&amp;gt;&lt;br /&gt;
For autologin, alpine uses busybox, which has an alias to /sbin/getty as well as /bin/login. It&#039;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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Set up a couple of gettys&lt;br /&gt;
#tty1::respawn:/sbin/getty 38400 tty1&lt;br /&gt;
tty2::respawn:/sbin/getty 38400 tty2&lt;br /&gt;
tty3::respawn:/sbin/getty 38400 tty3&lt;br /&gt;
tty4::respawn:/sbin/getty 38400 tty4&lt;br /&gt;
tty5::respawn:/sbin/getty 38400 tty5&lt;br /&gt;
tty6::respawn:/sbin/getty 38400 tty6&lt;br /&gt;
&lt;br /&gt;
tty1::respawn:/bin/login -f root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Disable Screensaver, and refresh webpage (optional)===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/X11/xorg.conf|&lt;br /&gt;
Section &amp;quot;Extensions&amp;quot;&lt;br /&gt;
    Option      &amp;quot;DPMS&amp;quot; &amp;quot;Disable&amp;quot;&lt;br /&gt;
EndSection}} &lt;br /&gt;
&lt;br /&gt;
{{cmd|# apk add xdotool}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# crontab -u root -e &lt;br /&gt;
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Note: xset is not an option here as it&#039;s not included by default. It can be installed from the repositories, if needed.&amp;lt;/small&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
That&#039;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.&lt;br /&gt;
&lt;br /&gt;
==Digital Signage==&lt;br /&gt;
It&#039;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? &lt;br /&gt;
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd). &lt;br /&gt;
# There is no requirement to use &#039;cloud&#039; services, or an internet connection. &lt;br /&gt;
# You have full control over the build and design (all kiosk build steps are documented &amp;amp; have a small learning curve, compared to some of the more complex projects mentioned above).&lt;br /&gt;
# Free software. No recurring costs (outside of optional maintenance). &lt;br /&gt;
# No ties to external infrastructure / frameworks. Full freedom.&lt;br /&gt;
&lt;br /&gt;
In this addition to the guide above, we&#039;ll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we&#039;ll also run a web server with PHP, which hosts the resources we want to display on the sign.&lt;br /&gt;
Make sure community apk is enabled in /etc/apk/repositories&lt;br /&gt;
 apk add chromium&lt;br /&gt;
In /etc/startup.sh add chromium instead of firefox:&lt;br /&gt;
  chromium-browser --home-page &amp;lt;nowiki&amp;gt;http://127.0.0.1/resource&amp;lt;/nowiki&amp;gt; --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you deploy the device on a TV, and you&#039;re unsure what resolution it is, you can access the resolution from the terminal (not in X), by using &lt;br /&gt;
 xrandr -d :0&lt;br /&gt;
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&#039;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&#039;s config.h, But a WM is not required.&lt;br /&gt;
&lt;br /&gt;
Make sure to run lbu_commit -d, in order to save any changes as needed in the apkvol on the SD or HDD storage.&lt;br /&gt;
&lt;br /&gt;
===Install Apache/PHP===&lt;br /&gt;
See [[Apache]].&lt;br /&gt;
&lt;br /&gt;
===Install xset to disable screensaver===&lt;br /&gt;
 apk add xset&lt;br /&gt;
 xset q&lt;br /&gt;
 xset s off&lt;br /&gt;
&lt;br /&gt;
===Hide Scrollbars of Browser===&lt;br /&gt;
This can be done with CSS.&lt;br /&gt;
 body {&lt;br /&gt;
   overflow: hidden; /* Hide scrollbars */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
===Why was this setup used? Why not Awesome, or dwm?===&lt;br /&gt;
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&#039;t have this limitation. It should be possible to get more RAM via /boot/config.txt&lt;br /&gt;
&lt;br /&gt;
If your application doesn&#039;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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Width &amp;amp; height of firefox doesn&#039;t fit the monitor===&lt;br /&gt;
Firefox can be called with -height and -width flags, e.g. &lt;br /&gt;
{{cmd|firefox -width 480 -height 640 example.org}}&lt;br /&gt;
&lt;br /&gt;
===Periodic Firefox Crashes on RPI3 due to Low Memory===&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
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 &amp;gt;1GB ram which may eliminate the need for a nightly reboot.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* [[dwm]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22814</id>
		<title>Raspberry Pi 3 - Browser Client</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22814"/>
		<updated>2022-12-27T12:59:16Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* AutoLogin, Startx automatically on Boot */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;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.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This guide uses the following:&lt;br /&gt;
* aarch64 img (though this guide is also tested to be roughly x86-compatible)&lt;br /&gt;
* Raspberry Pi3 &lt;br /&gt;
* community repo.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
See https://pkgs.alpinelinux.org/packages?name=*firefox*&amp;amp;branch=v3.11&amp;amp;arch=aarch64&lt;br /&gt;
&lt;br /&gt;
Note: the aarch64 build is not compatible with all Raspberry Pi models. See [[Raspberry Pi]].&lt;br /&gt;
&lt;br /&gt;
==Steps==&lt;br /&gt;
===Base Install===&lt;br /&gt;
&lt;br /&gt;
These steps are duplicated from the [[Raspberry_Pi]] page. (Note that for sake of this guide, it&#039;s assumed the RPI is a RAM only install. Although there is no requirement for it to be done this way).&lt;br /&gt;
&lt;br /&gt;
Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem. &lt;br /&gt;
e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Command (m for help): p&lt;br /&gt;
Disk /dev/sdb: 59.5 GiB, 63864569856 bytes, 124735488 sectors&lt;br /&gt;
Units: sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disklabel type: dos&lt;br /&gt;
Disk identifier: 0x00000000&lt;br /&gt;
&lt;br /&gt;
Device     Boot Start      End  Sectors Size Id Type&lt;br /&gt;
/dev/sdb1  *     2048 62916607 62914560  30G  b W95 FAT32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 mkdosfs -F 32 /dev/sdX1&lt;br /&gt;
&lt;br /&gt;
untar onto mounted disk&lt;br /&gt;
&lt;br /&gt;
 mount /dev/sdX1 /mnt/folder&lt;br /&gt;
 tar xvf archive.tar -C /mnt/folder/.&lt;br /&gt;
&lt;br /&gt;
If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other&lt;br /&gt;
config settings, do so in usercfg.txt now.&lt;br /&gt;
&lt;br /&gt;
Again, duplicating the [[Raspberry Pi]] page &lt;br /&gt;
&lt;br /&gt;
    Insert the SD card into the Raspberry Pi and turn it on&lt;br /&gt;
    Log in to Alpine as root. Leave the password empty.&lt;br /&gt;
    Type setup-alpine, hit enter.&lt;br /&gt;
    Once the installation is complete, commit the changes by typing lbu commit -d&lt;br /&gt;
&lt;br /&gt;
Things to keep in mind:&lt;br /&gt;
* 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. &lt;br /&gt;
* For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with &amp;quot;No disks available, try boot media /mmcblk0p1&amp;quot;. Select the default [n]. If you make a mistake during the install, you can always reimage and start over.&lt;br /&gt;
&lt;br /&gt;
Saving space: busybox instead of chronyd, dropbear instead of openssh&lt;br /&gt;
&lt;br /&gt;
After setup, make sure dropbear is installed&lt;br /&gt;
 apk add dropbear&lt;br /&gt;
&lt;br /&gt;
Start it:&lt;br /&gt;
 rc-service dropbear start&lt;br /&gt;
&lt;br /&gt;
Add it to the default runlevel:&lt;br /&gt;
 rc-update add dropbear&lt;br /&gt;
&lt;br /&gt;
If you need an accurate clock, enable software/ntp here. (this step is optional)&lt;br /&gt;
 rc-update add swclock boot # enable the software clock &lt;br /&gt;
 rc-update del hwclock boot # disable the hardware clock&lt;br /&gt;
 setup-ntp&lt;br /&gt;
&lt;br /&gt;
===Browser Client Install===&lt;br /&gt;
&lt;br /&gt;
Enable community repo (/etc/apk/repositories) (uncomment community)&lt;br /&gt;
 nano /etc/apk/repositories&lt;br /&gt;
 apk update&lt;br /&gt;
&lt;br /&gt;
install firefox dependencies:&lt;br /&gt;
 apk add libx11-dev libxft-dev libxinerama-dev ttf-dejavu&lt;br /&gt;
&amp;lt;small&amp;gt;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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the amount of RAM tmp fs available can be viewed while installing with: watch df -h&lt;br /&gt;
&lt;br /&gt;
install firefox&lt;br /&gt;
 apk add firefox-esr&lt;br /&gt;
install X&lt;br /&gt;
 setup-xorg-base&lt;br /&gt;
The RPI also requires for X:&lt;br /&gt;
 apk add xf86-video-fbdev&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;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 &amp;quot;apk search libEGL.so&amp;quot; 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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, we have about 421MB of RAM used (if NTP was not set up).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
devtmpfs                 10.0M         0     10.0M   0% /dev&lt;br /&gt;
shm                     457.9M         0    457.9M   0% /dev/shm&lt;br /&gt;
/dev/mmcblk0p1           30.0G    259.4M     29.7G   1% /media/mmcblk0p1&lt;br /&gt;
tmpfs                   457.9M    420.0M     37.9M  92% /&lt;br /&gt;
tmpfs                    91.6M    188.0K     91.4M   0% /run&lt;br /&gt;
/dev/loop0               24.9M     24.9M         0 100% /.modloop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 lbu_commit -d&lt;br /&gt;
&lt;br /&gt;
===AutoLogin, Startx automatically on Boot===&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to login as root, and run startx manually. Now we&#039;ll add configuration files to enable that without user interaction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;What is happening here from my understanding is:&lt;br /&gt;
 1) User logs in. /etc/profile is run (which includes a call to startx)&lt;br /&gt;
 2) Startx references any relevant xinitrc (user folder or /etc/X11), which calls /etc/startup.sh&lt;br /&gt;
 3) /etc/startup.sh runs any commands, such as dwm, firefox, or chromium.&lt;br /&gt;
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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/root/ doesn&#039;t save any files, so it&#039;s necessary to edit files in /etc/ and run lbu_commit -d after all changes. First let&#039;s add a file that we&#039;ll call firefox.&lt;br /&gt;
&amp;lt;small&amp;gt;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&lt;br /&gt;
also see: /etc/apk/protected_paths.d/lbu.list&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
create a file named /etc/startup.sh:&lt;br /&gt;
 #!/bin/ash&lt;br /&gt;
 firefox-esr &amp;lt;nowiki&amp;gt;http://awebsite.com&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!!!NOTE: This is ash, not bash. By default, alpine ships with the ash shell. Bash is available in the repositories.&lt;br /&gt;
&lt;br /&gt;
We have to edit xinitrc, and the profile configs. Normally, this would be done in the user&#039;s directory, but here we will use the globals for simplicity.&lt;br /&gt;
 mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK&lt;br /&gt;
 nano /etc/X11/xinit/xinitrc&lt;br /&gt;
In this file, insert:&lt;br /&gt;
 /etc/startup.sh&lt;br /&gt;
At the end of /etc/profile (leave the existing file) append&lt;br /&gt;
 exec startx&lt;br /&gt;
Remember to run lbu_commit -d&amp;lt;BR&amp;gt;&lt;br /&gt;
For autologin, alpine uses busybox, which has an alias to /sbin/getty as well as /bin/login. It&#039;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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Set up a couple of gettys&lt;br /&gt;
#tty1::respawn:/sbin/getty 38400 tty1&lt;br /&gt;
tty2::respawn:/sbin/getty 38400 tty2&lt;br /&gt;
tty3::respawn:/sbin/getty 38400 tty3&lt;br /&gt;
tty4::respawn:/sbin/getty 38400 tty4&lt;br /&gt;
tty5::respawn:/sbin/getty 38400 tty5&lt;br /&gt;
tty6::respawn:/sbin/getty 38400 tty6&lt;br /&gt;
&lt;br /&gt;
tty1::respawn:/bin/login -f root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Disable Screensaver, and refresh webpage (optional)===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/X11/xorg.conf|&lt;br /&gt;
Section &amp;quot;Extensions&amp;quot;&lt;br /&gt;
    Option      &amp;quot;DPMS&amp;quot; &amp;quot;Disable&amp;quot;&lt;br /&gt;
EndSection}} &lt;br /&gt;
&lt;br /&gt;
{{cmd|# apk add xdotool}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# crontab -u root -e &lt;br /&gt;
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Note: xset is not an option here as it&#039;s not included by default. It can be installed from the repositories, if needed.&amp;lt;/small&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
That&#039;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.&lt;br /&gt;
&lt;br /&gt;
==Digital Signage==&lt;br /&gt;
It&#039;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? &lt;br /&gt;
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd). &lt;br /&gt;
# There is no requirement to use &#039;cloud&#039; services, or an internet connection. &lt;br /&gt;
# You have full control over the build and design (all kiosk build steps are documented &amp;amp; have a small learning curve, compared to some of the more complex projects mentioned above).&lt;br /&gt;
# Free software. No recurring costs (outside of optional maintenance). &lt;br /&gt;
# No ties to external infrastructure / frameworks. Full freedom.&lt;br /&gt;
&lt;br /&gt;
In this addition to the guide above, we&#039;ll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we&#039;ll also run a web server with PHP, which hosts the resources we want to display on the sign.&lt;br /&gt;
Make sure community apk is enabled in /etc/apk/repositories&lt;br /&gt;
 apk add chromium&lt;br /&gt;
In /etc/startup.sh add chromium instead of firefox:&lt;br /&gt;
  chromium-browser --home-page &amp;lt;nowiki&amp;gt;http://127.0.0.1/resource&amp;lt;/nowiki&amp;gt; --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you deploy the device on a TV, and you&#039;re unsure what resolution it is, you can access the resolution from the terminal (not in X), by using &lt;br /&gt;
 xrandr -d :0&lt;br /&gt;
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&#039;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&#039;s config.h, But a WM is not required.&lt;br /&gt;
&lt;br /&gt;
Make sure to run lbu_commit -d, in order to save any changes as needed in the apkvol on the SD or HDD storage.&lt;br /&gt;
&lt;br /&gt;
===Install Apache/PHP===&lt;br /&gt;
See [[Apache]].&lt;br /&gt;
&lt;br /&gt;
===Install xset to disable screensaver===&lt;br /&gt;
 apk add xset&lt;br /&gt;
 xset q&lt;br /&gt;
 xset s off&lt;br /&gt;
&lt;br /&gt;
===Hide Scrollbars of Browser===&lt;br /&gt;
This can be done with CSS.&lt;br /&gt;
 body {&lt;br /&gt;
   overflow: hidden; /* Hide scrollbars */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
===Why was this setup used? Why not Awesome, or dwm?===&lt;br /&gt;
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&#039;t have this limitation. It should be possible to get more RAM via /boot/config.txt&lt;br /&gt;
&lt;br /&gt;
If your application doesn&#039;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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Width &amp;amp; height of firefox doesn&#039;t fit the monitor===&lt;br /&gt;
Firefox can be called with -height and -width flags, e.g. &lt;br /&gt;
{{cmd|firefox -width 480 -height 640 example.org}}&lt;br /&gt;
&lt;br /&gt;
===Periodic Firefox Crashes on RPI3 due to Low Memory===&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
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 &amp;gt;1GB ram which may eliminate the need for a nightly reboot.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* [[dwm]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22813</id>
		<title>Raspberry Pi 3 - Browser Client</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22813"/>
		<updated>2022-12-27T12:58:43Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* AutoLogin, Startx automatically on Boot */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;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.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This guide uses the following:&lt;br /&gt;
* aarch64 img (though this guide is also tested to be roughly x86-compatible)&lt;br /&gt;
* Raspberry Pi3 &lt;br /&gt;
* community repo.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
See https://pkgs.alpinelinux.org/packages?name=*firefox*&amp;amp;branch=v3.11&amp;amp;arch=aarch64&lt;br /&gt;
&lt;br /&gt;
Note: the aarch64 build is not compatible with all Raspberry Pi models. See [[Raspberry Pi]].&lt;br /&gt;
&lt;br /&gt;
==Steps==&lt;br /&gt;
===Base Install===&lt;br /&gt;
&lt;br /&gt;
These steps are duplicated from the [[Raspberry_Pi]] page. (Note that for sake of this guide, it&#039;s assumed the RPI is a RAM only install. Although there is no requirement for it to be done this way).&lt;br /&gt;
&lt;br /&gt;
Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem. &lt;br /&gt;
e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Command (m for help): p&lt;br /&gt;
Disk /dev/sdb: 59.5 GiB, 63864569856 bytes, 124735488 sectors&lt;br /&gt;
Units: sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disklabel type: dos&lt;br /&gt;
Disk identifier: 0x00000000&lt;br /&gt;
&lt;br /&gt;
Device     Boot Start      End  Sectors Size Id Type&lt;br /&gt;
/dev/sdb1  *     2048 62916607 62914560  30G  b W95 FAT32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 mkdosfs -F 32 /dev/sdX1&lt;br /&gt;
&lt;br /&gt;
untar onto mounted disk&lt;br /&gt;
&lt;br /&gt;
 mount /dev/sdX1 /mnt/folder&lt;br /&gt;
 tar xvf archive.tar -C /mnt/folder/.&lt;br /&gt;
&lt;br /&gt;
If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other&lt;br /&gt;
config settings, do so in usercfg.txt now.&lt;br /&gt;
&lt;br /&gt;
Again, duplicating the [[Raspberry Pi]] page &lt;br /&gt;
&lt;br /&gt;
    Insert the SD card into the Raspberry Pi and turn it on&lt;br /&gt;
    Log in to Alpine as root. Leave the password empty.&lt;br /&gt;
    Type setup-alpine, hit enter.&lt;br /&gt;
    Once the installation is complete, commit the changes by typing lbu commit -d&lt;br /&gt;
&lt;br /&gt;
Things to keep in mind:&lt;br /&gt;
* 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. &lt;br /&gt;
* For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with &amp;quot;No disks available, try boot media /mmcblk0p1&amp;quot;. Select the default [n]. If you make a mistake during the install, you can always reimage and start over.&lt;br /&gt;
&lt;br /&gt;
Saving space: busybox instead of chronyd, dropbear instead of openssh&lt;br /&gt;
&lt;br /&gt;
After setup, make sure dropbear is installed&lt;br /&gt;
 apk add dropbear&lt;br /&gt;
&lt;br /&gt;
Start it:&lt;br /&gt;
 rc-service dropbear start&lt;br /&gt;
&lt;br /&gt;
Add it to the default runlevel:&lt;br /&gt;
 rc-update add dropbear&lt;br /&gt;
&lt;br /&gt;
If you need an accurate clock, enable software/ntp here. (this step is optional)&lt;br /&gt;
 rc-update add swclock boot # enable the software clock &lt;br /&gt;
 rc-update del hwclock boot # disable the hardware clock&lt;br /&gt;
 setup-ntp&lt;br /&gt;
&lt;br /&gt;
===Browser Client Install===&lt;br /&gt;
&lt;br /&gt;
Enable community repo (/etc/apk/repositories) (uncomment community)&lt;br /&gt;
 nano /etc/apk/repositories&lt;br /&gt;
 apk update&lt;br /&gt;
&lt;br /&gt;
install firefox dependencies:&lt;br /&gt;
 apk add libx11-dev libxft-dev libxinerama-dev ttf-dejavu&lt;br /&gt;
&amp;lt;small&amp;gt;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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the amount of RAM tmp fs available can be viewed while installing with: watch df -h&lt;br /&gt;
&lt;br /&gt;
install firefox&lt;br /&gt;
 apk add firefox-esr&lt;br /&gt;
install X&lt;br /&gt;
 setup-xorg-base&lt;br /&gt;
The RPI also requires for X:&lt;br /&gt;
 apk add xf86-video-fbdev&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;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 &amp;quot;apk search libEGL.so&amp;quot; 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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, we have about 421MB of RAM used (if NTP was not set up).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
devtmpfs                 10.0M         0     10.0M   0% /dev&lt;br /&gt;
shm                     457.9M         0    457.9M   0% /dev/shm&lt;br /&gt;
/dev/mmcblk0p1           30.0G    259.4M     29.7G   1% /media/mmcblk0p1&lt;br /&gt;
tmpfs                   457.9M    420.0M     37.9M  92% /&lt;br /&gt;
tmpfs                    91.6M    188.0K     91.4M   0% /run&lt;br /&gt;
/dev/loop0               24.9M     24.9M         0 100% /.modloop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 lbu_commit -d&lt;br /&gt;
&lt;br /&gt;
===AutoLogin, Startx automatically on Boot===&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to login as root, and run startx manually. Now we&#039;ll add configuration files to enable that without user interaction.&lt;br /&gt;
&lt;br /&gt;
What is happening here from my understanding is:&lt;br /&gt;
1) User logs in. /etc/profile is run (which includes a call to startx)&lt;br /&gt;
2) Startx references any relevant xinitrc (user folder or /etc/X11), which calls /etc/startup.sh&lt;br /&gt;
3) /etc/startup.sh runs any commands, such as dwm, firefox, or chromium.&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/root/ doesn&#039;t save any files, so it&#039;s necessary to edit files in /etc/ and run lbu_commit -d after all changes. First let&#039;s add a file that we&#039;ll call firefox.&lt;br /&gt;
&amp;lt;small&amp;gt;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&lt;br /&gt;
also see: /etc/apk/protected_paths.d/lbu.list&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
create a file named /etc/startup.sh:&lt;br /&gt;
 #!/bin/ash&lt;br /&gt;
 firefox-esr &amp;lt;nowiki&amp;gt;http://awebsite.com&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!!!NOTE: This is ash, not bash. By default, alpine ships with the ash shell. Bash is available in the repositories.&lt;br /&gt;
&lt;br /&gt;
We have to edit xinitrc, and the profile configs. Normally, this would be done in the user&#039;s directory, but here we will use the globals for simplicity.&lt;br /&gt;
 mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK&lt;br /&gt;
 nano /etc/X11/xinit/xinitrc&lt;br /&gt;
In this file, insert:&lt;br /&gt;
 /etc/startup.sh&lt;br /&gt;
At the end of /etc/profile (leave the existing file) append&lt;br /&gt;
 exec startx&lt;br /&gt;
Remember to run lbu_commit -d&amp;lt;BR&amp;gt;&lt;br /&gt;
For autologin, alpine uses busybox, which has an alias to /sbin/getty as well as /bin/login. It&#039;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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Set up a couple of gettys&lt;br /&gt;
#tty1::respawn:/sbin/getty 38400 tty1&lt;br /&gt;
tty2::respawn:/sbin/getty 38400 tty2&lt;br /&gt;
tty3::respawn:/sbin/getty 38400 tty3&lt;br /&gt;
tty4::respawn:/sbin/getty 38400 tty4&lt;br /&gt;
tty5::respawn:/sbin/getty 38400 tty5&lt;br /&gt;
tty6::respawn:/sbin/getty 38400 tty6&lt;br /&gt;
&lt;br /&gt;
tty1::respawn:/bin/login -f root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Disable Screensaver, and refresh webpage (optional)===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/X11/xorg.conf|&lt;br /&gt;
Section &amp;quot;Extensions&amp;quot;&lt;br /&gt;
    Option      &amp;quot;DPMS&amp;quot; &amp;quot;Disable&amp;quot;&lt;br /&gt;
EndSection}} &lt;br /&gt;
&lt;br /&gt;
{{cmd|# apk add xdotool}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# crontab -u root -e &lt;br /&gt;
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Note: xset is not an option here as it&#039;s not included by default. It can be installed from the repositories, if needed.&amp;lt;/small&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
That&#039;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.&lt;br /&gt;
&lt;br /&gt;
==Digital Signage==&lt;br /&gt;
It&#039;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? &lt;br /&gt;
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd). &lt;br /&gt;
# There is no requirement to use &#039;cloud&#039; services, or an internet connection. &lt;br /&gt;
# You have full control over the build and design (all kiosk build steps are documented &amp;amp; have a small learning curve, compared to some of the more complex projects mentioned above).&lt;br /&gt;
# Free software. No recurring costs (outside of optional maintenance). &lt;br /&gt;
# No ties to external infrastructure / frameworks. Full freedom.&lt;br /&gt;
&lt;br /&gt;
In this addition to the guide above, we&#039;ll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we&#039;ll also run a web server with PHP, which hosts the resources we want to display on the sign.&lt;br /&gt;
Make sure community apk is enabled in /etc/apk/repositories&lt;br /&gt;
 apk add chromium&lt;br /&gt;
In /etc/startup.sh add chromium instead of firefox:&lt;br /&gt;
  chromium-browser --home-page &amp;lt;nowiki&amp;gt;http://127.0.0.1/resource&amp;lt;/nowiki&amp;gt; --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you deploy the device on a TV, and you&#039;re unsure what resolution it is, you can access the resolution from the terminal (not in X), by using &lt;br /&gt;
 xrandr -d :0&lt;br /&gt;
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&#039;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&#039;s config.h, But a WM is not required.&lt;br /&gt;
&lt;br /&gt;
Make sure to run lbu_commit -d, in order to save any changes as needed in the apkvol on the SD or HDD storage.&lt;br /&gt;
&lt;br /&gt;
===Install Apache/PHP===&lt;br /&gt;
See [[Apache]].&lt;br /&gt;
&lt;br /&gt;
===Install xset to disable screensaver===&lt;br /&gt;
 apk add xset&lt;br /&gt;
 xset q&lt;br /&gt;
 xset s off&lt;br /&gt;
&lt;br /&gt;
===Hide Scrollbars of Browser===&lt;br /&gt;
This can be done with CSS.&lt;br /&gt;
 body {&lt;br /&gt;
   overflow: hidden; /* Hide scrollbars */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
===Why was this setup used? Why not Awesome, or dwm?===&lt;br /&gt;
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&#039;t have this limitation. It should be possible to get more RAM via /boot/config.txt&lt;br /&gt;
&lt;br /&gt;
If your application doesn&#039;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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Width &amp;amp; height of firefox doesn&#039;t fit the monitor===&lt;br /&gt;
Firefox can be called with -height and -width flags, e.g. &lt;br /&gt;
{{cmd|firefox -width 480 -height 640 example.org}}&lt;br /&gt;
&lt;br /&gt;
===Periodic Firefox Crashes on RPI3 due to Low Memory===&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
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 &amp;gt;1GB ram which may eliminate the need for a nightly reboot.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* [[dwm]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22812</id>
		<title>Raspberry Pi 3 - Browser Client</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22812"/>
		<updated>2022-12-27T12:10:36Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* AutoLogin, Startx automatically on Boot */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;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.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This guide uses the following:&lt;br /&gt;
* aarch64 img (though this guide is also tested to be roughly x86-compatible)&lt;br /&gt;
* Raspberry Pi3 &lt;br /&gt;
* community repo.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
See https://pkgs.alpinelinux.org/packages?name=*firefox*&amp;amp;branch=v3.11&amp;amp;arch=aarch64&lt;br /&gt;
&lt;br /&gt;
Note: the aarch64 build is not compatible with all Raspberry Pi models. See [[Raspberry Pi]].&lt;br /&gt;
&lt;br /&gt;
==Steps==&lt;br /&gt;
===Base Install===&lt;br /&gt;
&lt;br /&gt;
These steps are duplicated from the [[Raspberry_Pi]] page. (Note that for sake of this guide, it&#039;s assumed the RPI is a RAM only install. Although there is no requirement for it to be done this way).&lt;br /&gt;
&lt;br /&gt;
Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem. &lt;br /&gt;
e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Command (m for help): p&lt;br /&gt;
Disk /dev/sdb: 59.5 GiB, 63864569856 bytes, 124735488 sectors&lt;br /&gt;
Units: sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disklabel type: dos&lt;br /&gt;
Disk identifier: 0x00000000&lt;br /&gt;
&lt;br /&gt;
Device     Boot Start      End  Sectors Size Id Type&lt;br /&gt;
/dev/sdb1  *     2048 62916607 62914560  30G  b W95 FAT32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 mkdosfs -F 32 /dev/sdX1&lt;br /&gt;
&lt;br /&gt;
untar onto mounted disk&lt;br /&gt;
&lt;br /&gt;
 mount /dev/sdX1 /mnt/folder&lt;br /&gt;
 tar xvf archive.tar -C /mnt/folder/.&lt;br /&gt;
&lt;br /&gt;
If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other&lt;br /&gt;
config settings, do so in usercfg.txt now.&lt;br /&gt;
&lt;br /&gt;
Again, duplicating the [[Raspberry Pi]] page &lt;br /&gt;
&lt;br /&gt;
    Insert the SD card into the Raspberry Pi and turn it on&lt;br /&gt;
    Log in to Alpine as root. Leave the password empty.&lt;br /&gt;
    Type setup-alpine, hit enter.&lt;br /&gt;
    Once the installation is complete, commit the changes by typing lbu commit -d&lt;br /&gt;
&lt;br /&gt;
Things to keep in mind:&lt;br /&gt;
* 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. &lt;br /&gt;
* For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with &amp;quot;No disks available, try boot media /mmcblk0p1&amp;quot;. Select the default [n]. If you make a mistake during the install, you can always reimage and start over.&lt;br /&gt;
&lt;br /&gt;
Saving space: busybox instead of chronyd, dropbear instead of openssh&lt;br /&gt;
&lt;br /&gt;
After setup, make sure dropbear is installed&lt;br /&gt;
 apk add dropbear&lt;br /&gt;
&lt;br /&gt;
Start it:&lt;br /&gt;
 rc-service dropbear start&lt;br /&gt;
&lt;br /&gt;
Add it to the default runlevel:&lt;br /&gt;
 rc-update add dropbear&lt;br /&gt;
&lt;br /&gt;
If you need an accurate clock, enable software/ntp here. (this step is optional)&lt;br /&gt;
 rc-update add swclock boot # enable the software clock &lt;br /&gt;
 rc-update del hwclock boot # disable the hardware clock&lt;br /&gt;
 setup-ntp&lt;br /&gt;
&lt;br /&gt;
===Browser Client Install===&lt;br /&gt;
&lt;br /&gt;
Enable community repo (/etc/apk/repositories) (uncomment community)&lt;br /&gt;
 nano /etc/apk/repositories&lt;br /&gt;
 apk update&lt;br /&gt;
&lt;br /&gt;
install firefox dependencies:&lt;br /&gt;
 apk add libx11-dev libxft-dev libxinerama-dev ttf-dejavu&lt;br /&gt;
&amp;lt;small&amp;gt;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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the amount of RAM tmp fs available can be viewed while installing with: watch df -h&lt;br /&gt;
&lt;br /&gt;
install firefox&lt;br /&gt;
 apk add firefox-esr&lt;br /&gt;
install X&lt;br /&gt;
 setup-xorg-base&lt;br /&gt;
The RPI also requires for X:&lt;br /&gt;
 apk add xf86-video-fbdev&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;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 &amp;quot;apk search libEGL.so&amp;quot; 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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, we have about 421MB of RAM used (if NTP was not set up).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
devtmpfs                 10.0M         0     10.0M   0% /dev&lt;br /&gt;
shm                     457.9M         0    457.9M   0% /dev/shm&lt;br /&gt;
/dev/mmcblk0p1           30.0G    259.4M     29.7G   1% /media/mmcblk0p1&lt;br /&gt;
tmpfs                   457.9M    420.0M     37.9M  92% /&lt;br /&gt;
tmpfs                    91.6M    188.0K     91.4M   0% /run&lt;br /&gt;
/dev/loop0               24.9M     24.9M         0 100% /.modloop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 lbu_commit -d&lt;br /&gt;
&lt;br /&gt;
===AutoLogin, Startx automatically on Boot===&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to login as root, and run startx manually. Now we&#039;ll add configuration files to enable that without user interaction.&lt;br /&gt;
&lt;br /&gt;
/root/ doesn&#039;t save any files, so it&#039;s necessary to edit files in /etc/ and run lbu_commit -d after all changes. First let&#039;s add a file that we&#039;ll call firefox.&lt;br /&gt;
&amp;lt;small&amp;gt;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&lt;br /&gt;
also see: /etc/apk/protected_paths.d/lbu.list&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
create a file named /etc/startup.sh:&lt;br /&gt;
 #!/bin/ash&lt;br /&gt;
 firefox-esr &amp;lt;nowiki&amp;gt;http://awebsite.com&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!!!NOTE: This is ash, not bash. By default, alpine ships with the ash shell. Bash is available in the repositories.&lt;br /&gt;
&lt;br /&gt;
We have to edit xinitrc, and the profile configs. Normally, this would be done in the user&#039;s directory, but here we will use the globals for simplicity.&lt;br /&gt;
 mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK&lt;br /&gt;
 nano /etc/X11/xinit/xinitrc&lt;br /&gt;
In this file, insert:&lt;br /&gt;
 /etc/startup.sh&lt;br /&gt;
At the end of /etc/profile (leave the existing file) append&lt;br /&gt;
 exec startx&lt;br /&gt;
Remember to run lbu_commit -d&amp;lt;BR&amp;gt;&lt;br /&gt;
For autologin, alpine uses busybox, which has an alias to /sbin/getty as well as /bin/login. It&#039;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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Set up a couple of gettys&lt;br /&gt;
#tty1::respawn:/sbin/getty 38400 tty1&lt;br /&gt;
tty2::respawn:/sbin/getty 38400 tty2&lt;br /&gt;
tty3::respawn:/sbin/getty 38400 tty3&lt;br /&gt;
tty4::respawn:/sbin/getty 38400 tty4&lt;br /&gt;
tty5::respawn:/sbin/getty 38400 tty5&lt;br /&gt;
tty6::respawn:/sbin/getty 38400 tty6&lt;br /&gt;
&lt;br /&gt;
tty1::respawn:/bin/login -f root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Disable Screensaver, and refresh webpage (optional)===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/X11/xorg.conf|&lt;br /&gt;
Section &amp;quot;Extensions&amp;quot;&lt;br /&gt;
    Option      &amp;quot;DPMS&amp;quot; &amp;quot;Disable&amp;quot;&lt;br /&gt;
EndSection}} &lt;br /&gt;
&lt;br /&gt;
{{cmd|# apk add xdotool}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# crontab -u root -e &lt;br /&gt;
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Note: xset is not an option here as it&#039;s not included by default. It can be installed from the repositories, if needed.&amp;lt;/small&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
That&#039;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.&lt;br /&gt;
&lt;br /&gt;
==Digital Signage==&lt;br /&gt;
It&#039;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? &lt;br /&gt;
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd). &lt;br /&gt;
# There is no requirement to use &#039;cloud&#039; services, or an internet connection. &lt;br /&gt;
# You have full control over the build and design (all kiosk build steps are documented &amp;amp; have a small learning curve, compared to some of the more complex projects mentioned above).&lt;br /&gt;
# Free software. No recurring costs (outside of optional maintenance). &lt;br /&gt;
# No ties to external infrastructure / frameworks. Full freedom.&lt;br /&gt;
&lt;br /&gt;
In this addition to the guide above, we&#039;ll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we&#039;ll also run a web server with PHP, which hosts the resources we want to display on the sign.&lt;br /&gt;
Make sure community apk is enabled in /etc/apk/repositories&lt;br /&gt;
 apk add chromium&lt;br /&gt;
In /etc/startup.sh add chromium instead of firefox:&lt;br /&gt;
  chromium-browser --home-page &amp;lt;nowiki&amp;gt;http://127.0.0.1/resource&amp;lt;/nowiki&amp;gt; --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you deploy the device on a TV, and you&#039;re unsure what resolution it is, you can access the resolution from the terminal (not in X), by using &lt;br /&gt;
 xrandr -d :0&lt;br /&gt;
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&#039;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&#039;s config.h, But a WM is not required.&lt;br /&gt;
&lt;br /&gt;
Make sure to run lbu_commit -d, in order to save any changes as needed in the apkvol on the SD or HDD storage.&lt;br /&gt;
&lt;br /&gt;
===Install Apache/PHP===&lt;br /&gt;
See [[Apache]].&lt;br /&gt;
&lt;br /&gt;
===Install xset to disable screensaver===&lt;br /&gt;
 apk add xset&lt;br /&gt;
 xset q&lt;br /&gt;
 xset s off&lt;br /&gt;
&lt;br /&gt;
===Hide Scrollbars of Browser===&lt;br /&gt;
This can be done with CSS.&lt;br /&gt;
 body {&lt;br /&gt;
   overflow: hidden; /* Hide scrollbars */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
===Why was this setup used? Why not Awesome, or dwm?===&lt;br /&gt;
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&#039;t have this limitation. It should be possible to get more RAM via /boot/config.txt&lt;br /&gt;
&lt;br /&gt;
If your application doesn&#039;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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Width &amp;amp; height of firefox doesn&#039;t fit the monitor===&lt;br /&gt;
Firefox can be called with -height and -width flags, e.g. &lt;br /&gt;
{{cmd|firefox -width 480 -height 640 example.org}}&lt;br /&gt;
&lt;br /&gt;
===Periodic Firefox Crashes on RPI3 due to Low Memory===&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
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 &amp;gt;1GB ram which may eliminate the need for a nightly reboot.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* [[dwm]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22811</id>
		<title>Raspberry Pi 3 - Browser Client</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22811"/>
		<updated>2022-12-27T12:08:11Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* AutoLogin, Startx automatically on Boot */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;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.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This guide uses the following:&lt;br /&gt;
* aarch64 img (though this guide is also tested to be roughly x86-compatible)&lt;br /&gt;
* Raspberry Pi3 &lt;br /&gt;
* community repo.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
See https://pkgs.alpinelinux.org/packages?name=*firefox*&amp;amp;branch=v3.11&amp;amp;arch=aarch64&lt;br /&gt;
&lt;br /&gt;
Note: the aarch64 build is not compatible with all Raspberry Pi models. See [[Raspberry Pi]].&lt;br /&gt;
&lt;br /&gt;
==Steps==&lt;br /&gt;
===Base Install===&lt;br /&gt;
&lt;br /&gt;
These steps are duplicated from the [[Raspberry_Pi]] page. (Note that for sake of this guide, it&#039;s assumed the RPI is a RAM only install. Although there is no requirement for it to be done this way).&lt;br /&gt;
&lt;br /&gt;
Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem. &lt;br /&gt;
e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Command (m for help): p&lt;br /&gt;
Disk /dev/sdb: 59.5 GiB, 63864569856 bytes, 124735488 sectors&lt;br /&gt;
Units: sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disklabel type: dos&lt;br /&gt;
Disk identifier: 0x00000000&lt;br /&gt;
&lt;br /&gt;
Device     Boot Start      End  Sectors Size Id Type&lt;br /&gt;
/dev/sdb1  *     2048 62916607 62914560  30G  b W95 FAT32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 mkdosfs -F 32 /dev/sdX1&lt;br /&gt;
&lt;br /&gt;
untar onto mounted disk&lt;br /&gt;
&lt;br /&gt;
 mount /dev/sdX1 /mnt/folder&lt;br /&gt;
 tar xvf archive.tar -C /mnt/folder/.&lt;br /&gt;
&lt;br /&gt;
If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other&lt;br /&gt;
config settings, do so in usercfg.txt now.&lt;br /&gt;
&lt;br /&gt;
Again, duplicating the [[Raspberry Pi]] page &lt;br /&gt;
&lt;br /&gt;
    Insert the SD card into the Raspberry Pi and turn it on&lt;br /&gt;
    Log in to Alpine as root. Leave the password empty.&lt;br /&gt;
    Type setup-alpine, hit enter.&lt;br /&gt;
    Once the installation is complete, commit the changes by typing lbu commit -d&lt;br /&gt;
&lt;br /&gt;
Things to keep in mind:&lt;br /&gt;
* 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. &lt;br /&gt;
* For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with &amp;quot;No disks available, try boot media /mmcblk0p1&amp;quot;. Select the default [n]. If you make a mistake during the install, you can always reimage and start over.&lt;br /&gt;
&lt;br /&gt;
Saving space: busybox instead of chronyd, dropbear instead of openssh&lt;br /&gt;
&lt;br /&gt;
After setup, make sure dropbear is installed&lt;br /&gt;
 apk add dropbear&lt;br /&gt;
&lt;br /&gt;
Start it:&lt;br /&gt;
 rc-service dropbear start&lt;br /&gt;
&lt;br /&gt;
Add it to the default runlevel:&lt;br /&gt;
 rc-update add dropbear&lt;br /&gt;
&lt;br /&gt;
If you need an accurate clock, enable software/ntp here. (this step is optional)&lt;br /&gt;
 rc-update add swclock boot # enable the software clock &lt;br /&gt;
 rc-update del hwclock boot # disable the hardware clock&lt;br /&gt;
 setup-ntp&lt;br /&gt;
&lt;br /&gt;
===Browser Client Install===&lt;br /&gt;
&lt;br /&gt;
Enable community repo (/etc/apk/repositories) (uncomment community)&lt;br /&gt;
 nano /etc/apk/repositories&lt;br /&gt;
 apk update&lt;br /&gt;
&lt;br /&gt;
install firefox dependencies:&lt;br /&gt;
 apk add libx11-dev libxft-dev libxinerama-dev ttf-dejavu&lt;br /&gt;
&amp;lt;small&amp;gt;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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the amount of RAM tmp fs available can be viewed while installing with: watch df -h&lt;br /&gt;
&lt;br /&gt;
install firefox&lt;br /&gt;
 apk add firefox-esr&lt;br /&gt;
install X&lt;br /&gt;
 setup-xorg-base&lt;br /&gt;
The RPI also requires for X:&lt;br /&gt;
 apk add xf86-video-fbdev&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;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 &amp;quot;apk search libEGL.so&amp;quot; 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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, we have about 421MB of RAM used (if NTP was not set up).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
devtmpfs                 10.0M         0     10.0M   0% /dev&lt;br /&gt;
shm                     457.9M         0    457.9M   0% /dev/shm&lt;br /&gt;
/dev/mmcblk0p1           30.0G    259.4M     29.7G   1% /media/mmcblk0p1&lt;br /&gt;
tmpfs                   457.9M    420.0M     37.9M  92% /&lt;br /&gt;
tmpfs                    91.6M    188.0K     91.4M   0% /run&lt;br /&gt;
/dev/loop0               24.9M     24.9M         0 100% /.modloop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 lbu_commit -d&lt;br /&gt;
&lt;br /&gt;
===AutoLogin, Startx automatically on Boot===&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to login as root, and run startx manually. Now we&#039;ll add configuration files to enable that without user interaction.&lt;br /&gt;
&lt;br /&gt;
/root/ doesn&#039;t save any files, so it&#039;s necessary to edit files in /etc/ and run lbu_commit -d after all changes. First let&#039;s add a file that we&#039;ll call firefox.&lt;br /&gt;
&amp;lt;small&amp;gt;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&lt;br /&gt;
also see: /etc/apk/protected_paths.d/lbu.list&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
create a file named /etc/startup.sh:&lt;br /&gt;
 #!/bin/ash&lt;br /&gt;
 firefox-esr &amp;lt;nowiki&amp;gt;http://awebsite.com&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!!!NOTE: This is ash, not bash. By default, alpine ships with the ash shell. Bash is available in the repositories.&lt;br /&gt;
&lt;br /&gt;
We have to edit xinitrc, and the profile configs. Normally, this would be done in the user&#039;s directory, but here we will use the globals for simplicity.&lt;br /&gt;
 mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK&lt;br /&gt;
 nano /etc/X11/xinit/xinitrc&lt;br /&gt;
In this file, insert:&lt;br /&gt;
 /etc/startup.sh&lt;br /&gt;
At the end of /etc/profile (leave the existing file) append&lt;br /&gt;
 exec startx&lt;br /&gt;
Remember to run lbu_commit -d&amp;lt;BR&amp;gt;&lt;br /&gt;
For autologin, alpine uses busybox, which has an alias to /sbin/getty as well as /bin/login. It&#039;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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Set up a couple of gettys&lt;br /&gt;
#tty1::respawn:/sbin/getty 38400 tty1&lt;br /&gt;
tty2::respawn:/sbin/getty 38400 tty2&lt;br /&gt;
tty3::respawn:/sbin/getty 38400 tty3&lt;br /&gt;
tty4::respawn:/sbin/getty 38400 tty4&lt;br /&gt;
tty5::respawn:/sbin/getty 38400 tty5&lt;br /&gt;
tty6::respawn:/sbin/getty 38400 tty6&lt;br /&gt;
&lt;br /&gt;
tty1::respawn:/bin/login -f root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Disable Screensaver, and refresh webpage (optional)===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/X11/xorg.conf|&lt;br /&gt;
Section &amp;quot;Extensions&amp;quot;&lt;br /&gt;
    Option      &amp;quot;DPMS&amp;quot; &amp;quot;Disable&amp;quot;&lt;br /&gt;
EndSection}} &lt;br /&gt;
&lt;br /&gt;
{{cmd|# apk add xdotool}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# crontab -u root -e &lt;br /&gt;
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Note: xset is not an option here as it&#039;s not included by default. It can be installed from the repositories, if needed.&amp;lt;/small&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
That&#039;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.&lt;br /&gt;
&lt;br /&gt;
==Digital Signage==&lt;br /&gt;
It&#039;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? &lt;br /&gt;
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd). &lt;br /&gt;
# There is no requirement to use &#039;cloud&#039; services, or an internet connection. &lt;br /&gt;
# You have full control over the build and design (all kiosk build steps are documented &amp;amp; have a small learning curve, compared to some of the more complex projects mentioned above).&lt;br /&gt;
# Free software. No recurring costs (outside of optional maintenance). &lt;br /&gt;
# No ties to external infrastructure / frameworks. Full freedom.&lt;br /&gt;
&lt;br /&gt;
In this addition to the guide above, we&#039;ll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we&#039;ll also run a web server with PHP, which hosts the resources we want to display on the sign.&lt;br /&gt;
Make sure community apk is enabled in /etc/apk/repositories&lt;br /&gt;
 apk add chromium&lt;br /&gt;
In /etc/startup.sh add chromium instead of firefox:&lt;br /&gt;
  chromium-browser --home-page &amp;lt;nowiki&amp;gt;http://127.0.0.1/resource&amp;lt;/nowiki&amp;gt; --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you deploy the device on a TV, and you&#039;re unsure what resolution it is, you can access the resolution from the terminal (not in X), by using &lt;br /&gt;
 xrandr -d :0&lt;br /&gt;
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&#039;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&#039;s config.h, But a WM is not required.&lt;br /&gt;
&lt;br /&gt;
Make sure to run lbu_commit -d, in order to save any changes as needed in the apkvol on the SD or HDD storage.&lt;br /&gt;
&lt;br /&gt;
===Install Apache/PHP===&lt;br /&gt;
See [[Apache]].&lt;br /&gt;
&lt;br /&gt;
===Install xset to disable screensaver===&lt;br /&gt;
 apk add xset&lt;br /&gt;
 xset q&lt;br /&gt;
 xset s off&lt;br /&gt;
&lt;br /&gt;
===Hide Scrollbars of Browser===&lt;br /&gt;
This can be done with CSS.&lt;br /&gt;
 body {&lt;br /&gt;
   overflow: hidden; /* Hide scrollbars */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
===Why was this setup used? Why not Awesome, or dwm?===&lt;br /&gt;
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&#039;t have this limitation. It should be possible to get more RAM via /boot/config.txt&lt;br /&gt;
&lt;br /&gt;
If your application doesn&#039;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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Width &amp;amp; height of firefox doesn&#039;t fit the monitor===&lt;br /&gt;
Firefox can be called with -height and -width flags, e.g. &lt;br /&gt;
{{cmd|firefox -width 480 -height 640 example.org}}&lt;br /&gt;
&lt;br /&gt;
===Periodic Firefox Crashes on RPI3 due to Low Memory===&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
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 &amp;gt;1GB ram which may eliminate the need for a nightly reboot.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* [[dwm]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22810</id>
		<title>Raspberry Pi 3 - Browser Client</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22810"/>
		<updated>2022-12-27T12:07:56Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* AutoLogin, Startx automatically on Boot */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;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.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This guide uses the following:&lt;br /&gt;
* aarch64 img (though this guide is also tested to be roughly x86-compatible)&lt;br /&gt;
* Raspberry Pi3 &lt;br /&gt;
* community repo.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
See https://pkgs.alpinelinux.org/packages?name=*firefox*&amp;amp;branch=v3.11&amp;amp;arch=aarch64&lt;br /&gt;
&lt;br /&gt;
Note: the aarch64 build is not compatible with all Raspberry Pi models. See [[Raspberry Pi]].&lt;br /&gt;
&lt;br /&gt;
==Steps==&lt;br /&gt;
===Base Install===&lt;br /&gt;
&lt;br /&gt;
These steps are duplicated from the [[Raspberry_Pi]] page. (Note that for sake of this guide, it&#039;s assumed the RPI is a RAM only install. Although there is no requirement for it to be done this way).&lt;br /&gt;
&lt;br /&gt;
Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem. &lt;br /&gt;
e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Command (m for help): p&lt;br /&gt;
Disk /dev/sdb: 59.5 GiB, 63864569856 bytes, 124735488 sectors&lt;br /&gt;
Units: sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disklabel type: dos&lt;br /&gt;
Disk identifier: 0x00000000&lt;br /&gt;
&lt;br /&gt;
Device     Boot Start      End  Sectors Size Id Type&lt;br /&gt;
/dev/sdb1  *     2048 62916607 62914560  30G  b W95 FAT32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 mkdosfs -F 32 /dev/sdX1&lt;br /&gt;
&lt;br /&gt;
untar onto mounted disk&lt;br /&gt;
&lt;br /&gt;
 mount /dev/sdX1 /mnt/folder&lt;br /&gt;
 tar xvf archive.tar -C /mnt/folder/.&lt;br /&gt;
&lt;br /&gt;
If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other&lt;br /&gt;
config settings, do so in usercfg.txt now.&lt;br /&gt;
&lt;br /&gt;
Again, duplicating the [[Raspberry Pi]] page &lt;br /&gt;
&lt;br /&gt;
    Insert the SD card into the Raspberry Pi and turn it on&lt;br /&gt;
    Log in to Alpine as root. Leave the password empty.&lt;br /&gt;
    Type setup-alpine, hit enter.&lt;br /&gt;
    Once the installation is complete, commit the changes by typing lbu commit -d&lt;br /&gt;
&lt;br /&gt;
Things to keep in mind:&lt;br /&gt;
* 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. &lt;br /&gt;
* For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with &amp;quot;No disks available, try boot media /mmcblk0p1&amp;quot;. Select the default [n]. If you make a mistake during the install, you can always reimage and start over.&lt;br /&gt;
&lt;br /&gt;
Saving space: busybox instead of chronyd, dropbear instead of openssh&lt;br /&gt;
&lt;br /&gt;
After setup, make sure dropbear is installed&lt;br /&gt;
 apk add dropbear&lt;br /&gt;
&lt;br /&gt;
Start it:&lt;br /&gt;
 rc-service dropbear start&lt;br /&gt;
&lt;br /&gt;
Add it to the default runlevel:&lt;br /&gt;
 rc-update add dropbear&lt;br /&gt;
&lt;br /&gt;
If you need an accurate clock, enable software/ntp here. (this step is optional)&lt;br /&gt;
 rc-update add swclock boot # enable the software clock &lt;br /&gt;
 rc-update del hwclock boot # disable the hardware clock&lt;br /&gt;
 setup-ntp&lt;br /&gt;
&lt;br /&gt;
===Browser Client Install===&lt;br /&gt;
&lt;br /&gt;
Enable community repo (/etc/apk/repositories) (uncomment community)&lt;br /&gt;
 nano /etc/apk/repositories&lt;br /&gt;
 apk update&lt;br /&gt;
&lt;br /&gt;
install firefox dependencies:&lt;br /&gt;
 apk add libx11-dev libxft-dev libxinerama-dev ttf-dejavu&lt;br /&gt;
&amp;lt;small&amp;gt;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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the amount of RAM tmp fs available can be viewed while installing with: watch df -h&lt;br /&gt;
&lt;br /&gt;
install firefox&lt;br /&gt;
 apk add firefox-esr&lt;br /&gt;
install X&lt;br /&gt;
 setup-xorg-base&lt;br /&gt;
The RPI also requires for X:&lt;br /&gt;
 apk add xf86-video-fbdev&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;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 &amp;quot;apk search libEGL.so&amp;quot; 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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, we have about 421MB of RAM used (if NTP was not set up).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
devtmpfs                 10.0M         0     10.0M   0% /dev&lt;br /&gt;
shm                     457.9M         0    457.9M   0% /dev/shm&lt;br /&gt;
/dev/mmcblk0p1           30.0G    259.4M     29.7G   1% /media/mmcblk0p1&lt;br /&gt;
tmpfs                   457.9M    420.0M     37.9M  92% /&lt;br /&gt;
tmpfs                    91.6M    188.0K     91.4M   0% /run&lt;br /&gt;
/dev/loop0               24.9M     24.9M         0 100% /.modloop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 lbu_commit -d&lt;br /&gt;
&lt;br /&gt;
===AutoLogin, Startx automatically on Boot===&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to login as root, and run startx manually. Now we&#039;ll add configuration files to enable that without user interaction.&lt;br /&gt;
&lt;br /&gt;
/root/ doesn&#039;t save any files, so it&#039;s necessary to edit files in /etc/ and run lbu_commit -d after all changes. First let&#039;s add a file that we&#039;ll call firefox.&lt;br /&gt;
&amp;lt;small&amp;gt;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&lt;br /&gt;
also see: /etc/apk/protected_paths.d/lbu.list&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
create a file named /etc/startup.sh:&lt;br /&gt;
 #!/bin/ash&lt;br /&gt;
 firefox-esr &amp;lt;nowiki&amp;gt;http://awebsite.com&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!!!NOTE: This is ash, not bash. By default, alpine ships with the ash shell. Bash is available in the repositories.&lt;br /&gt;
&lt;br /&gt;
We have to edit xinitrc, and the profile configs. Normally, this would be done in the user&#039;s directory, but here we will use the globals for simplicity.&lt;br /&gt;
 mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK&lt;br /&gt;
 nano /etc/X11/xinit/xinitrc&lt;br /&gt;
In this file, insert:&lt;br /&gt;
 /etc/startup.sh&lt;br /&gt;
At the end of /etc/profile (leave the existing file) append&lt;br /&gt;
 exec startx&lt;br /&gt;
Remember to run lbu_commit -d&amp;lt;BR&amp;gt;&lt;br /&gt;
For autologin, alpine uses busybox, which has an alias to /sbin/getty as well as /bin/login. It&#039;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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Set up a couple of gettys&lt;br /&gt;
#tty1::respawn:/sbin/getty 38400 tty1&lt;br /&gt;
tty2::respawn:/sbin/getty 38400 tty2&lt;br /&gt;
tty3::respawn:/sbin/getty 38400 tty3&lt;br /&gt;
tty4::respawn:/sbin/getty 38400 tty4&lt;br /&gt;
tty5::respawn:/sbin/getty 38400 tty5&lt;br /&gt;
tty6::respawn:/sbin/getty 38400 tty6&lt;br /&gt;
&lt;br /&gt;
tty1::respawn:/bin/login -f root&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Disable Screensaver, and refresh webpage (optional)===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/X11/xorg.conf|&lt;br /&gt;
Section &amp;quot;Extensions&amp;quot;&lt;br /&gt;
    Option      &amp;quot;DPMS&amp;quot; &amp;quot;Disable&amp;quot;&lt;br /&gt;
EndSection}} &lt;br /&gt;
&lt;br /&gt;
{{cmd|# apk add xdotool}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# crontab -u root -e &lt;br /&gt;
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Note: xset is not an option here as it&#039;s not included by default. It can be installed from the repositories, if needed.&amp;lt;/small&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
That&#039;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.&lt;br /&gt;
&lt;br /&gt;
==Digital Signage==&lt;br /&gt;
It&#039;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? &lt;br /&gt;
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd). &lt;br /&gt;
# There is no requirement to use &#039;cloud&#039; services, or an internet connection. &lt;br /&gt;
# You have full control over the build and design (all kiosk build steps are documented &amp;amp; have a small learning curve, compared to some of the more complex projects mentioned above).&lt;br /&gt;
# Free software. No recurring costs (outside of optional maintenance). &lt;br /&gt;
# No ties to external infrastructure / frameworks. Full freedom.&lt;br /&gt;
&lt;br /&gt;
In this addition to the guide above, we&#039;ll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we&#039;ll also run a web server with PHP, which hosts the resources we want to display on the sign.&lt;br /&gt;
Make sure community apk is enabled in /etc/apk/repositories&lt;br /&gt;
 apk add chromium&lt;br /&gt;
In /etc/startup.sh add chromium instead of firefox:&lt;br /&gt;
  chromium-browser --home-page &amp;lt;nowiki&amp;gt;http://127.0.0.1/resource&amp;lt;/nowiki&amp;gt; --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you deploy the device on a TV, and you&#039;re unsure what resolution it is, you can access the resolution from the terminal (not in X), by using &lt;br /&gt;
 xrandr -d :0&lt;br /&gt;
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&#039;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&#039;s config.h, But a WM is not required.&lt;br /&gt;
&lt;br /&gt;
Make sure to run lbu_commit -d, in order to save any changes as needed in the apkvol on the SD or HDD storage.&lt;br /&gt;
&lt;br /&gt;
===Install Apache/PHP===&lt;br /&gt;
See [[Apache]].&lt;br /&gt;
&lt;br /&gt;
===Install xset to disable screensaver===&lt;br /&gt;
 apk add xset&lt;br /&gt;
 xset q&lt;br /&gt;
 xset s off&lt;br /&gt;
&lt;br /&gt;
===Hide Scrollbars of Browser===&lt;br /&gt;
This can be done with CSS.&lt;br /&gt;
 body {&lt;br /&gt;
   overflow: hidden; /* Hide scrollbars */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
===Why was this setup used? Why not Awesome, or dwm?===&lt;br /&gt;
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&#039;t have this limitation. It should be possible to get more RAM via /boot/config.txt&lt;br /&gt;
&lt;br /&gt;
If your application doesn&#039;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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Width &amp;amp; height of firefox doesn&#039;t fit the monitor===&lt;br /&gt;
Firefox can be called with -height and -width flags, e.g. &lt;br /&gt;
{{cmd|firefox -width 480 -height 640 example.org}}&lt;br /&gt;
&lt;br /&gt;
===Periodic Firefox Crashes on RPI3 due to Low Memory===&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
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 &amp;gt;1GB ram which may eliminate the need for a nightly reboot.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* [[dwm]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22809</id>
		<title>Raspberry Pi 3 - Browser Client</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22809"/>
		<updated>2022-12-27T12:06:33Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* AutoLogin, Startx automatically on Boot */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;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.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This guide uses the following:&lt;br /&gt;
* aarch64 img (though this guide is also tested to be roughly x86-compatible)&lt;br /&gt;
* Raspberry Pi3 &lt;br /&gt;
* community repo.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
See https://pkgs.alpinelinux.org/packages?name=*firefox*&amp;amp;branch=v3.11&amp;amp;arch=aarch64&lt;br /&gt;
&lt;br /&gt;
Note: the aarch64 build is not compatible with all Raspberry Pi models. See [[Raspberry Pi]].&lt;br /&gt;
&lt;br /&gt;
==Steps==&lt;br /&gt;
===Base Install===&lt;br /&gt;
&lt;br /&gt;
These steps are duplicated from the [[Raspberry_Pi]] page. (Note that for sake of this guide, it&#039;s assumed the RPI is a RAM only install. Although there is no requirement for it to be done this way).&lt;br /&gt;
&lt;br /&gt;
Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem. &lt;br /&gt;
e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Command (m for help): p&lt;br /&gt;
Disk /dev/sdb: 59.5 GiB, 63864569856 bytes, 124735488 sectors&lt;br /&gt;
Units: sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disklabel type: dos&lt;br /&gt;
Disk identifier: 0x00000000&lt;br /&gt;
&lt;br /&gt;
Device     Boot Start      End  Sectors Size Id Type&lt;br /&gt;
/dev/sdb1  *     2048 62916607 62914560  30G  b W95 FAT32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 mkdosfs -F 32 /dev/sdX1&lt;br /&gt;
&lt;br /&gt;
untar onto mounted disk&lt;br /&gt;
&lt;br /&gt;
 mount /dev/sdX1 /mnt/folder&lt;br /&gt;
 tar xvf archive.tar -C /mnt/folder/.&lt;br /&gt;
&lt;br /&gt;
If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other&lt;br /&gt;
config settings, do so in usercfg.txt now.&lt;br /&gt;
&lt;br /&gt;
Again, duplicating the [[Raspberry Pi]] page &lt;br /&gt;
&lt;br /&gt;
    Insert the SD card into the Raspberry Pi and turn it on&lt;br /&gt;
    Log in to Alpine as root. Leave the password empty.&lt;br /&gt;
    Type setup-alpine, hit enter.&lt;br /&gt;
    Once the installation is complete, commit the changes by typing lbu commit -d&lt;br /&gt;
&lt;br /&gt;
Things to keep in mind:&lt;br /&gt;
* 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. &lt;br /&gt;
* For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with &amp;quot;No disks available, try boot media /mmcblk0p1&amp;quot;. Select the default [n]. If you make a mistake during the install, you can always reimage and start over.&lt;br /&gt;
&lt;br /&gt;
Saving space: busybox instead of chronyd, dropbear instead of openssh&lt;br /&gt;
&lt;br /&gt;
After setup, make sure dropbear is installed&lt;br /&gt;
 apk add dropbear&lt;br /&gt;
&lt;br /&gt;
Start it:&lt;br /&gt;
 rc-service dropbear start&lt;br /&gt;
&lt;br /&gt;
Add it to the default runlevel:&lt;br /&gt;
 rc-update add dropbear&lt;br /&gt;
&lt;br /&gt;
If you need an accurate clock, enable software/ntp here. (this step is optional)&lt;br /&gt;
 rc-update add swclock boot # enable the software clock &lt;br /&gt;
 rc-update del hwclock boot # disable the hardware clock&lt;br /&gt;
 setup-ntp&lt;br /&gt;
&lt;br /&gt;
===Browser Client Install===&lt;br /&gt;
&lt;br /&gt;
Enable community repo (/etc/apk/repositories) (uncomment community)&lt;br /&gt;
 nano /etc/apk/repositories&lt;br /&gt;
 apk update&lt;br /&gt;
&lt;br /&gt;
install firefox dependencies:&lt;br /&gt;
 apk add libx11-dev libxft-dev libxinerama-dev ttf-dejavu&lt;br /&gt;
&amp;lt;small&amp;gt;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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the amount of RAM tmp fs available can be viewed while installing with: watch df -h&lt;br /&gt;
&lt;br /&gt;
install firefox&lt;br /&gt;
 apk add firefox-esr&lt;br /&gt;
install X&lt;br /&gt;
 setup-xorg-base&lt;br /&gt;
The RPI also requires for X:&lt;br /&gt;
 apk add xf86-video-fbdev&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;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 &amp;quot;apk search libEGL.so&amp;quot; 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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, we have about 421MB of RAM used (if NTP was not set up).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
devtmpfs                 10.0M         0     10.0M   0% /dev&lt;br /&gt;
shm                     457.9M         0    457.9M   0% /dev/shm&lt;br /&gt;
/dev/mmcblk0p1           30.0G    259.4M     29.7G   1% /media/mmcblk0p1&lt;br /&gt;
tmpfs                   457.9M    420.0M     37.9M  92% /&lt;br /&gt;
tmpfs                    91.6M    188.0K     91.4M   0% /run&lt;br /&gt;
/dev/loop0               24.9M     24.9M         0 100% /.modloop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 lbu_commit -d&lt;br /&gt;
&lt;br /&gt;
===AutoLogin, Startx automatically on Boot===&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to login as root, and run startx manually. Now we&#039;ll add configuration files to enable that without user interaction.&lt;br /&gt;
&lt;br /&gt;
/root/ doesn&#039;t save any files, so it&#039;s necessary to edit files in /etc/ and run lbu_commit -d after all changes. First let&#039;s add a file that we&#039;ll call firefox.&lt;br /&gt;
&amp;lt;small&amp;gt;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&lt;br /&gt;
also see: /etc/apk/protected_paths.d/lbu.list&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
create a file named /etc/startup.sh:&lt;br /&gt;
 #!/bin/ash&lt;br /&gt;
 firefox-esr &amp;lt;nowiki&amp;gt;http://awebsite.com&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!!!NOTE: This is ash, not bash. By default, alpine ships with the ash shell. Bash is available in the repositories.&lt;br /&gt;
&lt;br /&gt;
We have to edit xinitrc, and the profile configs. Normally, this would be done in the user&#039;s directory, but here we will use the globals for simplicity.&lt;br /&gt;
 mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK&lt;br /&gt;
 nano /etc/X11/xinit/xinitrc&lt;br /&gt;
In this file, insert:&lt;br /&gt;
 /etc/startup.sh&lt;br /&gt;
At the end of /etc/profile (leave the existing file) append&lt;br /&gt;
 exec startx&lt;br /&gt;
Remember to run lbu_commit -d&amp;lt;BR&amp;gt;&lt;br /&gt;
For autologin, alpine uses busybox, which has an alias to /sbin/getty as well as /bin/login. It&#039;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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Set up a couple of gettys&lt;br /&gt;
#tty1::respawn:/sbin/getty 38400 tty1&lt;br /&gt;
tty2::respawn:/sbin/getty 38400 tty2&lt;br /&gt;
tty3::respawn:/sbin/getty 38400 tty3&lt;br /&gt;
tty4::respawn:/sbin/getty 38400 tty4&lt;br /&gt;
tty5::respawn:/sbin/getty 38400 tty5&lt;br /&gt;
tty6::respawn:/sbin/getty 38400 tty6&lt;br /&gt;
&lt;br /&gt;
tty1::respawn:/bin/login -f root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Disable Screensaver, and refresh webpage (optional)===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/X11/xorg.conf|&lt;br /&gt;
Section &amp;quot;Extensions&amp;quot;&lt;br /&gt;
    Option      &amp;quot;DPMS&amp;quot; &amp;quot;Disable&amp;quot;&lt;br /&gt;
EndSection}} &lt;br /&gt;
&lt;br /&gt;
{{cmd|# apk add xdotool}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# crontab -u root -e &lt;br /&gt;
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Note: xset is not an option here as it&#039;s not included by default. It can be installed from the repositories, if needed.&amp;lt;/small&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
That&#039;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.&lt;br /&gt;
&lt;br /&gt;
==Digital Signage==&lt;br /&gt;
It&#039;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? &lt;br /&gt;
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd). &lt;br /&gt;
# There is no requirement to use &#039;cloud&#039; services, or an internet connection. &lt;br /&gt;
# You have full control over the build and design (all kiosk build steps are documented &amp;amp; have a small learning curve, compared to some of the more complex projects mentioned above).&lt;br /&gt;
# Free software. No recurring costs (outside of optional maintenance). &lt;br /&gt;
# No ties to external infrastructure / frameworks. Full freedom.&lt;br /&gt;
&lt;br /&gt;
In this addition to the guide above, we&#039;ll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we&#039;ll also run a web server with PHP, which hosts the resources we want to display on the sign.&lt;br /&gt;
Make sure community apk is enabled in /etc/apk/repositories&lt;br /&gt;
 apk add chromium&lt;br /&gt;
In /etc/startup.sh add chromium instead of firefox:&lt;br /&gt;
  chromium-browser --home-page &amp;lt;nowiki&amp;gt;http://127.0.0.1/resource&amp;lt;/nowiki&amp;gt; --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you deploy the device on a TV, and you&#039;re unsure what resolution it is, you can access the resolution from the terminal (not in X), by using &lt;br /&gt;
 xrandr -d :0&lt;br /&gt;
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&#039;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&#039;s config.h, But a WM is not required.&lt;br /&gt;
&lt;br /&gt;
Make sure to run lbu_commit -d, in order to save any changes as needed in the apkvol on the SD or HDD storage.&lt;br /&gt;
&lt;br /&gt;
===Install Apache/PHP===&lt;br /&gt;
See [[Apache]].&lt;br /&gt;
&lt;br /&gt;
===Install xset to disable screensaver===&lt;br /&gt;
 apk add xset&lt;br /&gt;
 xset q&lt;br /&gt;
 xset s off&lt;br /&gt;
&lt;br /&gt;
===Hide Scrollbars of Browser===&lt;br /&gt;
This can be done with CSS.&lt;br /&gt;
 body {&lt;br /&gt;
   overflow: hidden; /* Hide scrollbars */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
===Why was this setup used? Why not Awesome, or dwm?===&lt;br /&gt;
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&#039;t have this limitation. It should be possible to get more RAM via /boot/config.txt&lt;br /&gt;
&lt;br /&gt;
If your application doesn&#039;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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Width &amp;amp; height of firefox doesn&#039;t fit the monitor===&lt;br /&gt;
Firefox can be called with -height and -width flags, e.g. &lt;br /&gt;
{{cmd|firefox -width 480 -height 640 example.org}}&lt;br /&gt;
&lt;br /&gt;
===Periodic Firefox Crashes on RPI3 due to Low Memory===&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
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 &amp;gt;1GB ram which may eliminate the need for a nightly reboot.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* [[dwm]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22808</id>
		<title>Raspberry Pi 3 - Browser Client</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22808"/>
		<updated>2022-12-27T12:05:59Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* Browser Client Install */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;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.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This guide uses the following:&lt;br /&gt;
* aarch64 img (though this guide is also tested to be roughly x86-compatible)&lt;br /&gt;
* Raspberry Pi3 &lt;br /&gt;
* community repo.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
See https://pkgs.alpinelinux.org/packages?name=*firefox*&amp;amp;branch=v3.11&amp;amp;arch=aarch64&lt;br /&gt;
&lt;br /&gt;
Note: the aarch64 build is not compatible with all Raspberry Pi models. See [[Raspberry Pi]].&lt;br /&gt;
&lt;br /&gt;
==Steps==&lt;br /&gt;
===Base Install===&lt;br /&gt;
&lt;br /&gt;
These steps are duplicated from the [[Raspberry_Pi]] page. (Note that for sake of this guide, it&#039;s assumed the RPI is a RAM only install. Although there is no requirement for it to be done this way).&lt;br /&gt;
&lt;br /&gt;
Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem. &lt;br /&gt;
e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Command (m for help): p&lt;br /&gt;
Disk /dev/sdb: 59.5 GiB, 63864569856 bytes, 124735488 sectors&lt;br /&gt;
Units: sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disklabel type: dos&lt;br /&gt;
Disk identifier: 0x00000000&lt;br /&gt;
&lt;br /&gt;
Device     Boot Start      End  Sectors Size Id Type&lt;br /&gt;
/dev/sdb1  *     2048 62916607 62914560  30G  b W95 FAT32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 mkdosfs -F 32 /dev/sdX1&lt;br /&gt;
&lt;br /&gt;
untar onto mounted disk&lt;br /&gt;
&lt;br /&gt;
 mount /dev/sdX1 /mnt/folder&lt;br /&gt;
 tar xvf archive.tar -C /mnt/folder/.&lt;br /&gt;
&lt;br /&gt;
If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other&lt;br /&gt;
config settings, do so in usercfg.txt now.&lt;br /&gt;
&lt;br /&gt;
Again, duplicating the [[Raspberry Pi]] page &lt;br /&gt;
&lt;br /&gt;
    Insert the SD card into the Raspberry Pi and turn it on&lt;br /&gt;
    Log in to Alpine as root. Leave the password empty.&lt;br /&gt;
    Type setup-alpine, hit enter.&lt;br /&gt;
    Once the installation is complete, commit the changes by typing lbu commit -d&lt;br /&gt;
&lt;br /&gt;
Things to keep in mind:&lt;br /&gt;
* 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. &lt;br /&gt;
* For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with &amp;quot;No disks available, try boot media /mmcblk0p1&amp;quot;. Select the default [n]. If you make a mistake during the install, you can always reimage and start over.&lt;br /&gt;
&lt;br /&gt;
Saving space: busybox instead of chronyd, dropbear instead of openssh&lt;br /&gt;
&lt;br /&gt;
After setup, make sure dropbear is installed&lt;br /&gt;
 apk add dropbear&lt;br /&gt;
&lt;br /&gt;
Start it:&lt;br /&gt;
 rc-service dropbear start&lt;br /&gt;
&lt;br /&gt;
Add it to the default runlevel:&lt;br /&gt;
 rc-update add dropbear&lt;br /&gt;
&lt;br /&gt;
If you need an accurate clock, enable software/ntp here. (this step is optional)&lt;br /&gt;
 rc-update add swclock boot # enable the software clock &lt;br /&gt;
 rc-update del hwclock boot # disable the hardware clock&lt;br /&gt;
 setup-ntp&lt;br /&gt;
&lt;br /&gt;
===Browser Client Install===&lt;br /&gt;
&lt;br /&gt;
Enable community repo (/etc/apk/repositories) (uncomment community)&lt;br /&gt;
 nano /etc/apk/repositories&lt;br /&gt;
 apk update&lt;br /&gt;
&lt;br /&gt;
install firefox dependencies:&lt;br /&gt;
 apk add libx11-dev libxft-dev libxinerama-dev ttf-dejavu&lt;br /&gt;
&amp;lt;small&amp;gt;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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the amount of RAM tmp fs available can be viewed while installing with: watch df -h&lt;br /&gt;
&lt;br /&gt;
install firefox&lt;br /&gt;
 apk add firefox-esr&lt;br /&gt;
install X&lt;br /&gt;
 setup-xorg-base&lt;br /&gt;
The RPI also requires for X:&lt;br /&gt;
 apk add xf86-video-fbdev&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;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 &amp;quot;apk search libEGL.so&amp;quot; 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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, we have about 421MB of RAM used (if NTP was not set up).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
devtmpfs                 10.0M         0     10.0M   0% /dev&lt;br /&gt;
shm                     457.9M         0    457.9M   0% /dev/shm&lt;br /&gt;
/dev/mmcblk0p1           30.0G    259.4M     29.7G   1% /media/mmcblk0p1&lt;br /&gt;
tmpfs                   457.9M    420.0M     37.9M  92% /&lt;br /&gt;
tmpfs                    91.6M    188.0K     91.4M   0% /run&lt;br /&gt;
/dev/loop0               24.9M     24.9M         0 100% /.modloop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 lbu_commit -d&lt;br /&gt;
&lt;br /&gt;
===AutoLogin, Startx automatically on Boot===&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to login as root, and run startx manually. Now we&#039;ll add configuration files to enable that without user interaction.&lt;br /&gt;
&lt;br /&gt;
/root/ doesn&#039;t save any files, so it&#039;s necessary to edit files in /etc/ and run lbu_commit -d after all changes. First let&#039;s add a file that we&#039;ll call firefox.&lt;br /&gt;
&amp;lt;small&amp;gt;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&lt;br /&gt;
also see: /etc/apk/protected_paths.d/lbu.list&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
create a file named /etc/startup.sh:&lt;br /&gt;
 #!/bin/ash&lt;br /&gt;
 firefox-esr &amp;lt;nowiki&amp;gt;http://somewebsite.com&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!!!NOTE: This is ash, not bash. By default, alpine ships with the ash shell. Bash is available in the repositories.&lt;br /&gt;
&lt;br /&gt;
We have to edit xinitrc, and the profile configs. Normally, this would be done in the user&#039;s directory, but here we will use the globals for simplicity.&lt;br /&gt;
 mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK&lt;br /&gt;
 nano /etc/X11/xinit/xinitrc&lt;br /&gt;
In this file, insert:&lt;br /&gt;
 /etc/startup.sh&lt;br /&gt;
At the end of /etc/profile (leave the existing file) append&lt;br /&gt;
 exec startx&lt;br /&gt;
Remember to run lbu_commit -d&amp;lt;BR&amp;gt;&lt;br /&gt;
For autologin, alpine uses busybox, which has an alias to /sbin/getty as well as /bin/login. It&#039;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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Set up a couple of gettys&lt;br /&gt;
#tty1::respawn:/sbin/getty 38400 tty1&lt;br /&gt;
tty2::respawn:/sbin/getty 38400 tty2&lt;br /&gt;
tty3::respawn:/sbin/getty 38400 tty3&lt;br /&gt;
tty4::respawn:/sbin/getty 38400 tty4&lt;br /&gt;
tty5::respawn:/sbin/getty 38400 tty5&lt;br /&gt;
tty6::respawn:/sbin/getty 38400 tty6&lt;br /&gt;
&lt;br /&gt;
tty1::respawn:/bin/login -f root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Disable Screensaver, and refresh webpage (optional)===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/X11/xorg.conf|&lt;br /&gt;
Section &amp;quot;Extensions&amp;quot;&lt;br /&gt;
    Option      &amp;quot;DPMS&amp;quot; &amp;quot;Disable&amp;quot;&lt;br /&gt;
EndSection}} &lt;br /&gt;
&lt;br /&gt;
{{cmd|# apk add xdotool}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# crontab -u root -e &lt;br /&gt;
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Note: xset is not an option here as it&#039;s not included by default. It can be installed from the repositories, if needed.&amp;lt;/small&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
That&#039;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.&lt;br /&gt;
&lt;br /&gt;
==Digital Signage==&lt;br /&gt;
It&#039;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? &lt;br /&gt;
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd). &lt;br /&gt;
# There is no requirement to use &#039;cloud&#039; services, or an internet connection. &lt;br /&gt;
# You have full control over the build and design (all kiosk build steps are documented &amp;amp; have a small learning curve, compared to some of the more complex projects mentioned above).&lt;br /&gt;
# Free software. No recurring costs (outside of optional maintenance). &lt;br /&gt;
# No ties to external infrastructure / frameworks. Full freedom.&lt;br /&gt;
&lt;br /&gt;
In this addition to the guide above, we&#039;ll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we&#039;ll also run a web server with PHP, which hosts the resources we want to display on the sign.&lt;br /&gt;
Make sure community apk is enabled in /etc/apk/repositories&lt;br /&gt;
 apk add chromium&lt;br /&gt;
In /etc/startup.sh add chromium instead of firefox:&lt;br /&gt;
  chromium-browser --home-page &amp;lt;nowiki&amp;gt;http://127.0.0.1/resource&amp;lt;/nowiki&amp;gt; --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you deploy the device on a TV, and you&#039;re unsure what resolution it is, you can access the resolution from the terminal (not in X), by using &lt;br /&gt;
 xrandr -d :0&lt;br /&gt;
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&#039;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&#039;s config.h, But a WM is not required.&lt;br /&gt;
&lt;br /&gt;
Make sure to run lbu_commit -d, in order to save any changes as needed in the apkvol on the SD or HDD storage.&lt;br /&gt;
&lt;br /&gt;
===Install Apache/PHP===&lt;br /&gt;
See [[Apache]].&lt;br /&gt;
&lt;br /&gt;
===Install xset to disable screensaver===&lt;br /&gt;
 apk add xset&lt;br /&gt;
 xset q&lt;br /&gt;
 xset s off&lt;br /&gt;
&lt;br /&gt;
===Hide Scrollbars of Browser===&lt;br /&gt;
This can be done with CSS.&lt;br /&gt;
 body {&lt;br /&gt;
   overflow: hidden; /* Hide scrollbars */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
===Why was this setup used? Why not Awesome, or dwm?===&lt;br /&gt;
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&#039;t have this limitation. It should be possible to get more RAM via /boot/config.txt&lt;br /&gt;
&lt;br /&gt;
If your application doesn&#039;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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Width &amp;amp; height of firefox doesn&#039;t fit the monitor===&lt;br /&gt;
Firefox can be called with -height and -width flags, e.g. &lt;br /&gt;
{{cmd|firefox -width 480 -height 640 example.org}}&lt;br /&gt;
&lt;br /&gt;
===Periodic Firefox Crashes on RPI3 due to Low Memory===&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
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 &amp;gt;1GB ram which may eliminate the need for a nightly reboot.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* [[dwm]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22807</id>
		<title>Raspberry Pi 3 - Browser Client</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22807"/>
		<updated>2022-12-27T12:05:29Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* Base Install */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;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.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This guide uses the following:&lt;br /&gt;
* aarch64 img (though this guide is also tested to be roughly x86-compatible)&lt;br /&gt;
* Raspberry Pi3 &lt;br /&gt;
* community repo.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
See https://pkgs.alpinelinux.org/packages?name=*firefox*&amp;amp;branch=v3.11&amp;amp;arch=aarch64&lt;br /&gt;
&lt;br /&gt;
Note: the aarch64 build is not compatible with all Raspberry Pi models. See [[Raspberry Pi]].&lt;br /&gt;
&lt;br /&gt;
==Steps==&lt;br /&gt;
===Base Install===&lt;br /&gt;
&lt;br /&gt;
These steps are duplicated from the [[Raspberry_Pi]] page. (Note that for sake of this guide, it&#039;s assumed the RPI is a RAM only install. Although there is no requirement for it to be done this way).&lt;br /&gt;
&lt;br /&gt;
Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem. &lt;br /&gt;
e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Command (m for help): p&lt;br /&gt;
Disk /dev/sdb: 59.5 GiB, 63864569856 bytes, 124735488 sectors&lt;br /&gt;
Units: sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disklabel type: dos&lt;br /&gt;
Disk identifier: 0x00000000&lt;br /&gt;
&lt;br /&gt;
Device     Boot Start      End  Sectors Size Id Type&lt;br /&gt;
/dev/sdb1  *     2048 62916607 62914560  30G  b W95 FAT32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 mkdosfs -F 32 /dev/sdX1&lt;br /&gt;
&lt;br /&gt;
untar onto mounted disk&lt;br /&gt;
&lt;br /&gt;
 mount /dev/sdX1 /mnt/folder&lt;br /&gt;
 tar xvf archive.tar -C /mnt/folder/.&lt;br /&gt;
&lt;br /&gt;
If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other&lt;br /&gt;
config settings, do so in usercfg.txt now.&lt;br /&gt;
&lt;br /&gt;
Again, duplicating the [[Raspberry Pi]] page &lt;br /&gt;
&lt;br /&gt;
    Insert the SD card into the Raspberry Pi and turn it on&lt;br /&gt;
    Log in to Alpine as root. Leave the password empty.&lt;br /&gt;
    Type setup-alpine, hit enter.&lt;br /&gt;
    Once the installation is complete, commit the changes by typing lbu commit -d&lt;br /&gt;
&lt;br /&gt;
Things to keep in mind:&lt;br /&gt;
* 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. &lt;br /&gt;
* For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with &amp;quot;No disks available, try boot media /mmcblk0p1&amp;quot;. Select the default [n]. If you make a mistake during the install, you can always reimage and start over.&lt;br /&gt;
&lt;br /&gt;
Saving space: busybox instead of chronyd, dropbear instead of openssh&lt;br /&gt;
&lt;br /&gt;
After setup, make sure dropbear is installed&lt;br /&gt;
 apk add dropbear&lt;br /&gt;
&lt;br /&gt;
Start it:&lt;br /&gt;
 rc-service dropbear start&lt;br /&gt;
&lt;br /&gt;
Add it to the default runlevel:&lt;br /&gt;
 rc-update add dropbear&lt;br /&gt;
&lt;br /&gt;
If you need an accurate clock, enable software/ntp here. (this step is optional)&lt;br /&gt;
 rc-update add swclock boot # enable the software clock &lt;br /&gt;
 rc-update del hwclock boot # disable the hardware clock&lt;br /&gt;
 setup-ntp&lt;br /&gt;
&lt;br /&gt;
===Browser Client Install===&lt;br /&gt;
&lt;br /&gt;
Enable community repo (/etc/apk/repositories) (uncomment community)&lt;br /&gt;
 nano /etc/apk/repositories&lt;br /&gt;
 apk update&lt;br /&gt;
&lt;br /&gt;
install the firefox and X dependencies:&lt;br /&gt;
 apk add libx11-dev libxft-dev libxinerama-dev ttf-dejavu&lt;br /&gt;
&amp;lt;small&amp;gt;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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the amount of RAM tmp fs available can be viewed while installing with: watch df -h&lt;br /&gt;
&lt;br /&gt;
install firefox&lt;br /&gt;
 apk add firefox-esr&lt;br /&gt;
install X&lt;br /&gt;
 setup-xorg-base&lt;br /&gt;
The RPI also requires for X:&lt;br /&gt;
 apk add xf86-video-fbdev&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;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 &amp;quot;apk search libEGL.so&amp;quot; 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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, we have about 421MB of RAM used (if NTP was not set up).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
devtmpfs                 10.0M         0     10.0M   0% /dev&lt;br /&gt;
shm                     457.9M         0    457.9M   0% /dev/shm&lt;br /&gt;
/dev/mmcblk0p1           30.0G    259.4M     29.7G   1% /media/mmcblk0p1&lt;br /&gt;
tmpfs                   457.9M    420.0M     37.9M  92% /&lt;br /&gt;
tmpfs                    91.6M    188.0K     91.4M   0% /run&lt;br /&gt;
/dev/loop0               24.9M     24.9M         0 100% /.modloop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 lbu_commit -d&lt;br /&gt;
&lt;br /&gt;
===AutoLogin, Startx automatically on Boot===&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to login as root, and run startx manually. Now we&#039;ll add configuration files to enable that without user interaction.&lt;br /&gt;
&lt;br /&gt;
/root/ doesn&#039;t save any files, so it&#039;s necessary to edit files in /etc/ and run lbu_commit -d after all changes. First let&#039;s add a file that we&#039;ll call firefox.&lt;br /&gt;
&amp;lt;small&amp;gt;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&lt;br /&gt;
also see: /etc/apk/protected_paths.d/lbu.list&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
create a file named /etc/startup.sh:&lt;br /&gt;
 #!/bin/ash&lt;br /&gt;
 firefox-esr &amp;lt;nowiki&amp;gt;http://somewebsite.com&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!!!NOTE: This is ash, not bash. By default, alpine ships with the ash shell. Bash is available in the repositories.&lt;br /&gt;
&lt;br /&gt;
We have to edit xinitrc, and the profile configs. Normally, this would be done in the user&#039;s directory, but here we will use the globals for simplicity.&lt;br /&gt;
 mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK&lt;br /&gt;
 nano /etc/X11/xinit/xinitrc&lt;br /&gt;
In this file, insert:&lt;br /&gt;
 /etc/startup.sh&lt;br /&gt;
At the end of /etc/profile (leave the existing file) append&lt;br /&gt;
 exec startx&lt;br /&gt;
Remember to run lbu_commit -d&amp;lt;BR&amp;gt;&lt;br /&gt;
For autologin, alpine uses busybox, which has an alias to /sbin/getty as well as /bin/login. It&#039;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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Set up a couple of gettys&lt;br /&gt;
#tty1::respawn:/sbin/getty 38400 tty1&lt;br /&gt;
tty2::respawn:/sbin/getty 38400 tty2&lt;br /&gt;
tty3::respawn:/sbin/getty 38400 tty3&lt;br /&gt;
tty4::respawn:/sbin/getty 38400 tty4&lt;br /&gt;
tty5::respawn:/sbin/getty 38400 tty5&lt;br /&gt;
tty6::respawn:/sbin/getty 38400 tty6&lt;br /&gt;
&lt;br /&gt;
tty1::respawn:/bin/login -f root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Disable Screensaver, and refresh webpage (optional)===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/X11/xorg.conf|&lt;br /&gt;
Section &amp;quot;Extensions&amp;quot;&lt;br /&gt;
    Option      &amp;quot;DPMS&amp;quot; &amp;quot;Disable&amp;quot;&lt;br /&gt;
EndSection}} &lt;br /&gt;
&lt;br /&gt;
{{cmd|# apk add xdotool}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# crontab -u root -e &lt;br /&gt;
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Note: xset is not an option here as it&#039;s not included by default. It can be installed from the repositories, if needed.&amp;lt;/small&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
That&#039;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.&lt;br /&gt;
&lt;br /&gt;
==Digital Signage==&lt;br /&gt;
It&#039;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? &lt;br /&gt;
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd). &lt;br /&gt;
# There is no requirement to use &#039;cloud&#039; services, or an internet connection. &lt;br /&gt;
# You have full control over the build and design (all kiosk build steps are documented &amp;amp; have a small learning curve, compared to some of the more complex projects mentioned above).&lt;br /&gt;
# Free software. No recurring costs (outside of optional maintenance). &lt;br /&gt;
# No ties to external infrastructure / frameworks. Full freedom.&lt;br /&gt;
&lt;br /&gt;
In this addition to the guide above, we&#039;ll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we&#039;ll also run a web server with PHP, which hosts the resources we want to display on the sign.&lt;br /&gt;
Make sure community apk is enabled in /etc/apk/repositories&lt;br /&gt;
 apk add chromium&lt;br /&gt;
In /etc/startup.sh add chromium instead of firefox:&lt;br /&gt;
  chromium-browser --home-page &amp;lt;nowiki&amp;gt;http://127.0.0.1/resource&amp;lt;/nowiki&amp;gt; --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you deploy the device on a TV, and you&#039;re unsure what resolution it is, you can access the resolution from the terminal (not in X), by using &lt;br /&gt;
 xrandr -d :0&lt;br /&gt;
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&#039;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&#039;s config.h, But a WM is not required.&lt;br /&gt;
&lt;br /&gt;
Make sure to run lbu_commit -d, in order to save any changes as needed in the apkvol on the SD or HDD storage.&lt;br /&gt;
&lt;br /&gt;
===Install Apache/PHP===&lt;br /&gt;
See [[Apache]].&lt;br /&gt;
&lt;br /&gt;
===Install xset to disable screensaver===&lt;br /&gt;
 apk add xset&lt;br /&gt;
 xset q&lt;br /&gt;
 xset s off&lt;br /&gt;
&lt;br /&gt;
===Hide Scrollbars of Browser===&lt;br /&gt;
This can be done with CSS.&lt;br /&gt;
 body {&lt;br /&gt;
   overflow: hidden; /* Hide scrollbars */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
===Why was this setup used? Why not Awesome, or dwm?===&lt;br /&gt;
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&#039;t have this limitation. It should be possible to get more RAM via /boot/config.txt&lt;br /&gt;
&lt;br /&gt;
If your application doesn&#039;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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Width &amp;amp; height of firefox doesn&#039;t fit the monitor===&lt;br /&gt;
Firefox can be called with -height and -width flags, e.g. &lt;br /&gt;
{{cmd|firefox -width 480 -height 640 example.org}}&lt;br /&gt;
&lt;br /&gt;
===Periodic Firefox Crashes on RPI3 due to Low Memory===&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
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 &amp;gt;1GB ram which may eliminate the need for a nightly reboot.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* [[dwm]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22806</id>
		<title>Raspberry Pi 3 - Browser Client</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Raspberry_Pi_3_-_Browser_Client&amp;diff=22806"/>
		<updated>2022-12-27T12:01:40Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;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.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
This guide uses the following:&lt;br /&gt;
* aarch64 img (though this guide is also tested to be roughly x86-compatible)&lt;br /&gt;
* Raspberry Pi3 &lt;br /&gt;
* community repo.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
See https://pkgs.alpinelinux.org/packages?name=*firefox*&amp;amp;branch=v3.11&amp;amp;arch=aarch64&lt;br /&gt;
&lt;br /&gt;
Note: the aarch64 build is not compatible with all Raspberry Pi models. See [[Raspberry Pi]].&lt;br /&gt;
&lt;br /&gt;
==Steps==&lt;br /&gt;
===Base Install===&lt;br /&gt;
&lt;br /&gt;
These steps are duplicated from the [[Raspberry_Pi]] page.&lt;br /&gt;
&lt;br /&gt;
Use fdisk or gdisk to format the SD card. The first partition must be a bootable, FAT filesystem. &lt;br /&gt;
e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Command (m for help): p&lt;br /&gt;
Disk /dev/sdb: 59.5 GiB, 63864569856 bytes, 124735488 sectors&lt;br /&gt;
Units: sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disklabel type: dos&lt;br /&gt;
Disk identifier: 0x00000000&lt;br /&gt;
&lt;br /&gt;
Device     Boot Start      End  Sectors Size Id Type&lt;br /&gt;
/dev/sdb1  *     2048 62916607 62914560  30G  b W95 FAT32&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 mkdosfs -F 32 /dev/sdX1&lt;br /&gt;
&lt;br /&gt;
untar onto mounted disk&lt;br /&gt;
&lt;br /&gt;
 mount /dev/sdX1 /mnt/folder&lt;br /&gt;
 tar xvf archive.tar -C /mnt/folder/.&lt;br /&gt;
&lt;br /&gt;
If you plan to increase available RAM (e.g. for RPI4 with 2 or 4GB) or change other&lt;br /&gt;
config settings, do so in usercfg.txt now.&lt;br /&gt;
&lt;br /&gt;
Again, duplicating the [[Raspberry Pi]] page &lt;br /&gt;
&lt;br /&gt;
    Insert the SD card into the Raspberry Pi and turn it on&lt;br /&gt;
    Log in to Alpine as root. Leave the password empty.&lt;br /&gt;
    Type setup-alpine, hit enter.&lt;br /&gt;
    Once the installation is complete, commit the changes by typing lbu commit -d&lt;br /&gt;
&lt;br /&gt;
Things to keep in mind:&lt;br /&gt;
* 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. &lt;br /&gt;
* For the setup-alpine install, most of the choices will be the defaults. Particularly when prompted with &amp;quot;No disks available, try boot media /mmcblk0p1&amp;quot;. Select the default [n]. If you make a mistake during the install, you can always reimage and start over.&lt;br /&gt;
&lt;br /&gt;
Saving space: busybox instead of chronyd, dropbear instead of openssh&lt;br /&gt;
&lt;br /&gt;
After setup, make sure dropbear is installed&lt;br /&gt;
 apk add dropbear&lt;br /&gt;
&lt;br /&gt;
Start it:&lt;br /&gt;
 rc-service dropbear start&lt;br /&gt;
&lt;br /&gt;
Add it to the default runlevel:&lt;br /&gt;
 rc-update add dropbear&lt;br /&gt;
&lt;br /&gt;
If you need an accurate clock, enable software/ntp here. (this step is optional)&lt;br /&gt;
 rc-update add swclock boot # enable the software clock &lt;br /&gt;
 rc-update del hwclock boot # disable the hardware clock&lt;br /&gt;
 setup-ntp&lt;br /&gt;
&lt;br /&gt;
===Browser Client Install===&lt;br /&gt;
&lt;br /&gt;
Enable community repo (/etc/apk/repositories) (uncomment community)&lt;br /&gt;
 nano /etc/apk/repositories&lt;br /&gt;
 apk update&lt;br /&gt;
&lt;br /&gt;
install the firefox and X dependencies:&lt;br /&gt;
 apk add libx11-dev libxft-dev libxinerama-dev ttf-dejavu&lt;br /&gt;
&amp;lt;small&amp;gt;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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the amount of RAM tmp fs available can be viewed while installing with: watch df -h&lt;br /&gt;
&lt;br /&gt;
install firefox&lt;br /&gt;
 apk add firefox-esr&lt;br /&gt;
install X&lt;br /&gt;
 setup-xorg-base&lt;br /&gt;
The RPI also requires for X:&lt;br /&gt;
 apk add xf86-video-fbdev&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;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 &amp;quot;apk search libEGL.so&amp;quot; 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.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, we have about 421MB of RAM used (if NTP was not set up).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
devtmpfs                 10.0M         0     10.0M   0% /dev&lt;br /&gt;
shm                     457.9M         0    457.9M   0% /dev/shm&lt;br /&gt;
/dev/mmcblk0p1           30.0G    259.4M     29.7G   1% /media/mmcblk0p1&lt;br /&gt;
tmpfs                   457.9M    420.0M     37.9M  92% /&lt;br /&gt;
tmpfs                    91.6M    188.0K     91.4M   0% /run&lt;br /&gt;
/dev/loop0               24.9M     24.9M         0 100% /.modloop&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 lbu_commit -d&lt;br /&gt;
&lt;br /&gt;
===AutoLogin, Startx automatically on Boot===&lt;br /&gt;
&lt;br /&gt;
At this point, you should be able to login as root, and run startx manually. Now we&#039;ll add configuration files to enable that without user interaction.&lt;br /&gt;
&lt;br /&gt;
/root/ doesn&#039;t save any files, so it&#039;s necessary to edit files in /etc/ and run lbu_commit -d after all changes. First let&#039;s add a file that we&#039;ll call firefox.&lt;br /&gt;
&amp;lt;small&amp;gt;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&lt;br /&gt;
also see: /etc/apk/protected_paths.d/lbu.list&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
create a file named /etc/startup.sh:&lt;br /&gt;
 #!/bin/ash&lt;br /&gt;
 firefox-esr &amp;lt;nowiki&amp;gt;http://somewebsite.com&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
!!!NOTE: This is ash, not bash. By default, alpine ships with the ash shell. Bash is available in the repositories.&lt;br /&gt;
&lt;br /&gt;
We have to edit xinitrc, and the profile configs. Normally, this would be done in the user&#039;s directory, but here we will use the globals for simplicity.&lt;br /&gt;
 mv /etc/X11/xinit/xinitrc /etc/X11/xinit/xinitrc_BAK&lt;br /&gt;
 nano /etc/X11/xinit/xinitrc&lt;br /&gt;
In this file, insert:&lt;br /&gt;
 /etc/startup.sh&lt;br /&gt;
At the end of /etc/profile (leave the existing file) append&lt;br /&gt;
 exec startx&lt;br /&gt;
Remember to run lbu_commit -d&amp;lt;BR&amp;gt;&lt;br /&gt;
For autologin, alpine uses busybox, which has an alias to /sbin/getty as well as /bin/login. It&#039;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:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Set up a couple of gettys&lt;br /&gt;
#tty1::respawn:/sbin/getty 38400 tty1&lt;br /&gt;
tty2::respawn:/sbin/getty 38400 tty2&lt;br /&gt;
tty3::respawn:/sbin/getty 38400 tty3&lt;br /&gt;
tty4::respawn:/sbin/getty 38400 tty4&lt;br /&gt;
tty5::respawn:/sbin/getty 38400 tty5&lt;br /&gt;
tty6::respawn:/sbin/getty 38400 tty6&lt;br /&gt;
&lt;br /&gt;
tty1::respawn:/bin/login -f root&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Disable Screensaver, and refresh webpage (optional)===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
{{cat|/etc/X11/xorg.conf|&lt;br /&gt;
Section &amp;quot;Extensions&amp;quot;&lt;br /&gt;
    Option      &amp;quot;DPMS&amp;quot; &amp;quot;Disable&amp;quot;&lt;br /&gt;
EndSection}} &lt;br /&gt;
&lt;br /&gt;
{{cmd|# apk add xdotool}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# crontab -u root -e &lt;br /&gt;
* * * * * DISPLAY=:0 /usr/bin/xdotool key F5&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Note: xset is not an option here as it&#039;s not included by default. It can be installed from the repositories, if needed.&amp;lt;/small&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
That&#039;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.&lt;br /&gt;
&lt;br /&gt;
==Digital Signage==&lt;br /&gt;
It&#039;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? &lt;br /&gt;
# Alpine runs from RAM, which increases the lifetime of the storage (flash / hdd). &lt;br /&gt;
# There is no requirement to use &#039;cloud&#039; services, or an internet connection. &lt;br /&gt;
# You have full control over the build and design (all kiosk build steps are documented &amp;amp; have a small learning curve, compared to some of the more complex projects mentioned above).&lt;br /&gt;
# Free software. No recurring costs (outside of optional maintenance). &lt;br /&gt;
# No ties to external infrastructure / frameworks. Full freedom.&lt;br /&gt;
&lt;br /&gt;
In this addition to the guide above, we&#039;ll install Chromium, which seems to be the defacto standard. However, you could use any X-Window application. Here we&#039;ll also run a web server with PHP, which hosts the resources we want to display on the sign.&lt;br /&gt;
Make sure community apk is enabled in /etc/apk/repositories&lt;br /&gt;
 apk add chromium&lt;br /&gt;
In /etc/startup.sh add chromium instead of firefox:&lt;br /&gt;
  chromium-browser --home-page &amp;lt;nowiki&amp;gt;http://127.0.0.1/resource&amp;lt;/nowiki&amp;gt; --no-sandbox --window-size=1920,1280 --start-fullscreen --test-type&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
If you deploy the device on a TV, and you&#039;re unsure what resolution it is, you can access the resolution from the terminal (not in X), by using &lt;br /&gt;
 xrandr -d :0&lt;br /&gt;
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&#039;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&#039;s config.h, But a WM is not required.&lt;br /&gt;
&lt;br /&gt;
Make sure to run lbu_commit -d, in order to save any changes as needed in the apkvol on the SD or HDD storage.&lt;br /&gt;
&lt;br /&gt;
===Install Apache/PHP===&lt;br /&gt;
See [[Apache]].&lt;br /&gt;
&lt;br /&gt;
===Install xset to disable screensaver===&lt;br /&gt;
 apk add xset&lt;br /&gt;
 xset q&lt;br /&gt;
 xset s off&lt;br /&gt;
&lt;br /&gt;
===Hide Scrollbars of Browser===&lt;br /&gt;
This can be done with CSS.&lt;br /&gt;
 body {&lt;br /&gt;
   overflow: hidden; /* Hide scrollbars */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
===Why was this setup used? Why not Awesome, or dwm?===&lt;br /&gt;
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&#039;t have this limitation. It should be possible to get more RAM via /boot/config.txt&lt;br /&gt;
&lt;br /&gt;
If your application doesn&#039;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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
===Width &amp;amp; height of firefox doesn&#039;t fit the monitor===&lt;br /&gt;
Firefox can be called with -height and -width flags, e.g. &lt;br /&gt;
{{cmd|firefox -width 480 -height 640 example.org}}&lt;br /&gt;
&lt;br /&gt;
===Periodic Firefox Crashes on RPI3 due to Low Memory===&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
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 &amp;gt;1GB ram which may eliminate the need for a nightly reboot.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* [[dwm]]&lt;br /&gt;
* [[Raspberry Pi]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Raspberry]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Ethernet&amp;diff=22805</id>
		<title>Ethernet</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Ethernet&amp;diff=22805"/>
		<updated>2022-12-27T11:36:51Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;From [https://en.wikipedia.org/wiki/Ethernet Wikipedia]:&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ethernet is a family of wired computer networking technologies commonly used in local area networks (LAN), metropolitan area networks (MAN) and wide area networks (WAN). It was commercially introduced in 1980 and first standardized in 1983 as IEEE 802.3. Ethernet has since been refined to support higher bit rates, a greater number of nodes, and longer link distances, but retains much backward compatibility. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Setup ==&lt;br /&gt;
&lt;br /&gt;
When installing [[Alpine setup scripts|setup-alpine]] should give you the option to easily setup Ethernet or if you need to setup Ethernet after installation you can use [[Alpine setup scripts#setup-interfaces|setup-interfaces]].&lt;br /&gt;
&lt;br /&gt;
==== setup-interfaces ====&lt;br /&gt;
&lt;br /&gt;
start by running this command:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|# setup-interfaces}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Cat|setup-interfaces|Available interfaces are: eth0 wlan0.&lt;br /&gt;
Enter &#039;?&#039; for help on bridges, bonding and vlans.&lt;br /&gt;
Which one do you want to initialize? (or &#039;?&#039; or &#039;done&#039;) [eth0]}}&lt;br /&gt;
&lt;br /&gt;
choose &amp;lt;code&amp;gt;eth0&amp;lt;/code&amp;gt; (or your Ethernet device, Ethernet devices usually start with &amp;lt;code&amp;gt;e&amp;lt;/code&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if asked:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Ip address for eth0? (or &#039;dhcp&#039;, &#039;none&#039;, &#039;?&#039;) [dhcp]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
choose &#039;&#039;&#039;dhcp&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now it will ask &amp;lt;code&amp;gt;Do you to do any manual network configuration? (y/n) [n]&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unless you need to do manual network configuration choose &#039;&#039;&#039;n&#039;&#039;&#039;, if you need to do manual network configuration choose &#039;&#039;&#039;y&#039;&#039;&#039; and it will open the &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if  &amp;lt;code&amp;gt;setup-interfaces&amp;lt;/code&amp;gt; doesnt do this automatically, then you need to &#039;&#039;&#039;start&#039;&#039;&#039; (or &#039;&#039;&#039;restart&#039;&#039;&#039;) the networking service:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|# /etc/init.d/networking --quiet start &amp;amp;}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and add it to start on boot:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|# rc-update add networking boot}}&lt;br /&gt;
&lt;br /&gt;
==Tips / Troubleshooting==&lt;br /&gt;
Sometimes an ethernet interface will not be detected by the installation media. In this case, you may have to use an alternate interface for installation (e.g. a usb to ethernet adapter) upon which after install / reboot the interface will display. You may also try installing any missing packages that contain the drivers.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Networking]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=22650</id>
		<title>ZoneMinder video camera security and surveillance</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=22650"/>
		<updated>2022-11-04T19:47:55Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* Conclusion */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://www.zoneminder.com/ ZoneMinder] usually runs with [[Apache]], but in this short how-to we use [[Lighttpd]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Base Install==&lt;br /&gt;
&lt;br /&gt;
ZoneMinder is found in the community repositories, please enable it by following the instructions [[Repositories#Enabling_the_community_repository|here]]&lt;br /&gt;
&lt;br /&gt;
Then, add the needed packages to our system&lt;br /&gt;
&lt;br /&gt;
 apk add zoneminder mariadb mysql-client lighttpd php8-fpm php8-pdo php8-pdo_mysql&lt;br /&gt;
&lt;br /&gt;
===Database===&lt;br /&gt;
&lt;br /&gt;
Initialize [https://www.mysql.com/ MySQL] database&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/mariadb setup&lt;br /&gt;
&lt;br /&gt;
Start the database&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/mariadb start&lt;br /&gt;
&lt;br /&gt;
Set root password for MySQL as instructed by MySQL setup&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mysqladmin -u root password &#039;your_secure_root_mysql_password&#039;&lt;br /&gt;
&lt;br /&gt;
You can log into MySQL as current root user with&lt;br /&gt;
 mysql&lt;br /&gt;
&lt;br /&gt;
Create a ZoneMinder MySQL database and user&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; create database zm;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; CREATE USER zmuser@localhost IDENTIFIED BY &#039;your_zm_password_as_set_in_config&#039;;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; grant ALL on zm.* to zmuser@localhost;&lt;br /&gt;
&lt;br /&gt;
===Web Server===&lt;br /&gt;
&lt;br /&gt;
We are running &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;, so let&#039;s run &amp;lt;code&amp;gt;php-fpm&amp;lt;/code&amp;gt; as lighttpd user/group&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php8/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
Add this section to the bottom of the file:&lt;br /&gt;
&lt;br /&gt;
 ; Unix user/group of processes&lt;br /&gt;
 ; Note: The user is mandatory. If the group is not set, the default user&#039;s group&lt;br /&gt;
 ;       will be used.&lt;br /&gt;
 ;user = nobody&lt;br /&gt;
 ;group = nobody&lt;br /&gt;
 user = lighttpd&lt;br /&gt;
 group = lighttpd&lt;br /&gt;
&lt;br /&gt;
Enable the php cgi fpm config in &amp;lt;code&amp;gt;lighttpd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
Go down to the server modules section and uncomment &amp;lt;code&amp;gt;mod_alias&amp;lt;/code&amp;gt;, which is needed for the cgi-bin, and &amp;lt;code&amp;gt;mod_rewrite&amp;lt;/code&amp;gt;, for the api. It should look like:&lt;br /&gt;
&lt;br /&gt;
 # {{{ modules&lt;br /&gt;
 # At the very least, mod_access and mod_accesslog should be enabled.&lt;br /&gt;
 # All other modules should only be loaded if necessary.&lt;br /&gt;
 # NOTE: the order of modules is important.&lt;br /&gt;
 server.modules = (&lt;br /&gt;
      &amp;quot;mod_rewrite&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_redirect&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_alias&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_access&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_cml&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_trigger_b4_dl&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_auth&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_status&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_setenv&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_proxy&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_simple_vhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_evhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_userdir&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_deflate&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_ssi&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_usertrack&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_expire&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_secdownload&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_rrdtool&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_webdav&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_accesslog&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
Go down to the includes section, it should look like:&lt;br /&gt;
 # {{{ includes&lt;br /&gt;
 include &amp;quot;mime-types.conf&amp;quot;&lt;br /&gt;
 # uncomment for cgi support&lt;br /&gt;
    include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi support&lt;br /&gt;
 #   include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi fpm support&lt;br /&gt;
    include &amp;quot;mod_fastcgi_fpm.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
In order for video streaming to work in 1.36, you&#039;ll need the following&lt;br /&gt;
added to /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
 server.stream-response-body = 1&lt;br /&gt;
&lt;br /&gt;
In lighttpd.conf for the API, we will want to redirect any api+ requests to cakephp. Thus, add:&lt;br /&gt;
 url.rewrite = (&lt;br /&gt;
       &amp;quot;^/zm/api(.+)$&amp;quot;           =&amp;gt;              &amp;quot;/zm/api/index.php&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Edit lighttpd cgi config and add old style cgi support by adding to cgi.assign&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/mod_cgi.conf&lt;br /&gt;
&lt;br /&gt;
which should look like&lt;br /&gt;
&lt;br /&gt;
 cgi.assign = (&lt;br /&gt;
     &amp;quot;&amp;quot;      =&amp;gt;      &amp;quot;&amp;quot;,&lt;br /&gt;
     &amp;quot;.pl&amp;quot;   =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
     &amp;quot;.cgi&amp;quot;  =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Also add the following to alias.url in mod_cgi.conf so that it looks like&lt;br /&gt;
&lt;br /&gt;
 alias.url = (&lt;br /&gt;
     &amp;quot;/cgi-bin/&amp;quot;            =&amp;gt;      var.basedir + &amp;quot;/cgi-bin/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/api&amp;quot;              =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/api/app/webroot/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/&amp;quot;                 =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Remove the symlink in /var/www/localhost/htdocs (we will be using the alias, not the symlink). &lt;br /&gt;
 unlink /var/www/localhost/htdocs/zm&lt;br /&gt;
&lt;br /&gt;
Start php-fpm&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/php-fpm8 start&lt;br /&gt;
&lt;br /&gt;
Start lighttpd&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
===Zoneminder===&lt;br /&gt;
&lt;br /&gt;
Set the MySQL hostname, username, password.&lt;br /&gt;
&lt;br /&gt;
Change the ZoneMinder user (&amp;lt;code&amp;gt;ZM_WEB_USER&amp;lt;/code&amp;gt;) and group (&amp;lt;code&amp;gt;ZM_WEB_GROUP&amp;lt;/code&amp;gt;) to lighttpd&lt;br /&gt;
&lt;br /&gt;
And set &amp;lt;code&amp;gt;ZM_SERVER_HOST&amp;lt;/code&amp;gt; to your ZoneMinder hostname/ipaddress&lt;br /&gt;
&lt;br /&gt;
 vi /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Which should look like:&lt;br /&gt;
&lt;br /&gt;
 # Username and group that web daemon (httpd/apache) runs as&lt;br /&gt;
 ZM_WEB_USER=lighttpd&lt;br /&gt;
 ZM_WEB_GROUP=lighttpd&lt;br /&gt;
 ZM_PATH_DATA=/usr/share/zoneminder&lt;br /&gt;
&lt;br /&gt;
 # ZoneMinder database type: so far only mysql is supported&lt;br /&gt;
 ZM_DB_TYPE=mysql&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database hostname or ip address&lt;br /&gt;
 ZM_DB_HOST=localhost&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database name&lt;br /&gt;
 ZM_DB_NAME=zm&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database user&lt;br /&gt;
 ZM_DB_USER=zmuser&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database password&lt;br /&gt;
 ZM_DB_PASS=your_zm_password_as_set_in_config&lt;br /&gt;
 &lt;br /&gt;
 # Host of this machine&lt;br /&gt;
 ZM_SERVER_HOST=yourserver&lt;br /&gt;
&lt;br /&gt;
Change ownership of &amp;lt;code&amp;gt;zm.conf&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 chown lighttpd.lighttpd /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Zoneminder will create a cache in &amp;lt;code&amp;gt;/var/cache/zoneminder&amp;lt;/code&amp;gt; which isn&#039;t created by default. Create this directory and allow lighttpd access to it. Note that if you are using a diskless install, you must lbu add /var/cache/zoneminder.&lt;br /&gt;
&lt;br /&gt;
 mkdir /var/cache/zoneminder&lt;br /&gt;
 chown lighttpd.lighttpd /var/cache/zoneminder&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Initialize the ZoneMinder database&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/zoneminder setup&lt;br /&gt;
&lt;br /&gt;
Start ZoneMinder&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/zoneminder start&lt;br /&gt;
&lt;br /&gt;
Profit!&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
To access ZoneMinder, browse to &amp;lt;nowiki&amp;gt;http://yourserver/zm/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To test the API, run&lt;br /&gt;
 curl -X GET  http://yourserver/zm/api/host/getVersion.json&lt;br /&gt;
(This assumes you aren&#039;t using authentication.)&lt;br /&gt;
&lt;br /&gt;
To make it start automatically on boot:&lt;br /&gt;
&lt;br /&gt;
 rc-update add lighttpd default&lt;br /&gt;
 rc-update add mariadb default&lt;br /&gt;
 rc-update add php-fpm8 default&lt;br /&gt;
 rc-update add zoneminder default&lt;br /&gt;
&lt;br /&gt;
== Added notes to work with Nginx ==&lt;br /&gt;
Later to add some notes about running via nginx&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* https://wiki.alpinelinux.org/wiki/Raspberry_Pi_3_-_Browser_Client - Kiosk to watch Streams&lt;br /&gt;
&lt;br /&gt;
[[Category:Software]]&lt;br /&gt;
[[Category:Security]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=22649</id>
		<title>ZoneMinder video camera security and surveillance</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=22649"/>
		<updated>2022-11-04T19:44:07Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* Web Server */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://www.zoneminder.com/ ZoneMinder] usually runs with [[Apache]], but in this short how-to we use [[Lighttpd]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Base Install==&lt;br /&gt;
&lt;br /&gt;
ZoneMinder is found in the community repositories, please enable it by following the instructions [[Repositories#Enabling_the_community_repository|here]]&lt;br /&gt;
&lt;br /&gt;
Then, add the needed packages to our system&lt;br /&gt;
&lt;br /&gt;
 apk add zoneminder mariadb mysql-client lighttpd php8-fpm php8-pdo php8-pdo_mysql&lt;br /&gt;
&lt;br /&gt;
===Database===&lt;br /&gt;
&lt;br /&gt;
Initialize [https://www.mysql.com/ MySQL] database&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/mariadb setup&lt;br /&gt;
&lt;br /&gt;
Start the database&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/mariadb start&lt;br /&gt;
&lt;br /&gt;
Set root password for MySQL as instructed by MySQL setup&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mysqladmin -u root password &#039;your_secure_root_mysql_password&#039;&lt;br /&gt;
&lt;br /&gt;
You can log into MySQL as current root user with&lt;br /&gt;
 mysql&lt;br /&gt;
&lt;br /&gt;
Create a ZoneMinder MySQL database and user&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; create database zm;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; CREATE USER zmuser@localhost IDENTIFIED BY &#039;your_zm_password_as_set_in_config&#039;;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; grant ALL on zm.* to zmuser@localhost;&lt;br /&gt;
&lt;br /&gt;
===Web Server===&lt;br /&gt;
&lt;br /&gt;
We are running &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;, so let&#039;s run &amp;lt;code&amp;gt;php-fpm&amp;lt;/code&amp;gt; as lighttpd user/group&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php8/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
Add this section to the bottom of the file:&lt;br /&gt;
&lt;br /&gt;
 ; Unix user/group of processes&lt;br /&gt;
 ; Note: The user is mandatory. If the group is not set, the default user&#039;s group&lt;br /&gt;
 ;       will be used.&lt;br /&gt;
 ;user = nobody&lt;br /&gt;
 ;group = nobody&lt;br /&gt;
 user = lighttpd&lt;br /&gt;
 group = lighttpd&lt;br /&gt;
&lt;br /&gt;
Enable the php cgi fpm config in &amp;lt;code&amp;gt;lighttpd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
Go down to the server modules section and uncomment &amp;lt;code&amp;gt;mod_alias&amp;lt;/code&amp;gt;, which is needed for the cgi-bin, and &amp;lt;code&amp;gt;mod_rewrite&amp;lt;/code&amp;gt;, for the api. It should look like:&lt;br /&gt;
&lt;br /&gt;
 # {{{ modules&lt;br /&gt;
 # At the very least, mod_access and mod_accesslog should be enabled.&lt;br /&gt;
 # All other modules should only be loaded if necessary.&lt;br /&gt;
 # NOTE: the order of modules is important.&lt;br /&gt;
 server.modules = (&lt;br /&gt;
      &amp;quot;mod_rewrite&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_redirect&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_alias&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_access&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_cml&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_trigger_b4_dl&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_auth&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_status&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_setenv&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_proxy&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_simple_vhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_evhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_userdir&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_deflate&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_ssi&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_usertrack&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_expire&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_secdownload&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_rrdtool&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_webdav&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_accesslog&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
Go down to the includes section, it should look like:&lt;br /&gt;
 # {{{ includes&lt;br /&gt;
 include &amp;quot;mime-types.conf&amp;quot;&lt;br /&gt;
 # uncomment for cgi support&lt;br /&gt;
    include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi support&lt;br /&gt;
 #   include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi fpm support&lt;br /&gt;
    include &amp;quot;mod_fastcgi_fpm.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
In order for video streaming to work in 1.36, you&#039;ll need the following&lt;br /&gt;
added to /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
 server.stream-response-body = 1&lt;br /&gt;
&lt;br /&gt;
In lighttpd.conf for the API, we will want to redirect any api+ requests to cakephp. Thus, add:&lt;br /&gt;
 url.rewrite = (&lt;br /&gt;
       &amp;quot;^/zm/api(.+)$&amp;quot;           =&amp;gt;              &amp;quot;/zm/api/index.php&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Edit lighttpd cgi config and add old style cgi support by adding to cgi.assign&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/mod_cgi.conf&lt;br /&gt;
&lt;br /&gt;
which should look like&lt;br /&gt;
&lt;br /&gt;
 cgi.assign = (&lt;br /&gt;
     &amp;quot;&amp;quot;      =&amp;gt;      &amp;quot;&amp;quot;,&lt;br /&gt;
     &amp;quot;.pl&amp;quot;   =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
     &amp;quot;.cgi&amp;quot;  =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Also add the following to alias.url in mod_cgi.conf so that it looks like&lt;br /&gt;
&lt;br /&gt;
 alias.url = (&lt;br /&gt;
     &amp;quot;/cgi-bin/&amp;quot;            =&amp;gt;      var.basedir + &amp;quot;/cgi-bin/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/api&amp;quot;              =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/api/app/webroot/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/&amp;quot;                 =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Remove the symlink in /var/www/localhost/htdocs (we will be using the alias, not the symlink). &lt;br /&gt;
 unlink /var/www/localhost/htdocs/zm&lt;br /&gt;
&lt;br /&gt;
Start php-fpm&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/php-fpm8 start&lt;br /&gt;
&lt;br /&gt;
Start lighttpd&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
===Zoneminder===&lt;br /&gt;
&lt;br /&gt;
Set the MySQL hostname, username, password.&lt;br /&gt;
&lt;br /&gt;
Change the ZoneMinder user (&amp;lt;code&amp;gt;ZM_WEB_USER&amp;lt;/code&amp;gt;) and group (&amp;lt;code&amp;gt;ZM_WEB_GROUP&amp;lt;/code&amp;gt;) to lighttpd&lt;br /&gt;
&lt;br /&gt;
And set &amp;lt;code&amp;gt;ZM_SERVER_HOST&amp;lt;/code&amp;gt; to your ZoneMinder hostname/ipaddress&lt;br /&gt;
&lt;br /&gt;
 vi /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Which should look like:&lt;br /&gt;
&lt;br /&gt;
 # Username and group that web daemon (httpd/apache) runs as&lt;br /&gt;
 ZM_WEB_USER=lighttpd&lt;br /&gt;
 ZM_WEB_GROUP=lighttpd&lt;br /&gt;
 ZM_PATH_DATA=/usr/share/zoneminder&lt;br /&gt;
&lt;br /&gt;
 # ZoneMinder database type: so far only mysql is supported&lt;br /&gt;
 ZM_DB_TYPE=mysql&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database hostname or ip address&lt;br /&gt;
 ZM_DB_HOST=localhost&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database name&lt;br /&gt;
 ZM_DB_NAME=zm&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database user&lt;br /&gt;
 ZM_DB_USER=zmuser&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database password&lt;br /&gt;
 ZM_DB_PASS=your_zm_password_as_set_in_config&lt;br /&gt;
 &lt;br /&gt;
 # Host of this machine&lt;br /&gt;
 ZM_SERVER_HOST=yourserver&lt;br /&gt;
&lt;br /&gt;
Change ownership of &amp;lt;code&amp;gt;zm.conf&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 chown lighttpd.lighttpd /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Zoneminder will create a cache in &amp;lt;code&amp;gt;/var/cache/zoneminder&amp;lt;/code&amp;gt; which isn&#039;t created by default. Create this directory and allow lighttpd access to it. Note that if you are using a diskless install, you must lbu add /var/cache/zoneminder.&lt;br /&gt;
&lt;br /&gt;
 mkdir /var/cache/zoneminder&lt;br /&gt;
 chown lighttpd.lighttpd /var/cache/zoneminder&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Initialize the ZoneMinder database&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/zoneminder setup&lt;br /&gt;
&lt;br /&gt;
Start ZoneMinder&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/zoneminder start&lt;br /&gt;
&lt;br /&gt;
Profit!&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
To access ZoneMinder, browse to &amp;lt;nowiki&amp;gt;http://yourserver/zm/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To access the API, run&lt;br /&gt;
 curl -X GET  http://yourserver/zm/api/host/getVersion.json&lt;br /&gt;
(This assumes you aren&#039;t using authentication.)&lt;br /&gt;
&lt;br /&gt;
To make it start automatically on boot:&lt;br /&gt;
&lt;br /&gt;
 rc-update add lighttpd default&lt;br /&gt;
 rc-update add mariadb default&lt;br /&gt;
 rc-update add php-fpm8 default&lt;br /&gt;
 rc-update add zoneminder default&lt;br /&gt;
&lt;br /&gt;
== Added notes to work with Nginx ==&lt;br /&gt;
Later to add some notes about running via nginx&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* https://wiki.alpinelinux.org/wiki/Raspberry_Pi_3_-_Browser_Client - Kiosk to watch Streams&lt;br /&gt;
&lt;br /&gt;
[[Category:Software]]&lt;br /&gt;
[[Category:Security]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=22648</id>
		<title>ZoneMinder video camera security and surveillance</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=22648"/>
		<updated>2022-11-04T19:34:27Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* Conclusion */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://www.zoneminder.com/ ZoneMinder] usually runs with [[Apache]], but in this short how-to we use [[Lighttpd]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Base Install==&lt;br /&gt;
&lt;br /&gt;
ZoneMinder is found in the community repositories, please enable it by following the instructions [[Repositories#Enabling_the_community_repository|here]]&lt;br /&gt;
&lt;br /&gt;
Then, add the needed packages to our system&lt;br /&gt;
&lt;br /&gt;
 apk add zoneminder mariadb mysql-client lighttpd php8-fpm php8-pdo php8-pdo_mysql&lt;br /&gt;
&lt;br /&gt;
===Database===&lt;br /&gt;
&lt;br /&gt;
Initialize [https://www.mysql.com/ MySQL] database&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/mariadb setup&lt;br /&gt;
&lt;br /&gt;
Start the database&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/mariadb start&lt;br /&gt;
&lt;br /&gt;
Set root password for MySQL as instructed by MySQL setup&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mysqladmin -u root password &#039;your_secure_root_mysql_password&#039;&lt;br /&gt;
&lt;br /&gt;
You can log into MySQL as current root user with&lt;br /&gt;
 mysql&lt;br /&gt;
&lt;br /&gt;
Create a ZoneMinder MySQL database and user&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; create database zm;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; CREATE USER zmuser@localhost IDENTIFIED BY &#039;your_zm_password_as_set_in_config&#039;;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; grant ALL on zm.* to zmuser@localhost;&lt;br /&gt;
&lt;br /&gt;
===Web Server===&lt;br /&gt;
&lt;br /&gt;
We are running &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;, so let&#039;s run &amp;lt;code&amp;gt;php-fpm&amp;lt;/code&amp;gt; as lighttpd user/group&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php8/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
Add this section to the bottom of the file:&lt;br /&gt;
&lt;br /&gt;
 ; Unix user/group of processes&lt;br /&gt;
 ; Note: The user is mandatory. If the group is not set, the default user&#039;s group&lt;br /&gt;
 ;       will be used.&lt;br /&gt;
 ;user = nobody&lt;br /&gt;
 ;group = nobody&lt;br /&gt;
 user = lighttpd&lt;br /&gt;
 group = lighttpd&lt;br /&gt;
&lt;br /&gt;
Enable the php cgi fpm config in &amp;lt;code&amp;gt;lighttpd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
Go down to the server modules section and uncomment &amp;lt;code&amp;gt;mod_alias&amp;lt;/code&amp;gt;, which is needed for the cgi-bin, and &amp;lt;code&amp;gt;mod_rewrite&amp;lt;/code&amp;gt;, for the api. It should look like:&lt;br /&gt;
&lt;br /&gt;
 # {{{ modules&lt;br /&gt;
 # At the very least, mod_access and mod_accesslog should be enabled.&lt;br /&gt;
 # All other modules should only be loaded if necessary.&lt;br /&gt;
 # NOTE: the order of modules is important.&lt;br /&gt;
 server.modules = (&lt;br /&gt;
      &amp;quot;mod_rewrite&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_redirect&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_alias&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_access&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_cml&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_trigger_b4_dl&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_auth&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_status&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_setenv&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_proxy&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_simple_vhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_evhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_userdir&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_deflate&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_ssi&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_usertrack&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_expire&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_secdownload&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_rrdtool&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_webdav&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_accesslog&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
Go down to the includes section, it should look like:&lt;br /&gt;
 # {{{ includes&lt;br /&gt;
 include &amp;quot;mime-types.conf&amp;quot;&lt;br /&gt;
 # uncomment for cgi support&lt;br /&gt;
    include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi support&lt;br /&gt;
 #   include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi fpm support&lt;br /&gt;
    include &amp;quot;mod_fastcgi_fpm.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
In order for video streaming to work in 1.36, you&#039;ll need the following&lt;br /&gt;
added to /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
 server.stream-response-body = 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Edit lighttpd cgi config and add old style cgi support by adding to cgi.assign&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/mod_cgi.conf&lt;br /&gt;
&lt;br /&gt;
which should look like&lt;br /&gt;
&lt;br /&gt;
 cgi.assign = (&lt;br /&gt;
     &amp;quot;&amp;quot;      =&amp;gt;      &amp;quot;&amp;quot;,&lt;br /&gt;
     &amp;quot;.pl&amp;quot;   =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
     &amp;quot;.cgi&amp;quot;  =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Also add the following to alias.url in mod_cgi.conf so that it looks like&lt;br /&gt;
&lt;br /&gt;
 alias.url = (&lt;br /&gt;
     &amp;quot;/cgi-bin/&amp;quot;            =&amp;gt;      var.basedir + &amp;quot;/cgi-bin/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/api&amp;quot;              =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/api/app/webroot/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/&amp;quot;                 =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Remove the symlink in /var/www/localhost/htdocs (we will be using the alias, not the symlink). &lt;br /&gt;
 unlink /var/www/localhost/htdocs/zm&lt;br /&gt;
&lt;br /&gt;
Start php-fpm&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/php-fpm8 start&lt;br /&gt;
&lt;br /&gt;
Start lighttpd&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
===Zoneminder===&lt;br /&gt;
&lt;br /&gt;
Set the MySQL hostname, username, password.&lt;br /&gt;
&lt;br /&gt;
Change the ZoneMinder user (&amp;lt;code&amp;gt;ZM_WEB_USER&amp;lt;/code&amp;gt;) and group (&amp;lt;code&amp;gt;ZM_WEB_GROUP&amp;lt;/code&amp;gt;) to lighttpd&lt;br /&gt;
&lt;br /&gt;
And set &amp;lt;code&amp;gt;ZM_SERVER_HOST&amp;lt;/code&amp;gt; to your ZoneMinder hostname/ipaddress&lt;br /&gt;
&lt;br /&gt;
 vi /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Which should look like:&lt;br /&gt;
&lt;br /&gt;
 # Username and group that web daemon (httpd/apache) runs as&lt;br /&gt;
 ZM_WEB_USER=lighttpd&lt;br /&gt;
 ZM_WEB_GROUP=lighttpd&lt;br /&gt;
 ZM_PATH_DATA=/usr/share/zoneminder&lt;br /&gt;
&lt;br /&gt;
 # ZoneMinder database type: so far only mysql is supported&lt;br /&gt;
 ZM_DB_TYPE=mysql&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database hostname or ip address&lt;br /&gt;
 ZM_DB_HOST=localhost&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database name&lt;br /&gt;
 ZM_DB_NAME=zm&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database user&lt;br /&gt;
 ZM_DB_USER=zmuser&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database password&lt;br /&gt;
 ZM_DB_PASS=your_zm_password_as_set_in_config&lt;br /&gt;
 &lt;br /&gt;
 # Host of this machine&lt;br /&gt;
 ZM_SERVER_HOST=yourserver&lt;br /&gt;
&lt;br /&gt;
Change ownership of &amp;lt;code&amp;gt;zm.conf&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 chown lighttpd.lighttpd /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Zoneminder will create a cache in &amp;lt;code&amp;gt;/var/cache/zoneminder&amp;lt;/code&amp;gt; which isn&#039;t created by default. Create this directory and allow lighttpd access to it. Note that if you are using a diskless install, you must lbu add /var/cache/zoneminder.&lt;br /&gt;
&lt;br /&gt;
 mkdir /var/cache/zoneminder&lt;br /&gt;
 chown lighttpd.lighttpd /var/cache/zoneminder&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Initialize the ZoneMinder database&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/zoneminder setup&lt;br /&gt;
&lt;br /&gt;
Start ZoneMinder&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/zoneminder start&lt;br /&gt;
&lt;br /&gt;
Profit!&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
To access ZoneMinder, browse to &amp;lt;nowiki&amp;gt;http://yourserver/zm/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To access the API, run&lt;br /&gt;
 curl -X GET  http://yourserver/zm/api/host/getVersion.json&lt;br /&gt;
(This assumes you aren&#039;t using authentication.)&lt;br /&gt;
&lt;br /&gt;
To make it start automatically on boot:&lt;br /&gt;
&lt;br /&gt;
 rc-update add lighttpd default&lt;br /&gt;
 rc-update add mariadb default&lt;br /&gt;
 rc-update add php-fpm8 default&lt;br /&gt;
 rc-update add zoneminder default&lt;br /&gt;
&lt;br /&gt;
== Added notes to work with Nginx ==&lt;br /&gt;
Later to add some notes about running via nginx&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* https://wiki.alpinelinux.org/wiki/Raspberry_Pi_3_-_Browser_Client - Kiosk to watch Streams&lt;br /&gt;
&lt;br /&gt;
[[Category:Software]]&lt;br /&gt;
[[Category:Security]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=22647</id>
		<title>ZoneMinder video camera security and surveillance</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=22647"/>
		<updated>2022-11-04T19:32:59Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: /* Web Server */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://www.zoneminder.com/ ZoneMinder] usually runs with [[Apache]], but in this short how-to we use [[Lighttpd]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Base Install==&lt;br /&gt;
&lt;br /&gt;
ZoneMinder is found in the community repositories, please enable it by following the instructions [[Repositories#Enabling_the_community_repository|here]]&lt;br /&gt;
&lt;br /&gt;
Then, add the needed packages to our system&lt;br /&gt;
&lt;br /&gt;
 apk add zoneminder mariadb mysql-client lighttpd php8-fpm php8-pdo php8-pdo_mysql&lt;br /&gt;
&lt;br /&gt;
===Database===&lt;br /&gt;
&lt;br /&gt;
Initialize [https://www.mysql.com/ MySQL] database&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/mariadb setup&lt;br /&gt;
&lt;br /&gt;
Start the database&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/mariadb start&lt;br /&gt;
&lt;br /&gt;
Set root password for MySQL as instructed by MySQL setup&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mysqladmin -u root password &#039;your_secure_root_mysql_password&#039;&lt;br /&gt;
&lt;br /&gt;
You can log into MySQL as current root user with&lt;br /&gt;
 mysql&lt;br /&gt;
&lt;br /&gt;
Create a ZoneMinder MySQL database and user&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; create database zm;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; CREATE USER zmuser@localhost IDENTIFIED BY &#039;your_zm_password_as_set_in_config&#039;;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; grant ALL on zm.* to zmuser@localhost;&lt;br /&gt;
&lt;br /&gt;
===Web Server===&lt;br /&gt;
&lt;br /&gt;
We are running &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;, so let&#039;s run &amp;lt;code&amp;gt;php-fpm&amp;lt;/code&amp;gt; as lighttpd user/group&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php8/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
Add this section to the bottom of the file:&lt;br /&gt;
&lt;br /&gt;
 ; Unix user/group of processes&lt;br /&gt;
 ; Note: The user is mandatory. If the group is not set, the default user&#039;s group&lt;br /&gt;
 ;       will be used.&lt;br /&gt;
 ;user = nobody&lt;br /&gt;
 ;group = nobody&lt;br /&gt;
 user = lighttpd&lt;br /&gt;
 group = lighttpd&lt;br /&gt;
&lt;br /&gt;
Enable the php cgi fpm config in &amp;lt;code&amp;gt;lighttpd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
Go down to the server modules section and uncomment &amp;lt;code&amp;gt;mod_alias&amp;lt;/code&amp;gt;, which is needed for the cgi-bin, and &amp;lt;code&amp;gt;mod_rewrite&amp;lt;/code&amp;gt;, for the api. It should look like:&lt;br /&gt;
&lt;br /&gt;
 # {{{ modules&lt;br /&gt;
 # At the very least, mod_access and mod_accesslog should be enabled.&lt;br /&gt;
 # All other modules should only be loaded if necessary.&lt;br /&gt;
 # NOTE: the order of modules is important.&lt;br /&gt;
 server.modules = (&lt;br /&gt;
      &amp;quot;mod_rewrite&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_redirect&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_alias&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_access&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_cml&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_trigger_b4_dl&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_auth&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_status&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_setenv&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_proxy&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_simple_vhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_evhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_userdir&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_deflate&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_ssi&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_usertrack&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_expire&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_secdownload&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_rrdtool&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_webdav&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_accesslog&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
Go down to the includes section, it should look like:&lt;br /&gt;
 # {{{ includes&lt;br /&gt;
 include &amp;quot;mime-types.conf&amp;quot;&lt;br /&gt;
 # uncomment for cgi support&lt;br /&gt;
    include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi support&lt;br /&gt;
 #   include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi fpm support&lt;br /&gt;
    include &amp;quot;mod_fastcgi_fpm.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
In order for video streaming to work in 1.36, you&#039;ll need the following&lt;br /&gt;
added to /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
 server.stream-response-body = 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Edit lighttpd cgi config and add old style cgi support by adding to cgi.assign&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/mod_cgi.conf&lt;br /&gt;
&lt;br /&gt;
which should look like&lt;br /&gt;
&lt;br /&gt;
 cgi.assign = (&lt;br /&gt;
     &amp;quot;&amp;quot;      =&amp;gt;      &amp;quot;&amp;quot;,&lt;br /&gt;
     &amp;quot;.pl&amp;quot;   =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
     &amp;quot;.cgi&amp;quot;  =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Also add the following to alias.url in mod_cgi.conf so that it looks like&lt;br /&gt;
&lt;br /&gt;
 alias.url = (&lt;br /&gt;
     &amp;quot;/cgi-bin/&amp;quot;            =&amp;gt;      var.basedir + &amp;quot;/cgi-bin/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/api&amp;quot;              =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/api/app/webroot/&amp;quot;,&lt;br /&gt;
     &amp;quot;/zm/&amp;quot;                 =&amp;gt;      &amp;quot;/usr/share/webapps/zoneminder/htdocs/&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Remove the symlink in /var/www/localhost/htdocs (we will be using the alias, not the symlink). &lt;br /&gt;
 unlink /var/www/localhost/htdocs/zm&lt;br /&gt;
&lt;br /&gt;
Start php-fpm&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/php-fpm8 start&lt;br /&gt;
&lt;br /&gt;
Start lighttpd&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
===Zoneminder===&lt;br /&gt;
&lt;br /&gt;
Set the MySQL hostname, username, password.&lt;br /&gt;
&lt;br /&gt;
Change the ZoneMinder user (&amp;lt;code&amp;gt;ZM_WEB_USER&amp;lt;/code&amp;gt;) and group (&amp;lt;code&amp;gt;ZM_WEB_GROUP&amp;lt;/code&amp;gt;) to lighttpd&lt;br /&gt;
&lt;br /&gt;
And set &amp;lt;code&amp;gt;ZM_SERVER_HOST&amp;lt;/code&amp;gt; to your ZoneMinder hostname/ipaddress&lt;br /&gt;
&lt;br /&gt;
 vi /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Which should look like:&lt;br /&gt;
&lt;br /&gt;
 # Username and group that web daemon (httpd/apache) runs as&lt;br /&gt;
 ZM_WEB_USER=lighttpd&lt;br /&gt;
 ZM_WEB_GROUP=lighttpd&lt;br /&gt;
 ZM_PATH_DATA=/usr/share/zoneminder&lt;br /&gt;
&lt;br /&gt;
 # ZoneMinder database type: so far only mysql is supported&lt;br /&gt;
 ZM_DB_TYPE=mysql&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database hostname or ip address&lt;br /&gt;
 ZM_DB_HOST=localhost&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database name&lt;br /&gt;
 ZM_DB_NAME=zm&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database user&lt;br /&gt;
 ZM_DB_USER=zmuser&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database password&lt;br /&gt;
 ZM_DB_PASS=your_zm_password_as_set_in_config&lt;br /&gt;
 &lt;br /&gt;
 # Host of this machine&lt;br /&gt;
 ZM_SERVER_HOST=yourserver&lt;br /&gt;
&lt;br /&gt;
Change ownership of &amp;lt;code&amp;gt;zm.conf&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 chown lighttpd.lighttpd /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Zoneminder will create a cache in &amp;lt;code&amp;gt;/var/cache/zoneminder&amp;lt;/code&amp;gt; which isn&#039;t created by default. Create this directory and allow lighttpd access to it. Note that if you are using a diskless install, you must lbu add /var/cache/zoneminder.&lt;br /&gt;
&lt;br /&gt;
 mkdir /var/cache/zoneminder&lt;br /&gt;
 chown lighttpd.lighttpd /var/cache/zoneminder&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Initialize the ZoneMinder database&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/zoneminder setup&lt;br /&gt;
&lt;br /&gt;
Start ZoneMinder&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/zoneminder start&lt;br /&gt;
&lt;br /&gt;
Profit!&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
To access ZoneMinder, browse to &amp;lt;nowiki&amp;gt;http://yourserver/zm/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make it start automatically on boot:&lt;br /&gt;
&lt;br /&gt;
 rc-update add lighttpd default&lt;br /&gt;
 rc-update add mariadb default&lt;br /&gt;
 rc-update add php-fpm8 default&lt;br /&gt;
 rc-update add zoneminder default&lt;br /&gt;
&lt;br /&gt;
== Added notes to work with Nginx ==&lt;br /&gt;
Later to add some notes about running via nginx&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* https://wiki.alpinelinux.org/wiki/Raspberry_Pi_3_-_Browser_Client - Kiosk to watch Streams&lt;br /&gt;
&lt;br /&gt;
[[Category:Software]]&lt;br /&gt;
[[Category:Security]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=22646</id>
		<title>ZoneMinder video camera security and surveillance</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=22646"/>
		<updated>2022-11-04T17:47:35Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://www.zoneminder.com/ ZoneMinder] usually runs with [[Apache]], but in this short how-to we use [[Lighttpd]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Base Install==&lt;br /&gt;
&lt;br /&gt;
ZoneMinder is found in the community repositories, please enable it by following the instructions [[Repositories#Enabling_the_community_repository|here]]&lt;br /&gt;
&lt;br /&gt;
Then, add the needed packages to our system&lt;br /&gt;
&lt;br /&gt;
 apk add zoneminder mariadb mysql-client lighttpd php8-fpm php8-pdo php8-pdo_mysql&lt;br /&gt;
&lt;br /&gt;
===Database===&lt;br /&gt;
&lt;br /&gt;
Initialize [https://www.mysql.com/ MySQL] database&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/mariadb setup&lt;br /&gt;
&lt;br /&gt;
Start the database&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/mariadb start&lt;br /&gt;
&lt;br /&gt;
Set root password for MySQL as instructed by MySQL setup&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mysqladmin -u root password &#039;your_secure_root_mysql_password&#039;&lt;br /&gt;
&lt;br /&gt;
You can log into MySQL as current root user with&lt;br /&gt;
 mysql&lt;br /&gt;
&lt;br /&gt;
Create a ZoneMinder MySQL database and user&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; create database zm;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; CREATE USER zmuser@localhost IDENTIFIED BY &#039;your_zm_password_as_set_in_config&#039;;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; grant ALL on zm.* to zmuser@localhost;&lt;br /&gt;
&lt;br /&gt;
===Web Server===&lt;br /&gt;
&lt;br /&gt;
We are running &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;, so let&#039;s run &amp;lt;code&amp;gt;php-fpm&amp;lt;/code&amp;gt; as lighttpd user/group&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php8/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
Add this section to the bottom of the file:&lt;br /&gt;
&lt;br /&gt;
 ; Unix user/group of processes&lt;br /&gt;
 ; Note: The user is mandatory. If the group is not set, the default user&#039;s group&lt;br /&gt;
 ;       will be used.&lt;br /&gt;
 ;user = nobody&lt;br /&gt;
 ;group = nobody&lt;br /&gt;
 user = lighttpd&lt;br /&gt;
 group = lighttpd&lt;br /&gt;
&lt;br /&gt;
Enable the php cgi fpm config in &amp;lt;code&amp;gt;lighttpd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
Go down to the server modules section and uncomment &amp;lt;code&amp;gt;mod_alias&amp;lt;/code&amp;gt;, which is needed for the cgi-bin. It should look like:&lt;br /&gt;
&lt;br /&gt;
 # {{{ modules&lt;br /&gt;
 # At the very least, mod_access and mod_accesslog should be enabled.&lt;br /&gt;
 # All other modules should only be loaded if necessary.&lt;br /&gt;
 # NOTE: the order of modules is important.&lt;br /&gt;
 server.modules = (&lt;br /&gt;
 #    &amp;quot;mod_rewrite&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_redirect&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_alias&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_access&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_cml&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_trigger_b4_dl&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_auth&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_status&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_setenv&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_proxy&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_simple_vhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_evhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_userdir&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_deflate&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_ssi&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_usertrack&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_expire&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_secdownload&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_rrdtool&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_webdav&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_accesslog&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
Go down to the includes section, it should look like:&lt;br /&gt;
 # {{{ includes&lt;br /&gt;
 include &amp;quot;mime-types.conf&amp;quot;&lt;br /&gt;
 # uncomment for cgi support&lt;br /&gt;
    include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi support&lt;br /&gt;
 #   include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi fpm support&lt;br /&gt;
    include &amp;quot;mod_fastcgi_fpm.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
In order for video streaming to work in 1.36, you&#039;ll need the following config&lt;br /&gt;
added to /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
 server.stream-response-body = 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Edit lighttpd cgi config and add old style cgi support by adding to cgi.assign&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/mod_cgi.conf&lt;br /&gt;
&lt;br /&gt;
which should look like&lt;br /&gt;
&lt;br /&gt;
 cgi.assign = (&lt;br /&gt;
     &amp;quot;&amp;quot;      =&amp;gt;      &amp;quot;&amp;quot;,&lt;br /&gt;
     &amp;quot;.pl&amp;quot;   =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
     &amp;quot;.cgi&amp;quot;  =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Start php-fpm&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/php-fpm8 start&lt;br /&gt;
&lt;br /&gt;
Start lighttpd&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
===Zoneminder===&lt;br /&gt;
&lt;br /&gt;
Set the MySQL hostname, username, password.&lt;br /&gt;
&lt;br /&gt;
Change the ZoneMinder user (&amp;lt;code&amp;gt;ZM_WEB_USER&amp;lt;/code&amp;gt;) and group (&amp;lt;code&amp;gt;ZM_WEB_GROUP&amp;lt;/code&amp;gt;) to lighttpd&lt;br /&gt;
&lt;br /&gt;
And set &amp;lt;code&amp;gt;ZM_SERVER_HOST&amp;lt;/code&amp;gt; to your ZoneMinder hostname/ipaddress&lt;br /&gt;
&lt;br /&gt;
 vi /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Which should look like:&lt;br /&gt;
&lt;br /&gt;
 # Username and group that web daemon (httpd/apache) runs as&lt;br /&gt;
 ZM_WEB_USER=lighttpd&lt;br /&gt;
 ZM_WEB_GROUP=lighttpd&lt;br /&gt;
 ZM_PATH_DATA=/usr/share/zoneminder&lt;br /&gt;
&lt;br /&gt;
 # ZoneMinder database type: so far only mysql is supported&lt;br /&gt;
 ZM_DB_TYPE=mysql&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database hostname or ip address&lt;br /&gt;
 ZM_DB_HOST=localhost&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database name&lt;br /&gt;
 ZM_DB_NAME=zm&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database user&lt;br /&gt;
 ZM_DB_USER=zmuser&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database password&lt;br /&gt;
 ZM_DB_PASS=your_zm_password_as_set_in_config&lt;br /&gt;
 &lt;br /&gt;
 # Host of this machine&lt;br /&gt;
 ZM_SERVER_HOST=yourserver&lt;br /&gt;
&lt;br /&gt;
Change ownership of &amp;lt;code&amp;gt;zm.conf&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 chown lighttpd.lighttpd /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Zoneminder will create a cache in &amp;lt;code&amp;gt;/var/cache/zoneminder&amp;lt;/code&amp;gt; which isn&#039;t created by default. Create this directory and allow lighttpd access to it. Note that if you are using a diskless install, you must lbu add /var/cache/zoneminder.&lt;br /&gt;
&lt;br /&gt;
 mkdir /var/cache/zoneminder&lt;br /&gt;
 chown lighttpd.lighttpd /var/cache/zoneminder&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Initialize the ZoneMinder database&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/zoneminder setup&lt;br /&gt;
&lt;br /&gt;
Start ZoneMinder&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/zoneminder start&lt;br /&gt;
&lt;br /&gt;
Profit!&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
To access ZoneMinder, browse to &amp;lt;nowiki&amp;gt;http://yourserver/zm/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make it start automatically on boot:&lt;br /&gt;
&lt;br /&gt;
 rc-update add lighttpd default&lt;br /&gt;
 rc-update add mariadb default&lt;br /&gt;
 rc-update add php-fpm8 default&lt;br /&gt;
 rc-update add zoneminder default&lt;br /&gt;
&lt;br /&gt;
== Added notes to work with Nginx ==&lt;br /&gt;
Later to add some notes about running via nginx&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* https://wiki.alpinelinux.org/wiki/Raspberry_Pi_3_-_Browser_Client - Kiosk to watch Streams&lt;br /&gt;
&lt;br /&gt;
[[Category:Software]]&lt;br /&gt;
[[Category:Security]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=22645</id>
		<title>ZoneMinder video camera security and surveillance</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=ZoneMinder_video_camera_security_and_surveillance&amp;diff=22645"/>
		<updated>2022-11-04T17:46:11Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://www.zoneminder.com/ ZoneMinder] usually runs with [[Apache]], but in this short how-to we use [[Lighttpd]].&lt;br /&gt;
&lt;br /&gt;
ZoneMinder is found in the community repositories, please enable it by following the instructions [[Repositories#Enabling_the_community_repository|here]]&lt;br /&gt;
&lt;br /&gt;
==Base Install==&lt;br /&gt;
&lt;br /&gt;
First, add the needed packages to our system&lt;br /&gt;
&lt;br /&gt;
 apk add zoneminder mariadb mysql-client lighttpd php8-fpm php8-pdo php8-pdo_mysql&lt;br /&gt;
&lt;br /&gt;
===Database===&lt;br /&gt;
&lt;br /&gt;
Initialize [https://www.mysql.com/ MySQL] database&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/mariadb setup&lt;br /&gt;
&lt;br /&gt;
Start the database&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/mariadb start&lt;br /&gt;
&lt;br /&gt;
Set root password for MySQL as instructed by MySQL setup&lt;br /&gt;
&lt;br /&gt;
 /usr/bin/mysqladmin -u root password &#039;your_secure_root_mysql_password&#039;&lt;br /&gt;
&lt;br /&gt;
You can log into MySQL as current root user with&lt;br /&gt;
 mysql&lt;br /&gt;
&lt;br /&gt;
Create a ZoneMinder MySQL database and user&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; create database zm;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; CREATE USER zmuser@localhost IDENTIFIED BY &#039;your_zm_password_as_set_in_config&#039;;&lt;br /&gt;
&lt;br /&gt;
 mysql&amp;gt; grant ALL on zm.* to zmuser@localhost;&lt;br /&gt;
&lt;br /&gt;
===Web Server===&lt;br /&gt;
&lt;br /&gt;
We are running &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;, so let&#039;s run &amp;lt;code&amp;gt;php-fpm&amp;lt;/code&amp;gt; as lighttpd user/group&lt;br /&gt;
&lt;br /&gt;
 vi /etc/php8/php-fpm.conf&lt;br /&gt;
&lt;br /&gt;
Add this section to the bottom of the file:&lt;br /&gt;
&lt;br /&gt;
 ; Unix user/group of processes&lt;br /&gt;
 ; Note: The user is mandatory. If the group is not set, the default user&#039;s group&lt;br /&gt;
 ;       will be used.&lt;br /&gt;
 ;user = nobody&lt;br /&gt;
 ;group = nobody&lt;br /&gt;
 user = lighttpd&lt;br /&gt;
 group = lighttpd&lt;br /&gt;
&lt;br /&gt;
Enable the php cgi fpm config in &amp;lt;code&amp;gt;lighttpd.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/lighttpd.conf&lt;br /&gt;
&lt;br /&gt;
Go down to the server modules section and uncomment &amp;lt;code&amp;gt;mod_alias&amp;lt;/code&amp;gt;, which is needed for the cgi-bin. It should look like:&lt;br /&gt;
&lt;br /&gt;
 # {{{ modules&lt;br /&gt;
 # At the very least, mod_access and mod_accesslog should be enabled.&lt;br /&gt;
 # All other modules should only be loaded if necessary.&lt;br /&gt;
 # NOTE: the order of modules is important.&lt;br /&gt;
 server.modules = (&lt;br /&gt;
 #    &amp;quot;mod_rewrite&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_redirect&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_alias&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_access&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_cml&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_trigger_b4_dl&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_auth&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_status&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_setenv&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_proxy&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_simple_vhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_evhost&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_userdir&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_deflate&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_ssi&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_usertrack&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_expire&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_secdownload&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_rrdtool&amp;quot;,&lt;br /&gt;
 #    &amp;quot;mod_webdav&amp;quot;,&lt;br /&gt;
      &amp;quot;mod_accesslog&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
Go down to the includes section, it should look like:&lt;br /&gt;
 # {{{ includes&lt;br /&gt;
 include &amp;quot;mime-types.conf&amp;quot;&lt;br /&gt;
 # uncomment for cgi support&lt;br /&gt;
    include &amp;quot;mod_cgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi support&lt;br /&gt;
 #   include &amp;quot;mod_fastcgi.conf&amp;quot;&lt;br /&gt;
 # uncomment for php/fastcgi fpm support&lt;br /&gt;
    include &amp;quot;mod_fastcgi_fpm.conf&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 # }}}&lt;br /&gt;
&lt;br /&gt;
In order for video streaming to work in 1.36, you&#039;ll need the following config&lt;br /&gt;
added to /etc/lighttpd/lighttpd.conf:&lt;br /&gt;
 server.stream-response-body = 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Edit lighttpd cgi config and add old style cgi support by adding to cgi.assign&lt;br /&gt;
&lt;br /&gt;
 vi /etc/lighttpd/mod_cgi.conf&lt;br /&gt;
&lt;br /&gt;
which should look like&lt;br /&gt;
&lt;br /&gt;
 cgi.assign = (&lt;br /&gt;
     &amp;quot;&amp;quot;      =&amp;gt;      &amp;quot;&amp;quot;,&lt;br /&gt;
     &amp;quot;.pl&amp;quot;   =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;,&lt;br /&gt;
     &amp;quot;.cgi&amp;quot;  =&amp;gt;      &amp;quot;/usr/bin/perl&amp;quot;&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Start php-fpm&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/php-fpm8 start&lt;br /&gt;
&lt;br /&gt;
Start lighttpd&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/lighttpd start&lt;br /&gt;
&lt;br /&gt;
===Zoneminder===&lt;br /&gt;
&lt;br /&gt;
Set the MySQL hostname, username, password.&lt;br /&gt;
&lt;br /&gt;
Change the ZoneMinder user (&amp;lt;code&amp;gt;ZM_WEB_USER&amp;lt;/code&amp;gt;) and group (&amp;lt;code&amp;gt;ZM_WEB_GROUP&amp;lt;/code&amp;gt;) to lighttpd&lt;br /&gt;
&lt;br /&gt;
And set &amp;lt;code&amp;gt;ZM_SERVER_HOST&amp;lt;/code&amp;gt; to your ZoneMinder hostname/ipaddress&lt;br /&gt;
&lt;br /&gt;
 vi /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Which should look like:&lt;br /&gt;
&lt;br /&gt;
 # Username and group that web daemon (httpd/apache) runs as&lt;br /&gt;
 ZM_WEB_USER=lighttpd&lt;br /&gt;
 ZM_WEB_GROUP=lighttpd&lt;br /&gt;
 ZM_PATH_DATA=/usr/share/zoneminder&lt;br /&gt;
&lt;br /&gt;
 # ZoneMinder database type: so far only mysql is supported&lt;br /&gt;
 ZM_DB_TYPE=mysql&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database hostname or ip address&lt;br /&gt;
 ZM_DB_HOST=localhost&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database name&lt;br /&gt;
 ZM_DB_NAME=zm&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database user&lt;br /&gt;
 ZM_DB_USER=zmuser&lt;br /&gt;
 &lt;br /&gt;
 # ZoneMinder database password&lt;br /&gt;
 ZM_DB_PASS=your_zm_password_as_set_in_config&lt;br /&gt;
 &lt;br /&gt;
 # Host of this machine&lt;br /&gt;
 ZM_SERVER_HOST=yourserver&lt;br /&gt;
&lt;br /&gt;
Change ownership of &amp;lt;code&amp;gt;zm.conf&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;lighttpd&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 chown lighttpd.lighttpd /etc/zm/zm.conf&lt;br /&gt;
&lt;br /&gt;
Zoneminder will create a cache in &amp;lt;code&amp;gt;/var/cache/zoneminder&amp;lt;/code&amp;gt; which isn&#039;t created by default. Create this directory and allow lighttpd access to it. Note that if you are using a diskless install, you must lbu add /var/cache/zoneminder.&lt;br /&gt;
&lt;br /&gt;
 mkdir /var/cache/zoneminder&lt;br /&gt;
 chown lighttpd.lighttpd /var/cache/zoneminder&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Initialize the ZoneMinder database&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/zoneminder setup&lt;br /&gt;
&lt;br /&gt;
Start ZoneMinder&lt;br /&gt;
&lt;br /&gt;
 /etc/init.d/zoneminder start&lt;br /&gt;
&lt;br /&gt;
Profit!&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
To access ZoneMinder, browse to &amp;lt;nowiki&amp;gt;http://yourserver/zm/&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make it start automatically on boot:&lt;br /&gt;
&lt;br /&gt;
 rc-update add lighttpd default&lt;br /&gt;
 rc-update add mariadb default&lt;br /&gt;
 rc-update add php-fpm8 default&lt;br /&gt;
 rc-update add zoneminder default&lt;br /&gt;
&lt;br /&gt;
== Added notes to work with Nginx ==&lt;br /&gt;
Later to add some notes about running via nginx&lt;br /&gt;
&lt;br /&gt;
==Related Links==&lt;br /&gt;
* https://wiki.alpinelinux.org/wiki/Raspberry_Pi_3_-_Browser_Client - Kiosk to watch Streams&lt;br /&gt;
&lt;br /&gt;
[[Category:Software]]&lt;br /&gt;
[[Category:Security]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=User_talk:Alpineuser&amp;diff=21514</id>
		<title>User talk:Alpineuser</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=User_talk:Alpineuser&amp;diff=21514"/>
		<updated>2022-01-27T16:11:59Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: CC-BY-SA license clause&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I, alpineuser, hereby re-license my contributions to the Alpine Linux&lt;br /&gt;
wiki under the username alpineuser under the terms of the&lt;br /&gt;
CC-BY-SA license.&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Talk:Intrusion_Detection_using_Snort&amp;diff=20708</id>
		<title>Talk:Intrusion Detection using Snort</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Talk:Intrusion_Detection_using_Snort&amp;diff=20708"/>
		<updated>2021-12-08T06:17:44Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: Created page with &amp;quot;Reverted apparent vandalism by Guest09248. Baby with the bathwater, a user appears to be actively deleting pages without thorough testing or updating of guides. The proper way...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Reverted apparent vandalism by Guest09248. Baby with the bathwater, a user appears to be actively deleting pages without thorough testing or updating of guides. The proper way to edit guides is to evaluate and install each program, updating relevant info where necessary, not blanket deletion of all content.[[User:Alpineuser|Alpineuser]] ([[User talk:Alpineuser|talk]]) 06:17, 8 December 2021 (UTC)&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Intrusion_Detection_using_Snort&amp;diff=20707</id>
		<title>Intrusion Detection using Snort</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Intrusion_Detection_using_Snort&amp;diff=20707"/>
		<updated>2021-12-08T06:14:30Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: Undo revision 20519 by Guest09248 (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Draft}}&lt;br /&gt;
&lt;br /&gt;
This guide will set up (list subject to change):&lt;br /&gt;
* Snort&lt;br /&gt;
* Barnyard (maybe)&lt;br /&gt;
* BASE&lt;br /&gt;
&lt;br /&gt;
This guide will assume:&lt;br /&gt;
* You have a knowledge of your network setup (at least know which subnets exist).&lt;br /&gt;
* You have Alpine 2.0.2 installed and working with networking setup.&lt;br /&gt;
* You have had at least three cups of coffee this morning. And not decaf.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Get Development Packages ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Install Alpine and Pre-packaged components&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{Cmd|apk add alpine-sdk mysql-dev php-mysql lighttpd php-xml php-pear libpcap-dev php-gd pcre-dev wireshark tcpdump tcpflow cvs bison flex}}&lt;br /&gt;
&lt;br /&gt;
== Download Non-Packaged Applications ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Download the following packages &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For the purpose of this document we will assume you download these files to /usr/src.&lt;br /&gt;
&lt;br /&gt;
:Download snort from www.snort.org. We used version 2.8.6.1 in this document.&lt;br /&gt;
:Download the snort rules from http://www.snort.org/snort-rules/&lt;br /&gt;
:Download BASE from http://sourceforge.net/projects/secureideas/files/BASE/base-1.4.5/base-1.4.5.tar.gz/download&lt;br /&gt;
:Download adodb5 from http://sourceforge.net/projects/adodb/files/adodb-php5-only/adodb-511-for-php5/adodb511.zip/download&lt;br /&gt;
&lt;br /&gt;
== Compile Snort ==&lt;br /&gt;
&lt;br /&gt;
Uncompress snort with something like: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|tar -zxvf snort-2.8.6.1.tar.gz}}&lt;br /&gt;
&lt;br /&gt;
Then do the following:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|cd snort-2.8.6.1&lt;br /&gt;
./configure -enable-dynamicplugin --with-mysql&lt;br /&gt;
make&lt;br /&gt;
make install}}&lt;br /&gt;
&lt;br /&gt;
== Configure Snort and Ruleset ==&lt;br /&gt;
&lt;br /&gt;
{{Cmd|mkdir /etc/snort&lt;br /&gt;
cd /etc/snort&lt;br /&gt;
cp /usr/src/snort-2.8.6.1/etc/* .&lt;br /&gt;
mv /usr/src/snortrules-snapshot-2861.tar.gz /etc/snort/.&lt;br /&gt;
tar -zxvf /usr/src/snortrules-snapshot-2861.tar.gz}}&lt;br /&gt;
&lt;br /&gt;
Now edit the snort.conf file:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|vi snort.conf}}&lt;br /&gt;
&lt;br /&gt;
and change the following:&lt;br /&gt;
&lt;br /&gt;
* Change &amp;quot;var HOME_NET any&amp;quot; to &amp;quot;var HOME_NET X.X.X.X/X&amp;quot; (fill in the subnet with your trusted network)&lt;br /&gt;
* Change &amp;quot;var EXTERNAL_NET any&amp;quot; to &amp;quot;var EXTERNAL_NET !$HOME_NET&amp;quot; (this is stating everything except HOME_NET is external)&lt;br /&gt;
* Change &amp;quot;var RULE_PATH ../rules&amp;quot; to &amp;quot;var RULE_PATH /etc/snort/rules&amp;quot;&lt;br /&gt;
* Change &amp;quot;var SO_RULE_PATH ../so_rules&amp;quot; to &amp;quot;var SO_RULE_PATH /etc/snort/so_rules&amp;quot;&lt;br /&gt;
* Change &amp;quot;var PREPROC_RULE_PATH ../preproc_rules&amp;quot; to &amp;quot;var PREPROC_RULE_PATH /etc/snort/preproc_rules&amp;quot;&lt;br /&gt;
* Comment out the line that says &amp;quot;dynamicdetection directory /usr/local/lib/snort_dynamicrules&amp;quot; (by placing a &amp;quot;#&amp;quot; in front of the line)&lt;br /&gt;
* Scroll down the list to the section with &amp;quot;# output database: log, ...&amp;quot; and remove the &amp;quot;#&amp;quot; from in front of this line.&lt;br /&gt;
* Edit this line to look like this:&lt;br /&gt;
:output database: log, mysql, user=root password=yoursecretpassword dbname=snort host=localhost&lt;br /&gt;
* Make note of the username, password, and dbname. You will need this information when we set up mysql.&lt;br /&gt;
* Find this line (line 194 in current version)&lt;br /&gt;
::preprocessor http_inspect: global iis_unicode_map unicode.map 1252 compress_depth 20480 decompress_depth 20480&lt;br /&gt;
:and remove from &amp;quot;compress_depth&amp;quot; to the end of the line. When done, the line will read:&lt;br /&gt;
::preprocessor http_inspect: global iis_unicode_map unicode.map 1252&lt;br /&gt;
* Find this line (line 207 in current version)&lt;br /&gt;
::inspect_gzip \&lt;br /&gt;
:and remove it.&lt;br /&gt;
* Save and quit.&lt;br /&gt;
&lt;br /&gt;
== Start and Setup MySQL ==&lt;br /&gt;
&lt;br /&gt;
(Need to add detail here on starting up MySQL for the first time)&lt;br /&gt;
&lt;br /&gt;
{{Cmd|&amp;lt;nowiki&amp;gt;/usr/bin/mysql_install_db --user=mysql&lt;br /&gt;
rc-update add mysql&lt;br /&gt;
/etc/init.d/mysql start&lt;br /&gt;
/usr/bin/mysqladmin -u root password &#039;password&#039;  (set password to the same password you specified in the snort.conf file)&lt;br /&gt;
mysql -u root -p&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Once in mysql, type the following commands:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|mysql&amp;gt; create database snort;&lt;br /&gt;
mysql&amp;gt; exit}}&lt;br /&gt;
&lt;br /&gt;
Now create the database schema:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|mysql -D snort -u root -p &amp;lt; /usr/src/snort-2.8.6.1/schemas/create_mysql}}&lt;br /&gt;
&lt;br /&gt;
== Configure PHP and PEAR ==&lt;br /&gt;
&lt;br /&gt;
Edit /etc/php/php.ini and add the following under &amp;quot;Dynamic Extensions&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 extension=mysql.so&lt;br /&gt;
 extension=gd.so&lt;br /&gt;
&lt;br /&gt;
Save and exit. From the command line, type the following:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|pear install Image_Color&lt;br /&gt;
pear install Image_Canvas-alpha&lt;br /&gt;
pear install Image_Graph-alpha&lt;br /&gt;
pear install mail&lt;br /&gt;
pear install mail_mime}}&lt;br /&gt;
&lt;br /&gt;
== Start Apache or lighttpd ==&lt;br /&gt;
&lt;br /&gt;
Need to decide which of these to use in production.&lt;br /&gt;
&lt;br /&gt;
== Setup BASE ==&lt;br /&gt;
&lt;br /&gt;
^{{Cmd|mv /usr/src/adodb5 /var/www/localhost/htdocs/.&lt;br /&gt;
mv /usr/src/base-1.4.5/* /var/www/localhost/htdocs/.}}&lt;br /&gt;
&lt;br /&gt;
Now, open your web browser and navigate to http://X.X.X.X/setup (where x.x.x.x is your server&#039;s IP address)&lt;br /&gt;
&lt;br /&gt;
:Click continue on the first page.&lt;br /&gt;
:Step 1 of 5: Enter the path to ADODB.&lt;br /&gt;
::This is /var/www/localhost/htdocs/adodb5.&lt;br /&gt;
:Step 2 of 5:&lt;br /&gt;
::Database type = MySQL, Database name = snort, Database Host = localhost, Database username = root, Database Password = YOUR_PASSWORD&lt;br /&gt;
:Step 3 of 5: If you want to use authentication enter a username and password here.&lt;br /&gt;
:Step 4 of 5: Click on Create BASE AG.&lt;br /&gt;
:Step 5 of 5: one step 4 is done at the bottom click on Now continue to step 5.&lt;br /&gt;
:Copy the text on the screen, and then paste into a new file named /var/www/localhost/htdocs/base_conf.php. Save that file.&lt;br /&gt;
&lt;br /&gt;
== Configure Barnyard ==&lt;br /&gt;
&lt;br /&gt;
To improve performance.&lt;br /&gt;
&lt;br /&gt;
[[Category:Server]]&lt;br /&gt;
[[Category:Monitoring]]&lt;br /&gt;
[[Category:PHP]]&lt;br /&gt;
[[Category:SQL]]&lt;br /&gt;
[[Category:Security]]&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Talk:Flatpak&amp;diff=20706</id>
		<title>Talk:Flatpak</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Talk:Flatpak&amp;diff=20706"/>
		<updated>2021-12-08T06:09:34Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Guest09248, why did you delete the link to flatpak&#039;s page on alpine:* [https://flatpak.org/setup/Alpine/ Alpine Quick Setup. Follow these simple steps to start using Flatpak]&lt;br /&gt;
And other links. This information is valid alpine specific info and your edits appear to be vandalism.&lt;br /&gt;
[[User:Alpineuser|Alpineuser]] ([[User talk:Alpineuser|talk]]) 06:08, 8 December 2021 (UTC)&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Talk:Flatpak&amp;diff=20705</id>
		<title>Talk:Flatpak</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Talk:Flatpak&amp;diff=20705"/>
		<updated>2021-12-08T06:08:23Z</updated>

		<summary type="html">&lt;p&gt;Alpineuser: Created page with &amp;quot;Guest, why did you delete:* [https://flatpak.org/setup/Alpine/ Alpine Quick Setup. Follow these simple steps to start using Flatpak] And other links. This information is valid...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Guest, why did you delete:* [https://flatpak.org/setup/Alpine/ Alpine Quick Setup. Follow these simple steps to start using Flatpak]&lt;br /&gt;
And other links. This information is valid alpine specific info and your edits appear to be vandalism.&lt;br /&gt;
[[User:Alpineuser|Alpineuser]] ([[User talk:Alpineuser|talk]]) 06:08, 8 December 2021 (UTC)&lt;/div&gt;</summary>
		<author><name>Alpineuser</name></author>
	</entry>
</feed>