* Quick start
You can try out a QEMU kiosk, quickly. Just run:
#+BEGIN_SRC sh
$ nix-env -iA cachix -f https://cachix.org/api/v1/install
$ cachix use nixiosk
$ ./qemu.sh nixiosk.json.sample
#+END_SRC
This sets up the Nixiosk cachix and then downloads QEMU as well as the
image defined in nixiosk.json.sample. It then runs that image which
boots up NixOS and a web browser window.
* How it works
:PROPERTIES:
:CUSTOM_ID: how-it-works
:END:
This is a Kiosk builder system. It can be used to make a system that
single graphical program. This is useful for making systems that do
video conferencing, digital signage, informational displays, Internet
kiosks, and more. Right now, only Raspberry Pi 0-4 are supported.
** Configuration
To make things simple, it just reads from an ad-hoc JSON file that
describe the hardware plus some other customizations. It looks like
this:
#+BEGIN_SRC json
{
"hostName": "nixiosk",
"hardware": "raspberryPi4",
"authorizedKeys": [],
"program": {
"package": "cog",
"executable": "/bin/cog",
"args": ["https://en.wikipedia.org/"]
},
"networks": {
"my-router": "0000000000000000000000000000000000000000000000000000000000000000",
},
"locale": {
"timeZone": "America/New_York",
"regDom": "US",
"lang": "en_US.UTF-8"
},
"localSystem": {
"system": "x86_64-linux",
"sshUser": "me",
"hostName": "my-laptop-host",
}
}
#+END_SRC
Here’s a basic idea of what each of these fields do:
- hostName: Name of the host to use. If mDNS is configured on your
network, this can be used to identify the IP address of the device
via “<hostName>.local”.
- hardware: A string describing what hardware we are using. Valid
values currently are “raspberryPi0”, “raspberryPi1”, “raspberryPi2”,
“raspberryPi3”, “raspberryPi4”.
- authorizedKeys: A list of SSH public keys that are authorized to
make changes to your device. Note this is required because no
passwords will be set for this system.
- program: What to do in the kiosk. This should be a Nixpkgs attribute
(*package*), an *executable* in that package, and a list of *args*.
- networks: This is a name/value pairing of SSIDs to PSK passphrases.
This can be found with the wpa_passphrase(8) command from
wpa_supplicant.
- locale: This provides some information of what localizations to use.
You can set [[https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2][regulation domain]], [[https://www.gnu.org/software/libc/manual/html_node/Locale-Names.html#Locale-Names][language]], [[https://en.wikipedia.org/wiki/List_of_tz_database_time_zones][time zone]] via “regDom”,
“lang”, and “timeZone”. If unspecified, defaults to US / English /
New York.
- localSystem: Information on system to use for [[https://github.com/matthewbauer/nixiosk#remote-builder-optional][remote builder]].
Optional.
** Push to deploy
:PROPERTIES:
:CUSTOM_ID: push-to-deploy
:END:
By default, Basalt is set up to enable push-to-deploy. This allows you
to make changes to this repo and rebuild the system. Unfortunately, this
requires setting up a remote builder which is kind of difficult to do.
Some steps are as follows:
*** Cloning
:PROPERTIES:
:CUSTOM_ID: cloning
:END:
Once you have a remote builder configure on your Kiosk, you can clone
your Kiosk repo:
#+BEGIN_SRC sh
$ git clone ssh://root@nixiosk.local/etc/nixos/configuration.git nixiosk-configuration
#+END_SRC
From here, you can make some changes, and commit them to the repo. When
done, you can just do:
#+BEGIN_SRC sh
$ git push
#+END_SRC
and read the output of the new deployment.
*** Remote builder (optional)
:PROPERTIES:
:CUSTOM_ID: remote-builder-optional
:END:
Note: this is only necessary for 32-bit ARM systems. NixOS binary caches
are provided for 64-bit ARM, available in Raspberry Pi 3 and 4.
Before starting, you need to make sure your nixiosk.json has the correct
values for your local computer under localSystem. This should be a
hostname that the Kiosk will be able to access. For this to work, you
also need to be a trusted-user on your local system.
First, we need to give the Kiosk SSH access:
#+BEGIN_SRC sh
$ echo $(ssh root@nixiosk.local cat '$HOME'/.ssh/id_rsa.pub) >> $HOME/.ssh/authorized_keys
#+END_SRC
Then, we need to test that we can access the local computer through SSH:
#+BEGIN_SRC sh
$ ssh root@nixiosk.local
$ ssh me@my-laptop-host
#+END_SRC
If all is well, then we can proceed to cloning the configuration.
* Setup
** Install Nix
If you haven’t already, you need to install Nix. This can be done
through the installer:
#+BEGIN_SRC sh
$ bash <(curl -L https://nixos.org/nix/install)
#+END_SRC
** Cache
To speed things up, you should setup a binary cache for nixiosk. This
can be done easily through [[https://nixiosk.cachix.org/][Cachix]]. First, install Cachix:
#+BEGIN_SRC sh
$ nix-env -iA cachix -f https://cachix.org/api/v1/install
#+END_SRC
Then, use the nixiosk cache:
#+BEGIN_SRC sh
$ cachix use nixiosk
#+END_SRC
For more information refer to https://app.cachix.org/cache/nixiosk.
** Initial deployment
The deployment is pretty easy provided you have [[https://nixos.org/nix/][Nix installed]]. Here
are some steps:
#+BEGIN_SRC sh
$ git clone https://github.com/matthewbauer/nixiosk.git
$ cd nixiosk/
$ cp nixiosk.json.sample nixiosk.json
#+END_SRC
Now you need to make some changes to nixiosk.json to reflect what you
want your system to do. The important ones are ‘authorizedKeys’ and
‘networks’ so that your systems can startup and you can connect to it.
If you have an SSH key setup, you can get its value with:
#+BEGIN_SRC sh
$ cat $HOME/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC050iPG8ckY/dj2O3ol20G2lTdr7ERFz4LD3R4yqoT5W0THjNFdCqavvduCIAtF1Xx/OmTISblnGKf10rYLNzDdyMMFy7tUSiC7/T37EW0s+EFGhS9yOcjCVvHYwgnGZCF4ec33toE8Htq2UKBVgtE0PMwPAyCGYhFxFLYN8J8/xnMNGqNE6iTGbK5qb4yg3rwyrKMXLNGVNsPVcMfdyk3xqUilDp4U7HHQpqX0wKrUvrBZ87LnO9z3X/QIRVQhS5GqnIjRYe4L9yxZtTjW5HdwIq1jcvZc/1Uu7bkMh3gkCwbrpmudSGpdUlyEreaHOJf3XH4psr6IMGVJvxnGiV9 mbauer@dellbook
#+END_SRC
which will give you a line for “authorizedKeys” like:
#+BEGIN_SRC json
"authorizedKeys": ["ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC050iPG8ckY/dj2O3ol20G2lTdr7ERFz4LD3R4yqoT5W0THjNFdCqavvduCIAtF1Xx/OmTISblnGKf10rYLNzDdyMMFy7tUSiC7/T37EW0s+EFGhS9yOcjCVvHYwgnGZCF4ec33toE8Htq2UKBVgtE0PMwPAyCGYhFxFLYN8J8/xnMNGqNE6iTGbK5qb4yg3rwyrKMXLNGVNsPVcMfdyk3xqUilDp4U7HHQpqX0wKrUvrBZ87LnO9z3X/QIRVQhS5GqnIjRYe4L9yxZtTjW5HdwIq1jcvZc/1Uu7bkMh3gkCwbrpmudSGpdUlyEreaHOJf3XH4psr6IMGVJvxnGiV9 mbauer@dellbook"],
#+END_SRC
and you can get a PSK value for your WiFi network with:
#+BEGIN_SRC sh
$ nix-shell -p wpa_supplicant --run 'wpa_passphrase my-network'
network={
ssid="my-network"
#psk="abcdefgh"
psk=17e76a6490ac112dbeba996caa7cd1387c6ebf6ce721ef704f92b681bb2e9000
}
#+END_SRC
so your .json file looks like:
#+BEGIN_SRC json
"networks": {
"my-network": "17e76a6490ac112dbeba996caa7cd1387c6ebf6ce721ef704f92b681bb2e9000",
},
#+END_SRC
Now, after inserting your Raspberry Pi SD card into the primary slot,
you can deploy to it with:
#+BEGIN_SRC sh
$ ./deploy.sh /dev/mmcblk0
#+END_SRC
Note that this will take quite a while right now because I don’t have
a binary cache setup. Stay tuned so that this part hopefully gets
easier. It will also take a few minutes to write to your SD card.
You can now eject your SD card and insert it into your Raspberry Pi.
It will boot immediately to a Cog browser, loading
en.wikipedia.org.
** Redeployment
*** Git push
You can pretty easily make changes to a running system given you have
SSH access. This is as easy as cloning the running config:
#+BEGIN_SRC sh
$ git clone ssh://root@nixiosk.local/etc/nixos/configuration.git nixiosk-configuration
$ cd nixiosk-configuration
#+END_SRC
Then, make some changes in your repo. After your done, you can just
run ‘git push’ to redeploy.
#+BEGIN_SRC sh
$ git add .
$ git commit
$ git push
#+END_SRC
You’ll see the NixOS switch-to-configuration log in your command
output. If all is successful, the system should immediately reflect
your changes. If not, the output of Git should explain what went
wrong.
*** Redeploy script
Some machines like the Raspberry Pi 0 are too small to rebuild
themselves. For this, we can use the =update.sh= script. This works by
building a configuration, then running =nix copy= to move it to the
machine, then activating the configuration. Make sure you have plenty
of space on your SD card so that we don’t run out of space!
For example, with retropi1.json, you can do this:
#+BEGIN_SRC sh
$ ./redeploy.sh kodpi2.json kodipi2.local
#+END_SRC
** Development
You can fork and make changes to this repo . A =release.nix= lists all
of the configurations that are tested in CI. There is a =build.sh=
script as well.
It can be used like:
#+BEGIN_SRC sh
$ ./build.sh kodipi2.json
#+END_SRC
Additional arguments are passed to =nix-build=.
* ADVANCED: NixOS module / Flake configuration
For more advanced usage, we can utilize a full NixOS module
configuration. This requires experimental Nix 2.4 features to work.
First, we start with a template from nixiosk template directoy.
To setup a new project:
#+BEGIN_SRC sh
$ nix --experimental-features 'nix-command flakes' flake new -t github:matthewbauer/nixiosk myproject
#+END_SRC
You can look at myproject/flake.nix to get an idea of what you can
configure. Most of the settings in ‘nixosModule’ correspond to what is
available in the custom .json files. One advantage over .json is your
package does not need to be in Nixpkgs. In addition, you can override
other NixOS settings as needed.
The script commands work with flake if you provide a =--flake=
argument. For instance, to build your new configuration:
#+BEGIN_SRC sh
$ nix --experimental-features 'nix-command flakes' shell github:matthewbauer/nixiosk -c \
nixiosk-build --flake ./myproject#nixosConfigurations.example-rpi4
#+END_SRC
This is the SD image for a Raspberry Pi 4 system. Targets for ISO
(packages.x86_64-linux.isoImage), VirtualBox .ova
(packages.x86_64-linux.virtualBoxOVA), and QEMU .qcow2
(packages.x86_64-linux.qcow2) are also available. All of these are
cached on x86_64-linux.
You will most likely want to provide your own "nixiosk.program",
"authorizedKeys", and "networks" in the template baseConfig. Make sure
to also use nixiosk cachix to speed up building.
If you have your Raspberry Pi SD card inserted at /dev/sdb, you can
write to it directly with:
#+BEGIN_SRC sh
$ nix --experimental-features 'nix-command flakes' shell github:matthewbauer/nixiosk -c \
nixiosk-deploy /dev/sdb --flake ./myproject#nixosConfigurations.example-rpi4
#+END_SRC
You can insert the SD card directly into the Raspberry Pi and boot it up.
If the Raspberry Pi connects to your local network, you can deploy
changes with:
#+BEGIN_SRC sh
$ nix --experimental-features 'nix-command flakes' shell github:matthewbauer/nixiosk -c \
nixiosk-redeploy --flake ./myproject#nixosConfigurations.example-rpi4
#+END_SRC
If you don’t have a Raspberry Pi, you can run the QEMU emulator to
test out your configuration locally. This requires hardware
virtualization support to work well. On a graphical session, you can
run:
#+BEGIN_SRC sh
$ nix --experimental-features 'nix-command flakes' shell github:matthewbauer/nixiosk -c \
nixiosk-qemu --flake ./myproject#nixosConfigurations.example-qemu
#+END_SRC
On a non-graphical session, you can run:
#+BEGIN_SRC sh
$ nix --experimental-features 'nix-command flakes' shell github:matthewbauer/nixiosk -c \
nixiosk-qemu --vnc --flake ./myproject#nixosConfigurations.example-qemu
#+END_SRC
You must set the vnc password in the qemu console with =change vnc
password abcdef=. Connect to it in your VNC client with
vnc://localhost (replacing localhost with your local network
hostname).
You can also create a PXE server with:
#+BEGIN_SRC sh
$ nix --experimental-features 'nix-command flakes' shell github:matthewbauer/nixiosk -c \
nixiosk-pixiecore --flake ./myproject#nixosConfigurations.example-pxe
#+END_SRC
* Technology
Here are some of the pieces that make the Kiosk system possible:
- [[https://www.hjdskes.nl/projects/cage/][Cage]] / [[https://wayland.freedesktop.org/][Wayland]]: Cage is a Wayland compositor that allows only one
application to display at a time. This makes the system a true
Kiosk.
- [[https://nixos.org/][NixOS]] - A Linux distro built on top of functional package management.
- [[https://gitlab.com/obsidian.systems/basalt/][Basalt]]: A tool to manage NixOS directly from Git. This allows doing
push-to-deploy directly to NixOS.
- [[https://www.freedesktop.org/wiki/Software/Plymouth/][Plymouth]]: Nice graphical boot animations. Right now, it uses the
NixOS logo but in the future this should be configurable so that you
can include your own branding.
- [[https://www.openssh.com/][OpenSSH]]: Since no direct login is available, SSH is required for
remote administration.
- [[http://www.avahi.org/][Avahi]]: Configures mDNS registration for the system, allowing you to
remember host names instead of IP addresses.
- Cog: A minimalist browser based on WebKitGTK.
I would also like to include some more tools to make administration
easier:
- ddclient / miniupnp: Allow registering external IP address with a
DNS provider. This would enable administration outside of the
device’s immediate network.
* Troubleshooting
:PROPERTIES:
:CUSTOM_ID: troubleshooting
:END:
** /dev/mmcblk0 is not a valid device
If this file doesn’t exist, you may not have your SD card inserted
properly. If it is inserted properly, you may have a different device
name. Look in /dev for other devices.
** /dev/mmcblk0 has partitions! Reformat the table to avoid loss of data
You need to reformat the partition table to ensure we aren’t losing
data. You can do this with wipefs:
#+BEGIN_SRC sh
$ nix-shell -p utillinux -run 'wipefs /dev/mmcblk0'
#+END_SRC
** failed to open '/dev/disk2': Resource busy
You may have to unmount your sd drive to continue. You can try
running:
#+BEGIN_SRC sh
$ sudo diskutil unmountDisk /dev/disk2
#+END_SRC
** SSH into QEMU
In order to SSH into a running QEMU Nixiosk system, you must follow
the following steps:
In the QEMU window, go to the top Menu bar and select "View" →
"compat_monitor0". This will enter into a terminal view.
Within the terminal, type the following followed by enter:
#+BEGIN_SRC text
hostfwd_add tcp::2222-:22
#+END_SRC
Now you can SSH under the 2222 port:
#+BEGIN_SRC sh
$ ssh -p 2222 root@localhost
#+END_SRC
You can switch back to the manu QEMU window by selecting "View" →
"virtio-vga".
If you have multiple QEMU windows open at once, you will need to use a
different port for each one. Just follow the above steps substituting
2222 with 2223.
** SSH requires a password
If you cannot SSH following any of the above instructions, and get something
like:
#+BEGIN_SRC sh
$ ssh -p 2222 root@localhost
(root@localhost) Password:
(root@localhost) Password:
(root@localhost) Password:
root@localhost's password:
Permission denied, please try again.
root@localhost's password:
Permission denied, please try again.
root@localhost's password:
Received disconnect from 127.0.0.1 port 2222:2: Too many authentication failures
#+END_SRC
You have not configured your public keys correctly. Make sure the
contents on =$HOME/.ssh/id_rsa.pub= or similar are included in
authorizedKeys for your system configuration.
Not written in Markdown, so it's shown here as plain text — view it formatted on GitHub.
Nix
67.9%
Shell
32.1%
* Quick start
You can try out a QEMU kiosk, quickly. Just run:
#+BEGIN_SRC sh
$ nix-env -iA cachix -f https://cachix.org/api/v1/install
$ cachix use nixiosk
$ ./qemu.sh nixiosk.json.sample
#+END_SRC
This sets up the Nixiosk cachix and then downloads QEMU as well as the
image defined in nixiosk.json.sample. It then runs that image which
boots up NixOS and a web browser window.
* How it works
:PROPERTIES:
:CUSTOM_ID: how-it-works
:END:
This is a Kiosk builder system. It can be used to make a system that
single graphical program. This is useful for making systems that do
video conferencing, digital signage, informational displays, Internet
kiosks, and more. Right now, only Raspberry Pi 0-4 are supported.
** Configuration
To make things simple, it just reads from an ad-hoc JSON file that
describe the hardware plus some other customizations. It looks like
this:
#+BEGIN_SRC json
{
"hostName": "nixiosk",
"hardware": "raspberryPi4",
"authorizedKeys": [],
"program": {
"package": "cog",
"executable": "/bin/cog",
"args": ["https://en.wikipedia.org/"]
},
"networks": {
"my-router": "0000000000000000000000000000000000000000000000000000000000000000",
},
"locale": {
"timeZone": "America/New_York",
"regDom": "US",
"lang": "en_US.UTF-8"
},
"localSystem": {
"system": "x86_64-linux",
"sshUser": "me",
"hostName": "my-laptop-host",
}
}
#+END_SRC
Here’s a basic idea of what each of these fields do:
- hostName: Name of the host to use. If mDNS is configured on your
network, this can be used to identify the IP address of the device
via “<hostName>.local”.
- hardware: A string describing what hardware we are using. Valid
values currently are “raspberryPi0”, “raspberryPi1”, “raspberryPi2”,
“raspberryPi3”, “raspberryPi4”.
- authorizedKeys: A list of SSH public keys that are authorized to
make changes to your device. Note this is required because no
passwords will be set for this system.
- program: What to do in the kiosk. This should be a Nixpkgs attribute
(*package*), an *executable* in that package, and a list of *args*.
- networks: This is a name/value pairing of SSIDs to PSK passphrases.
This can be found with the wpa_passphrase(8) command from
wpa_supplicant.
- locale: This provides some information of what localizations to use.
You can set [[https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2][regulation domain]], [[https://www.gnu.org/software/libc/manual/html_node/Locale-Names.html#Locale-Names][language]], [[https://en.wikipedia.org/wiki/List_of_tz_database_time_zones][time zone]] via “regDom”,
“lang”, and “timeZone”. If unspecified, defaults to US / English /
New York.
- localSystem: Information on system to use for [[https://github.com/matthewbauer/nixiosk#remote-builder-optional][remote builder]].
Optional.
** Push to deploy
:PROPERTIES:
:CUSTOM_ID: push-to-deploy
:END:
By default, Basalt is set up to enable push-to-deploy. This allows you
to make changes to this repo and rebuild the system. Unfortunately, this
requires setting up a remote builder which is kind of difficult to do.
Some steps are as follows:
*** Cloning
:PROPERTIES:
:CUSTOM_ID: cloning
:END:
Once you have a remote builder configure on your Kiosk, you can clone
your Kiosk repo:
#+BEGIN_SRC sh
$ git clone ssh://root@nixiosk.local/etc/nixos/configuration.git nixiosk-configuration
#+END_SRC
From here, you can make some changes, and commit them to the repo. When
done, you can just do:
#+BEGIN_SRC sh
$ git push
#+END_SRC
and read the output of the new deployment.
*** Remote builder (optional)
:PROPERTIES:
:CUSTOM_ID: remote-builder-optional
:END:
Note: this is only necessary for 32-bit ARM systems. NixOS binary caches
are provided for 64-bit ARM, available in Raspberry Pi 3 and 4.
Before starting, you need to make sure your nixiosk.json has the correct
values for your local computer under localSystem. This should be a
hostname that the Kiosk will be able to access. For this to work, you
also need to be a trusted-user on your local system.
First, we need to give the Kiosk SSH access:
#+BEGIN_SRC sh
$ echo $(ssh root@nixiosk.local cat '$HOME'/.ssh/id_rsa.pub) >> $HOME/.ssh/authorized_keys
#+END_SRC
Then, we need to test that we can access the local computer through SSH:
#+BEGIN_SRC sh
$ ssh root@nixiosk.local
$ ssh me@my-laptop-host
#+END_SRC
If all is well, then we can proceed to cloning the configuration.
* Setup
** Install Nix
If you haven’t already, you need to install Nix. This can be done
through the installer:
#+BEGIN_SRC sh
$ bash <(curl -L https://nixos.org/nix/install)
#+END_SRC
** Cache
To speed things up, you should setup a binary cache for nixiosk. This
can be done easily through [[https://nixiosk.cachix.org/][Cachix]]. First, install Cachix:
#+BEGIN_SRC sh
$ nix-env -iA cachix -f https://cachix.org/api/v1/install
#+END_SRC
Then, use the nixiosk cache:
#+BEGIN_SRC sh
$ cachix use nixiosk
#+END_SRC
For more information refer to https://app.cachix.org/cache/nixiosk.
** Initial deployment
The deployment is pretty easy provided you have [[https://nixos.org/nix/][Nix installed]]. Here
are some steps:
#+BEGIN_SRC sh
$ git clone https://github.com/matthewbauer/nixiosk.git
$ cd nixiosk/
$ cp nixiosk.json.sample nixiosk.json
#+END_SRC
Now you need to make some changes to nixiosk.json to reflect what you
want your system to do. The important ones are ‘authorizedKeys’ and
‘networks’ so that your systems can startup and you can connect to it.
If you have an SSH key setup, you can get its value with:
#+BEGIN_SRC sh
$ cat $HOME/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC050iPG8ckY/dj2O3ol20G2lTdr7ERFz4LD3R4yqoT5W0THjNFdCqavvduCIAtF1Xx/OmTISblnGKf10rYLNzDdyMMFy7tUSiC7/T37EW0s+EFGhS9yOcjCVvHYwgnGZCF4ec33toE8Htq2UKBVgtE0PMwPAyCGYhFxFLYN8J8/xnMNGqNE6iTGbK5qb4yg3rwyrKMXLNGVNsPVcMfdyk3xqUilDp4U7HHQpqX0wKrUvrBZ87LnO9z3X/QIRVQhS5GqnIjRYe4L9yxZtTjW5HdwIq1jcvZc/1Uu7bkMh3gkCwbrpmudSGpdUlyEreaHOJf3XH4psr6IMGVJvxnGiV9 mbauer@dellbook
#+END_SRC
which will give you a line for “authorizedKeys” like:
#+BEGIN_SRC json
"authorizedKeys": ["ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC050iPG8ckY/dj2O3ol20G2lTdr7ERFz4LD3R4yqoT5W0THjNFdCqavvduCIAtF1Xx/OmTISblnGKf10rYLNzDdyMMFy7tUSiC7/T37EW0s+EFGhS9yOcjCVvHYwgnGZCF4ec33toE8Htq2UKBVgtE0PMwPAyCGYhFxFLYN8J8/xnMNGqNE6iTGbK5qb4yg3rwyrKMXLNGVNsPVcMfdyk3xqUilDp4U7HHQpqX0wKrUvrBZ87LnO9z3X/QIRVQhS5GqnIjRYe4L9yxZtTjW5HdwIq1jcvZc/1Uu7bkMh3gkCwbrpmudSGpdUlyEreaHOJf3XH4psr6IMGVJvxnGiV9 mbauer@dellbook"],
#+END_SRC
and you can get a PSK value for your WiFi network with:
#+BEGIN_SRC sh
$ nix-shell -p wpa_supplicant --run 'wpa_passphrase my-network'
network={
ssid="my-network"
#psk="abcdefgh"
psk=17e76a6490ac112dbeba996caa7cd1387c6ebf6ce721ef704f92b681bb2e9000
}
#+END_SRC
so your .json file looks like:
#+BEGIN_SRC json
"networks": {
"my-network": "17e76a6490ac112dbeba996caa7cd1387c6ebf6ce721ef704f92b681bb2e9000",
},
#+END_SRC
Now, after inserting your Raspberry Pi SD card into the primary slot,
you can deploy to it with:
#+BEGIN_SRC sh
$ ./deploy.sh /dev/mmcblk0
#+END_SRC
Note that this will take quite a while right now because I don’t have
a binary cache setup. Stay tuned so that this part hopefully gets
easier. It will also take a few minutes to write to your SD card.
You can now eject your SD card and insert it into your Raspberry Pi.
It will boot immediately to a Cog browser, loading
en.wikipedia.org.
** Redeployment
*** Git push
You can pretty easily make changes to a running system given you have
SSH access. This is as easy as cloning the running config:
#+BEGIN_SRC sh
$ git clone ssh://root@nixiosk.local/etc/nixos/configuration.git nixiosk-configuration
$ cd nixiosk-configuration
#+END_SRC
Then, make some changes in your repo. After your done, you can just
run ‘git push’ to redeploy.
#+BEGIN_SRC sh
$ git add .
$ git commit
$ git push
#+END_SRC
You’ll see the NixOS switch-to-configuration log in your command
output. If all is successful, the system should immediately reflect
your changes. If not, the output of Git should explain what went
wrong.
*** Redeploy script
Some machines like the Raspberry Pi 0 are too small to rebuild
themselves. For this, we can use the =update.sh= script. This works by
building a configuration, then running =nix copy= to move it to the
machine, then activating the configuration. Make sure you have plenty
of space on your SD card so that we don’t run out of space!
For example, with retropi1.json, you can do this:
#+BEGIN_SRC sh
$ ./redeploy.sh kodpi2.json kodipi2.local
#+END_SRC
** Development
You can fork and make changes to this repo . A =release.nix= lists all
of the configurations that are tested in CI. There is a =build.sh=
script as well.
It can be used like:
#+BEGIN_SRC sh
$ ./build.sh kodipi2.json
#+END_SRC
Additional arguments are passed to =nix-build=.
* ADVANCED: NixOS module / Flake configuration
For more advanced usage, we can utilize a full NixOS module
configuration. This requires experimental Nix 2.4 features to work.
First, we start with a template from nixiosk template directoy.
To setup a new project:
#+BEGIN_SRC sh
$ nix --experimental-features 'nix-command flakes' flake new -t github:matthewbauer/nixiosk myproject
#+END_SRC
You can look at myproject/flake.nix to get an idea of what you can
configure. Most of the settings in ‘nixosModule’ correspond to what is
available in the custom .json files. One advantage over .json is your
package does not need to be in Nixpkgs. In addition, you can override
other NixOS settings as needed.
The script commands work with flake if you provide a =--flake=
argument. For instance, to build your new configuration:
#+BEGIN_SRC sh
$ nix --experimental-features 'nix-command flakes' shell github:matthewbauer/nixiosk -c \
nixiosk-build --flake ./myproject#nixosConfigurations.example-rpi4
#+END_SRC
This is the SD image for a Raspberry Pi 4 system. Targets for ISO
(packages.x86_64-linux.isoImage), VirtualBox .ova
(packages.x86_64-linux.virtualBoxOVA), and QEMU .qcow2
(packages.x86_64-linux.qcow2) are also available. All of these are
cached on x86_64-linux.
You will most likely want to provide your own "nixiosk.program",
"authorizedKeys", and "networks" in the template baseConfig. Make sure
to also use nixiosk cachix to speed up building.
If you have your Raspberry Pi SD card inserted at /dev/sdb, you can
write to it directly with:
#+BEGIN_SRC sh
$ nix --experimental-features 'nix-command flakes' shell github:matthewbauer/nixiosk -c \
nixiosk-deploy /dev/sdb --flake ./myproject#nixosConfigurations.example-rpi4
#+END_SRC
You can insert the SD card directly into the Raspberry Pi and boot it up.
If the Raspberry Pi connects to your local network, you can deploy
changes with:
#+BEGIN_SRC sh
$ nix --experimental-features 'nix-command flakes' shell github:matthewbauer/nixiosk -c \
nixiosk-redeploy --flake ./myproject#nixosConfigurations.example-rpi4
#+END_SRC
If you don’t have a Raspberry Pi, you can run the QEMU emulator to
test out your configuration locally. This requires hardware
virtualization support to work well. On a graphical session, you can
run:
#+BEGIN_SRC sh
$ nix --experimental-features 'nix-command flakes' shell github:matthewbauer/nixiosk -c \
nixiosk-qemu --flake ./myproject#nixosConfigurations.example-qemu
#+END_SRC
On a non-graphical session, you can run:
#+BEGIN_SRC sh
$ nix --experimental-features 'nix-command flakes' shell github:matthewbauer/nixiosk -c \
nixiosk-qemu --vnc --flake ./myproject#nixosConfigurations.example-qemu
#+END_SRC
You must set the vnc password in the qemu console with =change vnc
password abcdef=. Connect to it in your VNC client with
vnc://localhost (replacing localhost with your local network
hostname).
You can also create a PXE server with:
#+BEGIN_SRC sh
$ nix --experimental-features 'nix-command flakes' shell github:matthewbauer/nixiosk -c \
nixiosk-pixiecore --flake ./myproject#nixosConfigurations.example-pxe
#+END_SRC
* Technology
Here are some of the pieces that make the Kiosk system possible:
- [[https://www.hjdskes.nl/projects/cage/][Cage]] / [[https://wayland.freedesktop.org/][Wayland]]: Cage is a Wayland compositor that allows only one
application to display at a time. This makes the system a true
Kiosk.
- [[https://nixos.org/][NixOS]] - A Linux distro built on top of functional package management.
- [[https://gitlab.com/obsidian.systems/basalt/][Basalt]]: A tool to manage NixOS directly from Git. This allows doing
push-to-deploy directly to NixOS.
- [[https://www.freedesktop.org/wiki/Software/Plymouth/][Plymouth]]: Nice graphical boot animations. Right now, it uses the
NixOS logo but in the future this should be configurable so that you
can include your own branding.
- [[https://www.openssh.com/][OpenSSH]]: Since no direct login is available, SSH is required for
remote administration.
- [[http://www.avahi.org/][Avahi]]: Configures mDNS registration for the system, allowing you to
remember host names instead of IP addresses.
- Cog: A minimalist browser based on WebKitGTK.
I would also like to include some more tools to make administration
easier:
- ddclient / miniupnp: Allow registering external IP address with a
DNS provider. This would enable administration outside of the
device’s immediate network.
* Troubleshooting
:PROPERTIES:
:CUSTOM_ID: troubleshooting
:END:
** /dev/mmcblk0 is not a valid device
If this file doesn’t exist, you may not have your SD card inserted
properly. If it is inserted properly, you may have a different device
name. Look in /dev for other devices.
** /dev/mmcblk0 has partitions! Reformat the table to avoid loss of data
You need to reformat the partition table to ensure we aren’t losing
data. You can do this with wipefs:
#+BEGIN_SRC sh
$ nix-shell -p utillinux -run 'wipefs /dev/mmcblk0'
#+END_SRC
** failed to open '/dev/disk2': Resource busy
You may have to unmount your sd drive to continue. You can try
running:
#+BEGIN_SRC sh
$ sudo diskutil unmountDisk /dev/disk2
#+END_SRC
** SSH into QEMU
In order to SSH into a running QEMU Nixiosk system, you must follow
the following steps:
In the QEMU window, go to the top Menu bar and select "View" →
"compat_monitor0". This will enter into a terminal view.
Within the terminal, type the following followed by enter:
#+BEGIN_SRC text
hostfwd_add tcp::2222-:22
#+END_SRC
Now you can SSH under the 2222 port:
#+BEGIN_SRC sh
$ ssh -p 2222 root@localhost
#+END_SRC
You can switch back to the manu QEMU window by selecting "View" →
"virtio-vga".
If you have multiple QEMU windows open at once, you will need to use a
different port for each one. Just follow the above steps substituting
2222 with 2223.
** SSH requires a password
If you cannot SSH following any of the above instructions, and get something
like:
#+BEGIN_SRC sh
$ ssh -p 2222 root@localhost
(root@localhost) Password:
(root@localhost) Password:
(root@localhost) Password:
root@localhost's password:
Permission denied, please try again.
root@localhost's password:
Permission denied, please try again.
root@localhost's password:
Received disconnect from 127.0.0.1 port 2222:2: Too many authentication failures
#+END_SRC
You have not configured your public keys correctly. Make sure the
contents on =$HOME/.ssh/id_rsa.pub= or similar are included in
authorizedKeys for your system configuration.
Not written in Markdown, so it's shown here as plain text — view it formatted on GitHub.
Nix
67.9%
Shell
32.1%