This is a continuation of my previous article on the Net Booted Thin Client. The instructions got way too long, so I created a new article for the client setup. You need a functional server setup (TFTP, HTTP, iPXE) which I did in my previous post. I could use something like Linux Terminal Server Project, but that’s a bit overkill for this, and I wanted to learn Alpine anyway, so I’ve chosen to use Alpine Linux for the client operating system. It’s extremely basic.

Here, we’re gonna create an apkovl file. This is essentially a minimal set of the data on the system, so the system can be recreated. It includes all of the system configuration in /etc, any other directories you specify, and the /etc/apk/world file. When the APKOVL is loaded, it will install all of the apk packages in the world file, and apply the apkovl files on top of any defaults.

We are going to take the ISO image for Alpine Linux, boot it in a VM without a hard disk (live, no installation), and configure it to our liking as a thin client. Once we’re happy, we’re going to generate an apkovl file and save it to our http server, then delete the VM.


Here’s a table of contents. This assumes you have a functional netboot environment including TFTP, HTTP, and iPXE - such as what I setup in my previous article/video.


Click on the thumbnail to watch the video for this! Video Thumbnail

Basic Alpine Environment

The basics of getting Alpine setup:

  1. Login as root in the base system (no password by default)
  2. Run setup-alpine, with the following selections:
    1. Pick your keyboard layout
    2. Setup hostname. I chose thinclient
    3. Setup eth0 for DHCP with no additional configuration
    4. Set a root password
    5. Choose timezone (I chose America/Detroit)
    6. No HTTP proxy information
    7. Choose ‘1’ for the mirror (this is alpine’s primary mirror)
    8. Choose none for SSH
    9. Try boot media as a package repository (for now)
    10. Disk = none (this will not install Alpine anywhere, just setup the system in RAM)
    11. Where to store configs = none (this means it won’t have a place for lbu, but it’s okay)
    12. APK cache directory = none (this means it has to go out to the internet to install anything)
  3. Install nano - apk add nano
  4. Edit /etc/apk/repositories to comment out the cdrom (first line) and uncomment the community repository (third line)
  5. Setup the X11 server for graphics - setup-xorg-base
  6. Install all the stuff we need for a basic kiosk via apk - apk add openbox xterm terminus-font font-noto
  7. Add user - adduser vdi, follow prompts, then add to input and video groups addgroup vdi input and addgroup vdi video
  8. If you want to be fun, you can edit /etc/motd with your own message, but nobody should see it.

Install PVE VDI Client

If you’re creating your own netbooted appliance based on this guide, you would install whatever software you want here (like Firefox or Remmina) using apk, set it up, and skip down to Configure Openbox to launch your kiosk software of choice graphically. Make sure all files you need for your appliance are stored in either your home directory (/home/vdi) or in /etc, otherwise they will be lost when we bundle the APK Overlay.

Install and configure PVE VDI Client in the simplest way possible. You’re free to add your own icons, etc. if you wish, but this uses the ones that Josh created already.

  1. Install packages we need specific to the thin client - apk add python3 py3-pip py3-pyside2 virt-viewer git
  2. Login as new user vdi (exit to logout)
  3. Install pip packages - pip3 install proxmoxer PySimpleGUIQt requests
  4. Upgrade PySimpleGUI to 0.35.0 since it doesn’t find pyside2 installed via apk - pip3 install PySimpleGUIQt==0.35.0 --no-deps
  5. Clone PVE-VDIClient - git clone
  6. Make executable - chmod +x ~/PVE-VDIClient/
  7. Create config dir - mkdir -p ~/.config/VDIClient
  8. Create config file - nano ~/.config/VDIClient/vdiclient.ini

And the contents:

#All of the settings in general can be customized if you want
title = apalrd VDI
theme = DarkAmber
icon = /home/vdi/PVE-VDIClient/vdiicon.ico
logo = /home/vdi/PVE-VDIClient/vdiclient.png


#Replace this with your Proxmox host or DNS name

Configure Openbox

Openbox is going to be the window manager here, so we need to configure it to start when X initializes, to launch the VDI client in a run loop, and to start X when the user vdi logs in

  1. Set X to launch on login - echo 'exec startx' >> ~/.profile
  2. Set openbox as default session - echo 'exec openbox-session' >> ~/.xinitrc
  3. Copy Openbox default config - cp -r /etc/xdg/openbox ~/.config
  4. Remove autostart file - rm ~/.config/openbox/autostart
  5. New autostart file - nano ~/.config/openbox/autostart

And the contents:

while true

Test that the VDI Client Works

Run startx and ensure that the client starts correctly. If it doesn’t, right-click on the black background and launch xterm, then try running ~/PVE-VDIClient/ manually to see the terminal output.

Once you are done, right-click on the black background and launch xterm, then run killall xinit which should kick you back to the login screen. Try logging in again to make sure you are launched directly into the X session.

Autostart on Boot

  1. Log back out of vdi (if you are currently in the X session, you have to do killall xinit)
  2. Log in as root with password
  3. Edit inittab to login as vdi automatically - nano /etc/inittab
#Find this line
tty1::respawn:/sbin/getty 38400 tty1
#Replace with this line
tty1::respawn:/bin/login -f vdi


Now we can generate the apkovl.tar.gz, still logged in as root:

  1. Remove the .ash_history from vdi so our command history isn’t visible to anyone - rm -f /home/vdi/.ash_history
  2. (Optional) Remove the packages we installed but only needed for setup so they aren’t usable in the final system - apk del git xterm nano - if you do this, you will have absolutely no way of debugging the setup once it netboots, so make sure it works at this point.
  3. Include /home in the lbu package - lbu include /home
  4. Package the system using lbu - lbu package thinclient.apkovl.tar.gz

Copy APKOVL to Netboot Server

Now we are going to temporarily stand up an HTTP server to offload our .tar.gz. Busybox includes an httpd server, but it’s not compiled in the busybox that Alpine includes by default. Thankfully, Alpine provides another busybox binary as a package that includes all options.

  1. Install busybox-extras so we have the version with httpd - apk add busybox-extras
  2. Get our IP address - ip a
  3. Use busybox-extras to launch an httpd server here - busybox-extras httpd -f -v
  4. Switch to the netboot server we set up in the previous episode, log in as root
  5. Change to the www directory - cd /srv/www
  6. Download the file - wget http://<temp client ip>/thinclient.apkovl.tar.gz


If all goes well, you should be able to boot your client, and as long as PXE is enabled higher than any other bootable devices in the boot order, it should launch into our thin client. You can even configure a VM in Proxmox with no disk and no DVD drive and it should netboot.