Home Server: Installing Docker, Portainer & Home-Assistant on Proxmox

Home Server: Installing Docker, Portainer & Home-Assistant on Proxmox

So recently I’ve been looking to find a small low powered machine that I could use as a small media server. I’m currently abroad so I was looking for a light weight machine that I could move around quite easily, but would also be sufficiently powerful enough to run the home and distribute media. Beelink were kind enough to send me one of their units for me to play with. I also wanted to do a complete home server set up tutorial, so this coincided perfectly. In this post, I’ll go over the Beelink GK Mini that they’ve sent me and then we’ll go through setting it up as a home server. By the end of this post, you’ll have a small efficient little server running, proxmox, home-assistant, docker and portainer. Let’s get started.

Beelink GK Mini

Initial Packaging Impressions were good
Initial Packaging Impressions were good

 

 

Beelink sent me this unit directly and it seems to fit the bill. It came well wrapped in the post and the packaging felt high end, almost apple-esque if you will. My unit had 8GBs of Ram and a 256GB m.2 drive. It has two full size hdmi ports (Intel HD Graphics 600 GPU) and both will support h.265 and VP9 video playback up to 4K resolutions. The specs can be found below, and the product page is here.

  • CPU: Intel Celeron J4125 (Gemini Lake)
  • Network: Gigabit / Wifi 802.11b/g/n/ac, 2.4 + 5.8Ghz
  • Memory: 8GB
  • Storage: 128/256/512GB m.2 and room for an SSD in the base of the unit.
  • Ports: 4* USB 3.0, 1* 1000 LAN, 2* HDMI (fullsize), audio jack (headphone+mic)
  • Power: DC-in (12V / 2A)
  • Size: 115mm*102mm*43mm, under 300g

In the box alongside the unit and power adaptor, we have a fixing plate for VESA mounting, user manual and a pair of HDMI cables. One short, and one long. We also have a small bag of replacement/drive screws.

Contents of the Box
Contents of the Box

When you first pick up the unit, it’s hard to describe how light it feels. It’s made from plastic, but it doesn’t feel cheap. I’ve taken a couple of shots of it alongside my 6th Generation Intel Nuc. Whilst they’re both small form factor, the beelink is smaller and significantly lighter.

Beelink GK Mini v Intel 6th Gen NUC
Beelink GK Mini v Intel 6th Gen NUC
Beelink GK Mini v Intel 6th Gen NUC
Beelink GK Mini v Intel 6th Gen NUC

I did take a quick look under the hood so to speak. In the base of the unit you can add an SSD. I was pleasantly surprised to see a heatsink had been used on the m.2 sata drive.

Room for an SSD
Room for an SSD

I plugged the machine in and powered her up. The power button gave a satisfying click when pressed. Within a few moments I was met with the Windows 10 set up page. A couple of minutes of declining to be tracked and refusing to use Cortana and we were in business. The GK mini was up and running and connected to my WIfi. The machine came with Windows 10 Pro, although this wasn’t the OS I wanted to use with it. I used a quick script to extract the Windows Licence key (to add to my collection) from the install and shut the machine down. It was time to give this little unit its new OS.

 

Installing Proxmox

Proxmox
Proxmox

I decided to go with Proxmox for this build as I felt Unraid wouldn’t run so well on the hardware and would be a bit of a waste. I wanted to use a bare metal hypervisor and wanted the simplicity of Docker and Portainer, alongside the ability to run a VM for Home-Assistant (Supervised). To install Proxmox, we needed to download the ISO and flash it to a USB drive.

I downloaded the latest version of Proxmox from here. I chose the Proxmox VE 7.0 ISO Installer.

Next it was time to download Etcher in order to flash the ISO above onto the USB drive. I used Chocolatey to accomplish this (this saves me so much time).

Installing Etcher with Choco
Installing Etcher with Choco

Within a few short moments, we were done. Select your ISO and your target disk (make sure you select the correct drive!) and begin the flash.

Flashing the USB drlive with Proxmox
Flashing the USB drlive with Proxmox
USB flashed Successfully
USB flashed Successfully

Next it was time to go into the BIOS of the Beelink GK Mini to make sure that USB was the first option on the Boot order. After switching her on, i repeatedly pressed DEL until I was faced with the BIOS. No airs and graces here. Nothing fancy like the NUC’s BIOS, but I was surprised by the sheer amount of configurability that was available. There was an option for absolutely everything. Virtualisation had already been switched on thankfully. Once the boot order was amended. I plugged in the stick and rebooted the machine.

I selected to install Proxmox v7 .

Install Proxmox
Install Proxmox

 

I agreed to the EULA, selected the 256GB drive as the Target Harddisk, and filled out my regional details (country, time, keyboard etc). Pop in your email and configure a secure password (this will be used to access the machine). Next, I needed to name the machine. Thanks to dhcp, the ip address, gateway and DNS were pre-filled. Remember to reserve this IP address in your router’s page to make sure it stays constant. If you have more than one network port in your machine, make sure you pick the correct one at the top. For naming, I just left it as is.

Configuring the Machine's Details
Configuring the Machine’s Details

I confirmed the settings on the next page and within a few short moments, I was being asked to remove the install media and reboot the machine. Once it came back up, I logged in as root (default user) and used the password we’d set up a minute earlier. On entry I was greeted with this:

 

Proxmox v7
Proxmox v7

Next thing we want to do is to update it to the latest version. The simplest and easiest way I found to do this was to use shell commands.

Using Shell Commands in Proxmox
Using Shell Commands in Proxmox

Click on your machine (pve in my case) and then the Shell icon. Next we need to run the following commands:

nano /etc/apt/sources.list

I copied and pasted over the existing content with this:

deb http://ftp.us.debian.org/debian bullseye main contrib
deb http://ftp.us.debian.org/debian bullseye-updates main contrib
# security updates
deb http://security.debian.org bullseye/updates main contrib
# not for production use
deb http://download.proxmox.com/debian bullseye pve-no-subscription

Ctrl O and Ctrl X when you’re done. Next command:

nano /etc/apt/sources.list.d/pve-enterprise.list
I amended my file to look like this (note the # at the beginning).
# deb https://enterprise.proxmox.com/debian/pve bullseye pve-enterprise

Ctrl O and Ctrl X to save and exit.

apt-get update

apt dist-upgrade

reboot

Your machine should be fully updated now. You’ll still see the disclaimer about you not having a subscription, but you can ignore this.

Subscription Error
Subscription Error

To check, click on Updates, and hit the refresh window.

Updates Successfully Run
Updates Successfully Run

Once done, close it. You should see there’s nothing listed to upgrade. If there is something there, then simply click upgrade and you should be good.

At this point, you have a full updated and working proxmox installation. What else can we do with it?

Creating a Container

I’m a huge fan of Docker and Portainer for managing the various containers. Docker is something that Unraid does so well, but that doesn’t mean we can’t enjoy similar here. Let’s install Docker via an LXC container. Go back to the shell window and type the following:

pveam update

This command essentially updates the list of templates that we can choose from when creating a container. We need a template to base our container on. Click on local storage on the left, then CT Templates on the right.

 

Navigating to the Template Area
Navigating to the Template Area

You’ll see a button above saying templates. Click on that.

Selection of Templates
Selection of Templates

For our Template, we are going to use turnkey-core, which is basically a very lightweight version of Linux which should help keep the container quick and relatively light. Search for core and download it. It will be downloaded into your server’s template database. Remember, if you find you only have a few templates to choose from, make sure you carried out the pveam update command in the shell previously.

Searching for Turnkey Core
Searching for Turnkey Core

Now that we have our turnkey template downloaded, let’s move on.

Click on Create CT (container) on the top right.

I don’t want to go through each and every option, as things like CPU (cores etc), Memory, Storage are pretty self explanatory. I’ll cover the main points…

You need to give your container an ID. Your node (server) should be pre-filled. Add credentials as necessary.

Container General
Container General

Select the template that we’d previously downloaded.

Choosing your template
Choosing your template

For the next few tabs, I selected 100gb, 1 cpu, 2048gb memory.

For network I set it to DHCP, and for DNS I left it as standard (handled by the host).

My confirmation screen looked like this:

Create Container Confirm Screen
Create Container Confirm Screen

Hit finish and you’re almost done. Next we need to click on the container options tab and double click on features. We need to make sure “Nesting” and “keyctl” are enabled.

Switching on Nesting and Keyctl
Switching on Nesting and Keyctl

With that done, start the container (right click shortcut) and within a few seconds you should be up and running. Login with root and the password that you specified on the General tab above and you should now have a linux prompt ready for the next step. Turnkey needs to be installed. As the install screens appear, you can skip the first two but choose install for the third. Once the process is complete and Turnkey is installed, exit with Ctrl+C and then run the following commands as normal:

apt-get update

apt-get upgrade

Depending on the number of updates needed, it might be a good idea to reboot the container before we proceed with installing docker.

 

Installing Docker

in the shell of the container you just created, copy and paste the following commands (for command 2 and 3 you can paste them in as one multi line command each):

apt-get update

apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release

curl -fsSL https://download.docker.com/linux/debian/gpg | gpg –dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg    ** for some reason wordpress isn’t showing that dearmor needs a double dash not a single** 

echo \
“deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \
$(lsb_release -cs) stable” | tee /etc/apt/sources.list.d/docker.list > /dev/null

apt-get update

apt-get install docker-ce docker-ce-cli containerd.io

This should have added and installed docker to your container. To check it’s running, paste in the final command:

systemctl status docker

If all is well, you should be met with a screenshot similar to the below (to return to the command line, hit ctrl + c):

Docker Success
Docker Success

So we now have Docker running in a very lightweight container. Let’s install Portainer so that we can administer our Docker containers easier.

Installing Portainer

This is very easy to do. Literally, in the same shell prompt as above, type the following command.

docker volume create portainer_data

This creates a place where we can place our data. Next we need to pull down the Portainer image from the cloud and install it.

docker run -d -p 8000:8000 -p 9000:9000 –name=portainer –restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce

And we’re done. The command above will download Portainer, expose it on your container’s IP address:9000 and set it to restart always. Give it a few moments to fully download and install, and if you’ve done everything correctly, you should be met with the following page:

Portainer Installed on Proxmox
Portainer Installed on Proxmox

Couple of things to note. You may need to check the IP address of the container. in the command prompt (shell of the container) you can type the following:

ifconfig

you can then reserve that container’s ip address in your router’s settings. I prefer to do it this way so the router (in my case my pfsense setup) has full oversight on what IP address is given to what machine, container, vm etc. If you’d prefer to manually specify the IP address in the container, then you can just click on the network tab and double click the DHCP option we set earlier and amend as needed.

I immediately made a snapshot of the container with just Portainer and Docker installed to use as a base should something go wrong with the installation in the future. This was as simple as selecting Snapshots in the Container menu and pressing Take Snapshot!

Taking a Container Snapshot
Taking a Container Snapshot

So to summarise, you can now create LXC containers, download templates, create docker containers and manage them via Portainer. Let’s have a look at Home-Assistant.

Installing Home-Assistant

As it stands there are many ways to install Home-Assistant. Some of the most popular include running it in Docker as a container, creating a virtual machine and installing it natively as an application, or you can also Home-Assistant as a complete OS (appliance) and run what is known as “supervised”. We’re going to go with the latter variant. You don’t need to run supervised you can achieve most of it using individual containers and installations, but for the purposes of this tutorial, we’re going to go with the most beginner friendly.

As we’re working with Proxmox today, we need to download and unzip the .qcow2 image found here:

We need the .qcow2
We need the .qcow2

 

Go to Proxmox and click on the Create VM button on the top right, you should already be familiar with the layout, given we’ve created a container above already. Make sure the container has a unique ID, and give it a name.

Creating Your Virtual Machine
Creating Your Virtual Machine

Next let’s go through the rest of the steps:

Don't choose an OS yet
Don’t choose an OS yet
Change the Bios
Change the Bios to OVMF
Spec your Hard Disk
Spec your Hard Disk
Choose your CPU
Choose your CPU
Choose Your Memory
Choose Your Memory
The Network Settings
The Network Settings
Confirmation of VM
Confirmation of VM

 

Hit finish, but don’t start just yet. We need to swap in the .qcow2 disk that we previously downloaded. Use your favourite SFTP client to move the unzipped .qcow2 file over into the root directory of proxmox. Credentials should be root / password, proxmox ip and port 22.

Transferring the file to Root
Transferring the file to Root

Then go to the Server’s shell and enter the following command to import the disk from the root directory into the VM you just created:

qm importdisk 100 /root/hasos_ova-6.4.qcow2 local-lvm –format qcow2

A couple of things to be mindful of. In the command above you may need to change it according to your set up. My VM has the id 100, hence the qm importdisk 100. Also, at the time of writing this, HA OS was 6.4. If you download a file from Home-Assistant and the file is 6.5 etc, then you’ll need to modify the above command accordingly.

Once you send the disk across, you can delete the file in the root directory (I did this in filezilla). Now we need to amend the VM’s configuration to use this disk instead of the existing ones. Detach the original Hard Disk using the button above.

Detach the original Hard Disk
Detach the original Hard Disk

 

Once detached you’ll see two Unused Disks. Disk 0 which is the one that we have added already but not incorporated, and Disk 1 which is the disk we just detached but it’s still part of the machine. Click on Disk 1 and remove it using the button above. Once removed and erased, you’ll be left with Unused Disk 0. Click on it and press add.

Adding the HA disk to your VM
Adding the HA disk to your VM

Now we need to amend the boot order to ensure the VM starts off it (remember to enable also).

Changing the Boot Order
Changing the Boot Order
Change your Boot Order
Change your Boot Order

Also whilst you’re there in the Options panel, enable the QEMU Guest Agent. If you don’t enable it, Home-Assistant will still run perfectly well, but it will flag an error on boot, so for my own piece of mind, I enabled it to remove the error.

And that’s it. We’re done. Start the machine and wait a few minutes for Home-Assistant to load. If all’s gone well, once you log in, you should be greeted with this familiar screen. You can highlight the console icon on the VM at any time and you’ll be shown the IP address etc.

Home-Assistant: Blank Canvas
Home-Assistant: Blank Canvas

I immediately took a snapshot like before:

Home-Assistant Snapshot
Home-Assistant Snapshot

And there you have it. You have Supervised Home-Assistant running on Proxmox, with instant snapshots you can roll back to. You can use the add-ons in the VM, or you can choose to use containers in docker as you see fit. Candidates for either would be things like:

 

Summary

So to summarise, I am very pleased with the Beelink GK Mini. It’s small, very quiet (not silent, but not irritating by any means) and it’s more than capable of running a home server. Current utilisation with just a Home-Assistant VM and Portainer running is as follows:

Current Server Utilisation
Current Server Utilisation

As you can see plenty of overhead on the Celeron there. I plan to add a 1TB ssd to it in the coming weeks and to build up a complete docker stack allowing me to distribute media around the home and whilst out and about. I will be adding Tailscale to the server to allow me to access it when away, without the need to use any portforwards.

A huge thank you to Beelink for providing me with the unit itself. They have a range of AMD and Intel products that would cover most of your needs. Check out the full range here.

On the Proxmox side, I know that I’m only scratching the surface right now. We haven’t covered additional disks, storage arrays, or a myraid of other things that Proxmox does well. Consider this an entry level walkthrough! If you have any good ideas on how to utilise Proxmox further, pop them in the comments below or come over to our facebook group to discuss further.

https://www.facebook.com/groups/386238285944105

If you’re considering a renovation and looking at the structured wiring side of things, or maybe you just want to support the blog, have a look below at my smarthome book, it’s available in all the usual places (including paperback)!

The Smarthome Book
The Smarthome Book

 

Comments

  1. doesn’t works

    root@FRIGATE ~# apt-get install docker-ce docker-ce-cli containerd.io
    Reading package lists… Done
    Building dependency tree
    Reading state information… Done
    Package docker-ce is not available, but is referred to by another package.
    This may mean that the package is missing, has been obsoleted, or
    is only available from another source

    E: Package ‘docker-ce’ has no installation candidate
    E: Unable to locate package docker-ce-cli
    E: Unable to locate package containerd.io
    E: Couldn’t find any package by glob ‘containerd.io’
    E: Couldn’t find any package by regex ‘containerd.io’

    1. Hey Bob, I’d left a command out accidentally. Run apt-get remove docker docker-engine docker.io containerd runc and go through the commands again. I’ve inserted the missing curl command. You should be good now!

  2. Tnx for your great tutorial. Unfortunatly it doesn’t work:

    Err:3 https://download.docker.com/linux/debian buster InRelease
    The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY 7EA0A9C3F273FCD8
    Reading package lists… Done
    W: GPG error: https://download.docker.com/linux/debian buster InRelease: The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY 7EA0A9C3F273FCD8
    E: The repository ‘https://download.docker.com/linux/debian buster InRelease’ is not signed.
    N: Updating from such a repository can’t be done securely, and is therefore disabled by default.
    N: See apt-secure(8) manpage for repository creation and user configuration details.

    1. Hey there, thanks for the kind words, sorry to hear you’re having issues. I wonder if this is similar to the issue Bob was having in the other comment. You need to be adding the key to the installation to be able to update.
      What version of linux are you using on the container? Assuming you followed my guide from scratch, did you manage to successfully complete this command? I pasted the command below as one complete line.

      echo \
      “deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \
      $(lsb_release -cs) stable” | tee /etc/apt/sources.list.d/docker.list > /dev/null

      This adds the docker keyring (gpg) to your list of resources. Copy those three lines above and paste them in as one. I think you should be good. Do come back if not!

      1. Hi,

        after apt-get update i get:

        Hit:1 http://security.debian.org buster/updates InRelease
        Hit:2 http://deb.debian.org/debian buster InRelease
        Get:3 https://download.docker.com/linux/debian buster InRelease [54.0 kB]
        Ign:4 http://archive.turnkeylinux.org/debian buster-security InRelease
        Ign:5 http://archive.turnkeylinux.org/debian buster InRelease
        Hit:6 http://archive.turnkeylinux.org/debian buster-security Release
        Hit:7 http://archive.turnkeylinux.org/debian buster Release
        Err:3 https://download.docker.com/linux/debian buster InRelease
        The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY 7EA0A9C3F273FCD8
        Reading package lists… Done
        W: GPG error: https://download.docker.com/linux/debian buster InRelease: The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY 7EA0A9C3F273FCD8
        E: The repository ‘https://download.docker.com/linux/debian buster InRelease’ is not signed.
        N: Updating from such a repository can’t be done securely, and is therefore disabled by default.
        N: See apt-secure(8) manpage for repository creation and user configuration details

        or

        E: Malformed entry 1 in list file /etc/apt/sources.list.d/docker.list (Component)
        E: The list of sources could not be read.

        I indeed followed your instructions and have the latest turnkey linux version.

        1. Apologies, I just saw a command had been left out… I suggest to run : apt-get remove docker docker-engine docker.io containerd runc
          And then follow through the instructions again in the blog. You should be able to get it running now (a curl command was left out previously) Sorry!

  3. Unfortunately I’m unable to install docker following your guide 🙁

    root@docker ~# apt-get install docker-ce docker-ce-cli containerd.io
    Reading package lists… Done
    Building dependency tree
    Reading state information… Done
    Package docker-ce is not available, but is referred to by another package.
    This may mean that the package is missing, has been obsoleted, or
    is only available from another source

    E: Package ‘docker-ce’ has no installation candidate
    E: Unable to locate package docker-ce-cli
    E: Unable to locate package containerd.io
    E: Couldn’t find any package by glob ‘containerd.io’
    E: Couldn’t find any package by regex ‘containerd.io’

    1. Hi Geir, unfortunately, one command was left out! Try again, run this command apt-get remove docker docker-engine docker.io containerd runc
      And then then try again to see if it completes now. I just went through on a fresh container copying only commands from the blog and it works.

      1. I’m sorry, still fails here, it seems to fail already at that curl command for me.
        Unfortunately I’m at the linux-level where I can only follow commands and have no knowledge to understand why/what is failing, so I attemted to follow through with the commands anyway.

        root@docker ~# curl -fsSL https://download.docker.com/linux/debian/gpg | gpg –dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
        gpg: WARNING: no command supplied. Trying to guess what you mean …
        usage: gpg [options] [filename]
        (23) Failed writing body
        root@docker ~# echo \
        b [arch> deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \
        ble” | > $(lsb_release -cs) stable” | tee /etc/apt/sources.list.d/docker.list > /dev/null
        root@docker ~# apt-get update
        Get:1 https://download.docker.com/linux/debian buster InRelease [54.0 kB]
        Hit:2 http://security.debian.org buster/updates InRelease
        Err:1 https://download.docker.com/linux/debian buster InRelease
        The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY 7EA0A9C3F273FCD8
        Ign:3 http://archive.turnkeylinux.org/debian buster-security InRelease
        Hit:4 http://deb.debian.org/debian buster InRelease
        Ign:5 http://archive.turnkeylinux.org/debian buster InRelease
        Hit:6 http://archive.turnkeylinux.org/debian buster-security Release
        Hit:7 http://archive.turnkeylinux.org/debian buster Release
        Reading package lists… Done
        W: GPG error: https://download.docker.com/linux/debian buster InRelease: The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY 7EA0A9C3F273FCD8
        E: The repository ‘https://download.docker.com/linux/debian buster InRelease’ is not signed.
        N: Updating from such a repository can’t be done securely, and is therefore disabled by default.
        N: See apt-secure(8) manpage for repository creation and user configuration details.
        root@docker ~# apt-get install docker-ce docker-ce-cli containerd.io
        Reading package lists… Done
        Building dependency tree
        Reading state information… Done
        Package docker-ce is not available, but is referred to by another package.
        This may mean that the package is missing, has been obsoleted, or
        is only available from another source

        E: Package ‘docker-ce’ has no installation candidate
        E: Unable to locate package docker-ce-cli
        E: Unable to locate package containerd.io
        E: Couldn’t find any package by glob ‘containerd.io’
        E: Couldn’t find any package by regex ‘containerd.io’
        root@docker ~#

  4. Here are some corrections I figured out.
    Here are the right commands:

    curl -fsSL https://download.docker.com/linux/debian/gpg | gpg –dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

    the next one was:

    echo \
    deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \
    $(lsb_release -cs) stable | tee /etc/apt/sources.list.d/docker.list > /dev/null

    and the last one:

    docker run -d -p 8000:8000 -p 9000:9000 -name=portainer -restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce

    1. thanks, just note that name and restart need a double dash in front:

      docker run -d -p 8000:8000 -p 9000:9000 –name=portainer –restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce

  5. After running:
    curl -fsSL https://download.docker.com/linux/debian/gpg | gpg –dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
    and then:
    apt-get update
    I get the following error:
    E: Type ‘“deb’ is not known on line 1 in source list /etc/apt/sources.list.d/docker.list
    E: The list of sources could not be read.

  6. Any plan to write a detailed guide for frigate in proxmox along with home assistant?
    Thanks

  7. Hi,

    any known way that default motherboard Bluetooth will work this way to discover devices?

Leave a Reply