# Proxmox

best open source cluster os for homelab server

# Lần đầu Install Configuration for Proxmox

Chỉnh sữa file: **/etc/apt/sources.list**

```
nano /etc/apt/sources.list
```

```
deb http://ftp.debian.org/debian bookworm main contrib

deb http://ftp.debian.org/debian bookworm-updates main contrib

# security updates
deb http://security.debian.org bookworm-security main contrib

# not for production use
deb http://download.proxmox.com/debian buster pve-no-subscriptionOA

```

Chỉnh sửa file dành cho proxmox &gt;8.0: /etc/apt/sources.list.d/pve-no-enterprise.list

```
nano /etc/apt/sources.list.d/pve-no-enterprise.list
```

```
# not for production use
deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription
```

Kế tiếp comment out cái dòng enterprise update list ở file: /etc/apt/sources.list.d/pve-enterprise.list

```
nano /etc/apt/sources.list.d/pve-enterprise.list
```

```
#deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise
```

Chạy các update sau:

```
apt-get update
apt dist-upgrade
```

nhấn y để chấp nhận update

sau đó reboot system.

```
reboot
```

IOMMU ([PCI Passthrough](https://pve.proxmox.com/wiki/PCI_Passthrough))

sửa file grub dành cho intel hay amd iommu:

```
nano /etc/default/grub
```

nếu đang xài amd thì sửa intel\_iommu thành **amd\_iommu**

```
#GRUB_CMDLINE_LINUX_DEFAULT="quiet"
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on"
```

save file lại và update grub

Sửa file /etc/modules

```
# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.
# Parameters can be specified after the module name.

vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd

```

```
update-initramfs -u -k all
```

```
reboot
```

update DNS nameserver nếu đang xài pi hole.

[![image.png](https://wiki.kyluat.com/uploads/images/gallery/2023-11/scaled-1680-/PIWimage.png)](https://wiki.kyluat.com/uploads/images/gallery/2023-11/PIWimage.png)

Kế tiếp: tạo cloud image

# Tạo Cloud Image Ubuntu cho Proxmox Node

Download Current Ubuntu Cloud Image:

```
wget https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img
```

Tạo new virtual machine:

8000: là Virtual Machine Id trên proxmox  
ubuntu-cloud: là tên của vm

```
qm create 8004 --memory 8192 --core 4 --name ubuntu-cloud --net0 virtio,bridge=vmbr0
```

Import disk vào local-lvm storage

```
qm importdisk 8004 jammy-server-cloudimg-amd64.img local-lvm
```

Attach the new disk to the vm as a scsi drive on the scsi controller

```
qm set 8004 --scsihw virtio-scsi-pci --scsi0 local-lvm:vm-8004-disk-0
```

8004: là vmid của cloud image. ở trên có 2 id 8004 cần sửa.

Add cloud init drive

```
qm set 8004 --ide2 local-lvm:cloudinit
```

Make the cloud init drive bootable and restrict BIOS to boot from disk only

```
qm set 8004 --boot c --bootdisk scsi0
```

Add serial console

```
qm set 8004 --serial0 socket --vga serial0
```

Create template.

```
qm template 8004
```

Clone template.

```
qm clone 8004 135 --name yoshi --full
```

- 135 là id mới
- 8004 là vmid của cloud image

Scale disk

```
qm resize 135 scsi0 +45G
```

Setting Up Ubuntu VM:

[https://technotim.live/posts/fist-13-things-linux/](https://technotim.live/posts/fist-13-things-linux/)

```
sudo apt-get update -y
sudo apt-get upgrade -y
sudo apt-get install qemu-guest-agent -y

sudo dpkg-reconfigure --priority=low unattended-upgrades

sudo nano /etc/ssh/sshd_config

PasswordAuthentication no
ChallengeResponseAuthentication no

sudo nano /etc/systemd/timesyncd.conf

[Time]
NTP=192.168.1.1
```

Disable root login:

```
sudo passwd -l root
```

# Tạo Wake On Lan cho server node Proxmox

- Vào bios enable WOL
- ssh vào node, chạy các command sau:

```
sudo apt install ethtool -y
ip addr
sudo ethtool eno1
sudo ethtool -s eno1 wol g
sudo nano /etc/network/interfaces
```

Paste vào cuối trang:

```
ethernet-wol g
```

Save và shutdown

Test thử và check:

```
sudo ethtool eno1
```

source: [https://i12bretro.github.io/tutorials/0608.html](https://i12bretro.github.io/tutorials/0608.html)

# Proxmox Problems and Solutions

#### No quorum? Undefined Code: 1006

Gắn màn hình vào máy và reboot lại sau đó login root, nhấn command sau cho không hiện error là được

> <div class="bbCodeBlock-content"><div class="bbCodeBlock-expandContent js-expandContent ">  
> </div><div class="bbCodeBlock-expandContent js-expandContent ">pvecm expect 1</div><div class="bbCodeBlock-expandContent js-expandContent ">pvecm expect 2</div><div class="bbCodeBlock-expandContent js-expandContent ">pvecm expect 3</div><div class="bbCodeBlock-expandContent js-expandContent ">  
> </div></div>

# Install và cấu hình proxmox

Best Tutorial from Techno Tim

[https://www.youtube.com/watch?v=GoZaMgEgrHw&amp;list=PL8cwSAAaP9W37Vnxkw6\_\_sshVY-XohWNm](https://www.youtube.com/watch?v=GoZaMgEgrHw&list=PL8cwSAAaP9W37Vnxkw6__sshVY-XohWNm)

Note:

1. server disk space sẽ xài tầm 6 GB nên để 10 GB là đủ

# Vấn đề về networking với proxmox sau khi cài NIC 10Gib

Sau khi Khải cài card 10 gb vào máy thu xong thì gặp vấn đề mất mạng vì proxmox không tự detect được network card name mới.

Cách khắc phục: update lại network name mới cho đúng

Sử dụng command sau để mò xem network name nào hoạt động:

```
nano /etc/network/interfaces
```

[![image.png](https://wiki.kyluat.com/uploads/images/gallery/2024-05/scaled-1680-/4KLimage.png)](https://wiki.kyluat.com/uploads/images/gallery/2024-05/4KLimage.png)

Hiện tại network name của mình là enp1s0. Tùy theo config cũ nó sẽ có số thứ tự naming riêng

```
ethtool enp1s0
```

[![image.png](https://wiki.kyluat.com/uploads/images/gallery/2024-05/scaled-1680-/eanimage.png)](https://wiki.kyluat.com/uploads/images/gallery/2024-05/eanimage.png)

Chúng ta có thể thay đổi enp1s0 thành enp2s0 ... cho tới enp20s0 . nếu như link đánh command ethtool enp2s0 mà nó hiện ra bảng na ná như hình thì nó đang có link ( hoạt động ). Tức là ta có thể sử dụng name đó cho network interfaces.

3\. command để list link nào còn hoạt động:

```
ip link show
```

[![image.png](https://wiki.kyluat.com/uploads/images/gallery/2024-05/scaled-1680-/UgYimage.png)](https://wiki.kyluat.com/uploads/images/gallery/2024-05/UgYimage.png)

Thử chỉnh sửa /etc/network/interfaces với cái name nào mà còn up sau đó nhớ đánh command để restart network lại

```
systemctl restart networking
```

Sau khi chỉnh sửa network name enp1s0 và restart networking xong thì cứ việc ping tới router, nếu router chịu trả về response thì đạt nhé:

```
ping 192.168.1.1
```

192.168.1.1 là ip của router nhà mình

[![image.png](https://wiki.kyluat.com/uploads/images/gallery/2024-05/scaled-1680-/XyYimage.png)](https://wiki.kyluat.com/uploads/images/gallery/2024-05/XyYimage.png)

Gg gl hf

# Giảm dung lượng ổ đĩa - Reduce ( Shrink ) VM Disk Space in Proxmox

Ref: [https://forum.proxmox.com/threads/decrease-a-vm-disk-size.122430/](https://forum.proxmox.com/threads/decrease-a-vm-disk-size.122430/)

**Clone hay backup VM trước** sau đó test thử:

Hai command cơ bản:

```
lvm lvreduce -L -99g pve/vm-114-disk-0
qm rescan
```

# Tạo Alpine Cloud Image với Proxmox

ssh vào proxmox node

```
qm create 8006 --memory 8192 --core 4 --name alpine-cloud --net0 virtio,bridge=vmbr0
```

read more: [https://github.com/red-lichtie/alpine-cloud-init](https://github.com/red-lichtie/alpine-cloud-init)

Vào download page: [https://alpinelinux.org/downloads/](https://alpinelinux.org/downloads/)

Download file iso về: [https://dl-cdn.alpinelinux.org/alpine/v3.20/releases/x86\_64/alpine-virt-3.20.1-x86\_64.iso](https://dl-cdn.alpinelinux.org/alpine/v3.20/releases/x86_64/alpine-virt-3.20.1-x86_64.iso)

# Tạo Cloud Image cho tất cả các loại Linux OS với shell script trên proxmox

Create Cloud Template Shell:

Nguồn từ bạn [meramsey](https://gist.github.com/meramsey), link: [https://gist.github.com/meramsey/aa759614cb5e387d8b88a0adfe77cc1d](https://gist.github.com/meramsey/aa759614cb5e387d8b88a0adfe77cc1d)

create-cloud-template.sh

```
#!/bin/bash
set -o errexit

clear
printf "\n*** This script will download a cloud image and create a Proxmox VM template from it. ***\n\n"

### HOW TO USE
### Pre-req:
### - run on a Proxmox 6 server
### - a dhcp server should be active on vmbr1
###
### - fork the gist and adapt the defaults (especially SSHKEY) as needed
### - download latest version of the script:
###   curl wget https://gist.githubusercontent.com/chriswayg/43fbea910e024cbe608d7dcb12cb8466/raw/create-cloud-template.sh > /usr/local/bin/create-cloud-template.sh && chmod -v +x /usr/local/bin/create-cloud-template.sh
### - (optionally) prepare a cloudinit user-config.yml in the working directory
###   this could be copied and modified from the cloudinit user dump at the end of this script
### - run the script:
###   $ create-cloud-template.sh
### - clone the finished template from the Proxmox GUI and test
###
### NOTES:
### - links to cloud images:
###   Directory: https://docs.openstack.org/image-guide/obtain-images.html
###   Debian http://cdimage.debian.org/cdimage/openstack/
###   Ubuntu http://cloud-images.ubuntu.com/
###   CentOS: http://cloud.centos.org/centos/7/images/
###   CentOS: https://cloud.centos.org/centos/8/x86_64/images/
###   AlmaLinux: https://repo.almalinux.org/almalinux/8/cloud/x86_64/images/
###   Fedora: https://alt.fedoraproject.org/cloud/
###   SUSE 15 SP1 JeOS: https://download.suse.com/Download?buildid=OE-3enq3uys~
###   CirrOS http://download.cirros-cloud.net/
###   CoreOS (EOL 05.2020): https://stable.release.core-os.net/amd64-usr/current/
###   Flatcar (CoreOS fork): https://stable.release.flatcar-linux.net/amd64-usr/current/
###   Gentoo: http://gentoo.osuosl.org/experimental/amd64/openstack
###   Arch (also Gentoo): https://linuximages.de/openstack/arch/
###   Alpine: https://github.com/chriswayg/packer-qemu-cloud/
###   RancherOS: https://github.com/rancher/os/releases (also includes Proxmox iso version)
###
### - most links will download the latest current (stable) version of the OS
### - older cloud-init versions do not support hashed passwords

## TODO
## - verify authenticity of downloaded images using hash or GPG

printf "* Available templates to generate:\n 2) Debian 9\n 3) Debian 10\n 4) Ubuntu 18.04\n 5) Ubuntu 20.04\n 6) Ubuntu 20.10\n 7) Ubuntu 21.04\n 8) Centos 7\n 9) Centos 8\n 10) AlmaLinux 8\n 11) CoreOS/Flatcar\n 12) Arch\n 13) Alpine 3.11\n 14) RancherOS 1.5.5\n\n"
read -p "* Enter number of distro to use: " OSNR

# defaults which are used for most templates
RESIZE=+30G
MEMORY=2048
BRIDGE=vmbr1
USERCONFIG_DEFAULT=none # cloud-init-config.yml
CITYPE=nocloud
SNIPPETSPATH=/var/lib/vz/snippets
SSHKEY=~/.ssh/2019_id_rsa.pub # ~/.ssh/id_rsa.pub
NOTE=""

case $OSNR in

  2)
    OSNAME=debian9
    VMID_DEFAULT=51100
    read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID
    VMID=${VMID:-$VMID_DEFAULT}
    VMIMAGE=debian-9-openstack-amd64.qcow2
    NOTE="\n## Default user is 'debian'\n## NOTE: Setting a password via cloud-config does not work.\n"
    printf "$NOTE\n"
    wget -P /tmp -N https://cdimage.debian.org/cdimage/openstack/current-9/$VMIMAGE
    ;;

  3)
    OSNAME=debian10
    VMID_DEFAULT=51200
    read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID
    VMID=${VMID:-$VMID_DEFAULT}
    VMIMAGE=debian-10-openstack-amd64.qcow2
    NOTE="\n## Default user is 'debian'\n"
    printf "$NOTE\n"
    wget -P /tmp -N https://cdimage.debian.org/cdimage/openstack/current-10/$VMIMAGE
    ;;

  4)
    OSNAME=ubuntu1804
    VMID_DEFAULT=52000
    read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID
    VMID=${VMID:-$VMID_DEFAULT}
    VMIMAGE=bionic-server-cloudimg-amd64.img
    NOTE="\n## Default user is 'ubuntu'\n"
    printf "$NOTE\n"
    wget -P /tmp -N https://cloud-images.ubuntu.com/bionic/current/$VMIMAGE
    ;;

  5)
    OSNAME=ubuntu2004
    VMID_DEFAULT=52004
    read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID
    VMID=${VMID:-$VMID_DEFAULT}
    VMIMAGE=focal-server-cloudimg-amd64.img
    NOTE="\n## Default user is 'ubuntu'\n"
    printf "$NOTE\n"
    wget -P /tmp -N https://cloud-images.ubuntu.com/focal/current/$VMIMAGE
    ;;
    
  6)
    OSNAME=ubuntu2010
    VMID_DEFAULT=52010
    read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID
    VMID=${VMID:-$VMID_DEFAULT}
    VMIMAGE=groovy-server-cloudimg-amd64.img
    NOTE="\n## Default user is 'ubuntu'\n"
    printf "$NOTE\n"
    wget -P /tmp -N https://cloud-images.ubuntu.com/groovy/current/$VMIMAGE
    ;;
 
   7)
    OSNAME=ubuntu2104
    VMID_DEFAULT=52104
    read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID
    VMID=${VMID:-$VMID_DEFAULT}
    VMIMAGE=hirsute-server-cloudimg-amd64.img
    NOTE="\n## Default user is 'ubuntu'\n"
    printf "$NOTE\n"
    wget -P /tmp -N https://cloud-images.ubuntu.com/hirsute/current/$VMIMAGE
    ;;

  8)
    OSNAME=centos7
    VMID_DEFAULT=53100
    read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID
    VMID=${VMID:-$VMID_DEFAULT}
    RESIZE=+24G
    VMIMAGE=CentOS-7-x86_64-GenericCloud.qcow2
    NOTE="\n## Default user is 'centos'\n## NOTE: CentOS ignores hostname config.\n#  use 'hostnamectl set-hostname centos7-cloud' inside VM\n"
    printf "$NOTE\n"
    wget -P /tmp -N http://cloud.centos.org/centos/7/images/$VMIMAGE
    ;;

  9)
    OSNAME=centos8
    VMID_DEFAULT=53108
    read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID
    VMID=${VMID:-$VMID_DEFAULT}
    RESIZE=+24G
    VMIMAGE=CentOS-8-GenericCloud-8.4.2105-20210603.0.x86_64.qcow2
    NOTE="\n## Default user is 'centos'\n## NOTE: CentOS ignores hostname config.\n#  use 'hostnamectl set-hostname centos8-cloud' inside VM\n"
    printf "$NOTE\n"
    wget -P /tmp -N https://cloud.centos.org/centos/8/x86_64/images/$VMIMAGE
    ;;

  10)
    OSNAME=almalinux8
    VMID_DEFAULT=53208
    read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID
    VMID=${VMID:-$VMID_DEFAULT}
    RESIZE=+24G
    VMIMAGE=AlmaLinux-8-GenericCloud-latest.x86_64.qcow2
    NOTE="\n## Default user is 'almalinux'\n"
    printf "$NOTE\n"
    wget -P /tmp -N https://repo.almalinux.org/almalinux/8/cloud/x86_64/images/$VMIMAGE
    ;;

  11)
    # - Proxmox creates a configdrive with the option: 'manage_etc_hosts: true'
    #   which causes an error in 'user-configdrive.service':
    #   'Failed to apply cloud-config: Invalid option to manage_etc_hosts'
    #   There is no problem, when supplying a compatible 'user-config.yml'.
    # - CoreOS needs 'configdrive2'
    # - CoreOS is End of Life in 05.2020, use Flatcar instead
    # https://github.com/coreos/coreos-cloudinit/blob/master/Documentation/config-drive.md
    #
    # OSNAME=coreos
    # VMID_DEFAULT=54600
    # read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID
    # VMID=${VMID:-$VMID_DEFAULT}
    # RESIZE=+24G
    # VMIMAGE=coreos_production_qemu_image.img.bz2
    # CITYPE=configdrive2
    # NOTE="\n## Default user is 'core'\n## NOTE: In CoreOS, setting a password via cloud-config does not seem to work!\n"
    # printf "$NOTE\n"
    # wget -P /tmp -N https://stable.release.core-os.net/amd64-usr/current/$VMIMAGE
    OSNAME=flatcar
    VMID_DEFAULT=54600
    read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID
    VMID=${VMID:-$VMID_DEFAULT}
    RESIZE=+24G
    VMIMAGE=flatcar_production_qemu_image.img.bz2
    CITYPE=configdrive2
    NOTE="\n## Default user is 'coreos'\n## NOTE: Setting a password via cloud-config does not work.\n"
    printf "$NOTE\n"
    wget -P /tmp -N https://stable.release.flatcar-linux.net/amd64-usr/current/$VMIMAGE
    ;;

  12)
    OSNAME=arch
    VMID_DEFAULT=54200
    read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID
    VMID=${VMID:-$VMID_DEFAULT}
    RESIZE=+29G
    VMIMAGE=arch-openstack-LATEST-image-bootstrap.qcow2
    NOTE="\n## Default user is 'arch'\n## NOTE: Setting a password via cloud-config does not work.\n#  Resizing does not happen automatically inside the VM\n"
    printf "$NOTE\n"
    wget -P /tmp -N https://linuximages.de/openstack/arch/$VMIMAGE
    ;;

  13)
    OSNAME=alpine311
    VMID_DEFAULT=54000
    read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID
    VMID=${VMID:-$VMID_DEFAULT}
    VMIMAGE=alpine-311-cloudimg-amd64.qcow2
    NOTE="\n## Default user is 'alpine'\n## NOTE: Cloud-init on Alpine 3.11 is not able to apply network config.\n#  Setting a password via cloud-config does not work.\n#  CHANGE the default root passwword (root can only login via console).\n"
    printf "$NOTE\n"
    wget -P /tmp -N https://github.com/chriswayg/packer-proxmox-templates/releases/download/v1.6/$VMIMAGE
    #cp -v /root/$VMIMAGE /tmp/ # for local testing
    ;;

  14)
    OSNAME=rancheros
    VMID_DEFAULT=54400
    read -p "Enter a VM ID for $OSNAME [$VMID_DEFAULT]: " VMID
    VMID=${VMID:-$VMID_DEFAULT}
    VMIMAGE=rancheros-openstack.img
    CITYPE=configdrive2
    NOTE="\n## Default user is 'rancher'\n## NOTE: Setting a password via cloud-config does not work.\n#  RancherOS does autologin on console.\n"
    printf "$NOTE\n"
    wget -P /tmp -N https://github.com/rancher/os/releases/download/v1.5.5/$VMIMAGE
    ;;

  *)
    printf "\n** Unknown OS number. Please use one of the above!\n"
    exit 0
    ;;
esac

[[ $VMIMAGE == *".bz2" ]] \
    && printf "\n** Uncompressing image (waiting to complete...)\n" \
    && bzip2 -d --force /tmp/$VMIMAGE \
    && VMIMAGE=$(echo "${VMIMAGE%.*}") # remove .bz2 file extension from file name

# TODO: could prompt for the VM name
printf "\n** Creating a VM with $MEMORY MB using network bridge $BRIDGE\n"
qm create $VMID --name $OSNAME-cloud --memory $MEMORY --net0 virtio,bridge=$BRIDGE

printf "\n** Importing the disk in qcow2 format (as 'Unused Disk 0')\n"
qm importdisk $VMID /tmp/$VMIMAGE local -format qcow2

printf "\n** Attaching the disk to the vm using VirtIO SCSI\n"
qm set $VMID --scsihw virtio-scsi-pci --scsi0 /var/lib/vz/images/$VMID/vm-$VMID-disk-0.qcow2

printf "\n** Setting boot and display settings with serial console\n"
qm set $VMID --boot c --bootdisk scsi0 --serial0 socket --vga serial0

printf "\n** Using a dhcp server on $BRIDGE (or change to static IP)\n"
qm set $VMID --ipconfig0 ip=dhcp
#This would work in a bridged setup, but a routed setup requires a route to be added in the guest
#qm set $VMID --ipconfig0 ip=10.10.10.222/24,gw=10.10.10.1

printf "\n** Creating a cloudinit drive managed by Proxmox\n"
qm set $VMID --ide2 local:cloudinit

printf "\n** Specifying the cloud-init configuration format\n"
qm set $VMID --citype $CITYPE

printf "#** Made with create-cloud-template.sh - https://gist.github.com/chriswayg/43fbea910e024cbe608d7dcb12cb8466\n" >> /etc/pve/nodes/proxmox/qemu-server/$VMID.conf

## TODO: Also ask for a network configuration. Or create a config with routing for a static IP
printf "\n*** The script can add a cloud-init configuration with users and SSH keys from a file in the current directory.\n"
read -p "Supply the name of the cloud-init-config.yml (this will be skipped, if file not found) [$USERCONFIG_DEFAULT]: " USERCONFIG
USERCONFIG=${USERCONFIG:-$USERCONFIG_DEFAULT}
if [ -f $PWD/$USERCONFIG ]
then
    # The cloud-init user config file overrides the user settings done elsewhere
    printf "\n** Adding user configuration\n"
    cp -v $PWD/$USERCONFIG $SNIPPETSPATH/$VMID-$OSNAME-$USERCONFIG
    qm set $VMID --cicustom "user=local:snippets/$VMID-$OSNAME-$USERCONFIG"
    printf "#* cloud-config: $VMID-$OSNAME-$USERCONFIG\n" >> /etc/pve/nodes/proxmox/qemu-server/$VMID.conf
else
    # The SSH key should be supplied either in the cloud-init config file or here
    printf "\n** Skipping config file, as none was found\n\n** Adding SSH key\n"
    qm set $VMID --sshkey $SSHKEY
    printf "\n"
    read -p "Supply an optional password for the default user (press Enter for none): " PASSWORD
    [ ! -z "$PASSWORD" ] \
        && printf "\n** Adding the password to the config\n" \
        && qm set $VMID --cipassword $PASSWORD \
        && printf "#* a password has been set for the default user\n" >> /etc/pve/nodes/proxmox/qemu-server/$VMID.conf
    printf "#- cloud-config used: via Proxmox\n" >> /etc/pve/nodes/proxmox/qemu-server/$VMID.conf
fi

# The NOTE is added to the Summary section of the VM (TODO there seems to be no 'qm' command for this)
printf "#$NOTE\n" >> /etc/pve/nodes/proxmox/qemu-server/$VMID.conf

printf "\n** Increasing the disk size\n"
qm resize $VMID scsi0 $RESIZE

printf "\n*** The following cloud-init configuration will be used ***\n"
printf "\n-------------  User ------------------\n"
qm cloudinit dump $VMID user
printf "\n-------------  Network ---------------\n"
qm cloudinit dump $VMID network

# convert the vm into a template (TODO make this optional)
qm template $VMID

printf "\n** Removing previously downloaded image file\n\n"
rm -v /tmp/$VMIMAGE

printf "$NOTE\n\n"
```

# Tạo Proxmox VM Cloud Image Centos 8 với Shell

SSH vào Node nào muốn install

Sau đây là ví dụ để install Centos 8 cloud image: [https://cloud.centos.org/centos/8/x86\_64/images/](https://cloud.centos.org/centos/8/x86_64/images/)

file: [CentOS-8-GenericCloud-8.4.2105-20210603.0.x86\_64.qcow2](https://cloud.centos.org/centos/8/x86_64/images/CentOS-8-GenericCloud-8.4.2105-20210603.0.x86_64.qcow2)

Download file cloud về và connect ssh vào máy node proxmox

Mình xài IDM download cho lẹ. bạn có thể xài shell script bên dưới với wget.

Run Shell:

8009 là số thứ tự VM mới ( coi chừng bị trùng ). Thay đổi để tạo số thứ tự bạn mong muốn. càng cao thì càng nằm dưới list view của proxmox ui.

```
#!/usr/bin/env bash
wget -O CentOS-8-GenericCloud-8.4.2105-20210603.0.x86_64.qcow2 https://cloud.centos.org/centos/8/x86_64/images/CentOS-8-GenericCloud-8.4.2105-20210603.0.x86_64.qcow2
qm create 8009 --name centos8-cloud --net0 virtio,bridge=vmbr0
qm importdisk 8009 CentOS-8-GenericCloud-8.4.2105-20210603.0.x86_64.qcow2 local-lvm
qm set 8009 --scsihw virtio-scsi-pci --scsi0 local-lvm:vm-8009-disk-0
qm set 8009 --ide2 local-lvm:cloudinit
qm set 8009 --boot c --bootdisk scsi0
qm set 8009 --serial0 socket --vga serial0
```

Nguồn tại đây: [https://gist.github.com/OdracirJC/5e6fd420af44d992ba76296050c4ceda](https://gist.github.com/OdracirJC/5e6fd420af44d992ba76296050c4ceda)

Clone Template với mode Full Clone ( nhớ là không phải linked clone )

Sau khi tạo chạy thử xong bạn cần update repos urls

```bash
cd /etc/yum.repos.d/
sudo sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
sudo sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
sudo yum update -y
```

rồi sau đó:

```
sudo yum install qemu-guest-agent
```

shutdown vm

vào options &gt; qemu guest agent enable giống như hình

[![image.png](https://wiki.kyluat.com/uploads/images/gallery/2024-06/scaled-1680-/RgJimage.png)](https://wiki.kyluat.com/uploads/images/gallery/2024-06/RgJimage.png)

Chỉnh sudo không đánh password:

```
sudo visudo
```

thêm vào dòng sau dưới root ( đổi username thành tên username của bạn )

```
USERNAME ALL=(ALL)       NOPASSWD: ALL
```

[![image.png](https://wiki.kyluat.com/uploads/images/gallery/2024-06/scaled-1680-/m0bimage.png)](https://wiki.kyluat.com/uploads/images/gallery/2024-06/m0bimage.png)

tương tự với CENTOS 7:

```
qm create 8010 --name centos7-cloud --net0 virtio,bridge=vmbr0
qm importdisk 8010 CentOS-7-x86_64-GenericCloud.qcow2 local-lvm
qm set 8010 --scsihw virtio-scsi-pci --scsi0 local-lvm:vm-8010-disk-0
qm set 8010 --ide2 local-lvm:cloudinit
qm set 8010 --boot c --bootdisk scsi0
qm set 8010 --serial0 socket --vga serial0
```

**Lưu ý:** user mặc định là centos. sử dụng "hostnamectl set-hostname ABC\_VM\_NAME" bên trong vm để config hostname

```
hostnamectl set-hostname ABC_VM_NAME
```

# Setup Proxmox Node trên Hetzner Dedicated Server

Tóm tắt những gì sẽ làm:

1. Vào [Hetzner ](https://go.kyluat.com/hetzner), chọn dedicated server rẻ rẻ để bắt đầu, mình test với AX 42 (có hổ trợ Virtualization, INTEL-VT) do lúc này đang có promotion $0 setup fee để test và chuyển website applications từ shared hosting sang dedicated server luôn
2. Đăng ký xong thì bạn vào email lấy thông tin ssh đăng nhập
3. Download [Putty](https://go.kyluat.com/iZ0FZ), cấu hình ssh và SSH Tunnel để kết nối server đồng thời cài setup OS qua [RealVNC Viewer](https://go.kyluat.com/CX9MJ)

##### Chọn Dedicated Server nào phù hợp?

Performance Hetzner Servers: [https://go.kyluat.com/M8oBN](https://go.kyluat.com/M8oBN)

Đăng ký xong:

1. Xem email, lưu thông tin tài khoản lại
2. vào robot hetzner xem thử: [https://go.kyluat.com/hq1gs](https://go.kyluat.com/hq1gs)
3. Lưu lại thông tin server như public ip, gateway ip, netmask để tiện config
4. Chỉnh firewall port 22,8006,5900

Download Putty

Config Putty với SSH tunnel

Source Port: 9090 (để bất kỳ port nào để connect realvnc viewer với port này trên máy)

Destination: xxx.xxx.xxx.xxx:5900 ( địa chỉ public ip của server và port default vnc là 5900 )

Giải thích thêm: thì từ đây, sau khi đã connected với ssh server khi xài vnc thì chỉ cần đánh address localhost:9090 thì nó sẽ connect tới vnc server của server

[![image.png](https://wiki.kyluat.com/uploads/images/gallery/2024-06/scaled-1680-/fMPimage.png)](https://wiki.kyluat.com/uploads/images/gallery/2024-06/fMPimage.png)

[![image.png](https://wiki.kyluat.com/uploads/images/gallery/2024-06/scaled-1680-/yd7image.png)](https://wiki.kyluat.com/uploads/images/gallery/2024-06/yd7image.png)

Bước khó khăn cơ bản đã qua.

Mới bạn làm theo anh này: [https://www.youtube.com/watch?v=pZBLYTr4qzA](https://www.youtube.com/watch?v=pZBLYTr4qzA)

Download [Proxmox Iso image](https://www.proxmox.com/en/downloads/proxmox-virtual-environment/iso), rename thành pve.iso

Kết quả:

[![image.png](https://wiki.kyluat.com/uploads/images/gallery/2024-06/scaled-1680-/vFCimage.png)](https://wiki.kyluat.com/uploads/images/gallery/2024-06/vFCimage.png)

[![image.png](https://wiki.kyluat.com/uploads/images/gallery/2024-06/scaled-1680-/LROimage.png)](https://wiki.kyluat.com/uploads/images/gallery/2024-06/LROimage.png)

Thêm:

Mở port 9001 từ địa chỉ AAA của Node tới địa chỉ BBB của VM

```
sudo iptables -t nat -A PREROUTING -p tcp -d AAA.AAA.AAA.AAA --dport 9001 -i vmbr0 -j DNAT --to-destination BBB.BBB.BBB.BBB:9001
```

# Frigate & Google Coral and Proxmox VM

Bought items:

[![image.png](https://wiki.kyluat.com/uploads/images/gallery/2025-06/scaled-1680-/image.png)](https://wiki.kyluat.com/uploads/images/gallery/2025-06/image.png)

Good Youtube Tutorial: [https://www.youtube.com/watch?v=zKk9dnAp8FM](https://www.youtube.com/watch?v=zKk9dnAp8FM)

In Proxmox Node:

```shell
lsusb
```

root@orange:/etc/pve/lxc# lsusb  
Bus 008 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub  
Bus 007 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub  
Bus 006 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub  
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub  
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub  
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub  
Bus 002 Device 003: ID <span style="color: rgb(22, 145, 121);">**18d1:9302**</span> Google Inc.   
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub  
Bus 001 Device 002: ID 8087:0029 Intel Corp. AX200 Bluetooth  
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

#### Setup Ubuntu VM and Add USB device:

[![image.png](https://wiki.kyluat.com/uploads/images/gallery/2025-05/scaled-1680-/image.png)](https://wiki.kyluat.com/uploads/images/gallery/2025-05/image.png)

Restart VM

run lsusb to see if the vm has the USB

[![image.png](https://wiki.kyluat.com/uploads/images/gallery/2025-05/scaled-1680-/MHMimage.png)](https://wiki.kyluat.com/uploads/images/gallery/2025-05/MHMimage.png)

Install Docker and Portainer

Add this Docker Compose to install frigate

```yaml
version: "3.9"
services:
  frigate:
    
    container_name: frigate
    privileged: true # this may not be necessary for all setups
    restart: unless-stopped
    stop_grace_period: 30s # allow enough time to shut down the various services
    image: ghcr.io/blakeblackshear/frigate:stable
    shm_size: "512mb" # update for your cameras based on calculation above
    devices:
      - /dev/bus/usb:/dev/bus/usb # Passes the USB Coral, needs to be modified for other versions
      - /dev/apex_0:/dev/apex_0 # Passes a PCIe Coral, follow driver instructions here https://coral.ai/docs/m2/get-started/#2a-on-linux
      #- /dev/video11:/dev/video11 # For Raspberry Pi 4B
      #- /dev/dri/renderD128:/dev/dri/renderD128 # For intel hwaccel, needs to be updated for your hardware
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /mnt/portainer2/frigate/config:/config
      - /mnt/portainer2/frigate/storage:/media/frigate
      - type: tmpfs # Optional: 1GB of memory, reduces SSD/SD Card wear
        target: /tmp/cache
        tmpfs:
          size: 1000000000
    ports:
      - "8971:8971"
      - "5000:5000" # Internal unauthenticated access. Expose carefully.
      - "8554:8554" # RTSP feeds
      - "8555:8555/tcp" # WebRTC over tcp
      - "8555:8555/udp" # WebRTC over udp
    environment:
      FRIGATE_RTSP_PASSWORD: "strong@pwd"


```

go to path VM IP:5000 to view the Frigate UI Configuration Editor

[![image.png](https://wiki.kyluat.com/uploads/images/gallery/2025-05/scaled-1680-/rYCimage.png)](https://wiki.kyluat.com/uploads/images/gallery/2025-05/rYCimage.png)

Twist your config like mine:

make sure to change username , password and ip address. Below is the 3 tapo c110 configuration url address

```yaml
mqtt:
  enabled: false

cameras:
  tapo_username001: # <------ Name the camera
    enabled: true
    ffmpeg:
      inputs:
        - path: rtsp://tapo_username001:yourpassw@192.168.1.xxx:554/stream1 # <----- The stream you want to use for detection
          roles:
            - detect
            - record
    detect:
      enabled: true # <---- disable detection until you have a working camera feed
      width: 2304
      height: 1296
      fps: 5
    motion:
      threshold: 30
      contour_area: 28
      improve_contrast: true
    record:
      enabled: true
      retain:
        days: 30
        mode: motion
    snapshots:
      enabled: true
      timestamp: true
      bounding_box: true
      retain:
        default: 30
  tapo_username002: # <------ Name the camera
    enabled: true
    ffmpeg:
      inputs:
        - path: rtsp://tapo_username002:yourpassw@192.168.1.xxx:554/stream1 # <----- The stream you want to use for detection
          roles:
            - detect
            - record
    detect:
      enabled: true # <---- disable detection until you have a working camera feed
      width: 2304
      height: 1296
      fps: 5
    motion:
      threshold: 30
      contour_area: 28
      improve_contrast: true
    record:
      enabled: true
      retain:
        days: 30
        mode: motion
    snapshots:
      enabled: true
      timestamp: true
      bounding_box: true
      retain:
        default: 30
  tapo_username003: # <------ Name the camera
    enabled: true
    ffmpeg:
      inputs:
        - path: rtsp://tapo_username003:yourpassw@192.168.1.xxx:554/stream1 # <----- The stream you want to use for detection
          roles:
            - detect
            - record
    detect:
      enabled: true # <---- disable detection until you have a working camera feed
      width: 2304
      height: 1296
      fps: 5
    motion:
      threshold: 30
      contour_area: 28
      improve_contrast: true
    record:
      enabled: true
      retain:
        days: 30
        mode: motion
    snapshots:
      enabled: true
      timestamp: true
      bounding_box: true
      retain:
        default: 30


record:
  enabled: true
  retain:
    days: 30
    mode: active_objects
  alerts:
    retain:
      days: 30
      mode: motion
  detections:
    retain:
      days: 30
      mode: motion

detectors:
  coral:
    type: edgetpu
    device: usb

objects:
  track:
    - person
    - face
    - printer
    - toy
    - filament
    - print_bed
    - extruder
    - tool
    - wrench
    - screw
    - spaghetti
    - failed_print


version: 0.15-1
camera_groups:
  SonA1:
    order: 1
    icon: LuFingerprint
    cameras:
      - tapo_username001
      - tapo_username002
      - tapo_username003

```

Click save and restart button

Tips:

Make sure to disable detection on your tapo settings, disable the local recording ( we don't need to use sd card for storage )

Go to the UI &gt; Settings &gt; Motion Tuner to update the Threshold and Contour Area to match your needs.

If you have google coral, it should have red label around the images.

[![image.png](https://wiki.kyluat.com/uploads/images/gallery/2025-05/scaled-1680-/7Pyimage.png)](https://wiki.kyluat.com/uploads/images/gallery/2025-05/7Pyimage.png)

Well done.

#### PCI Devices mapping in Proxmox

if you restart your VM or Host, the usb address id could change so that you need to map your host usb into your vm usb. Here is a quick run:

Remove your PCI Device in your VM Hardware setting.

SSH into your host pc which has the coral usb plugged in, mine is Orange

```bash
lsusb -t
```

  
/: Bus 08.Port 1: Dev 1, Class=root\_hub, Driver=xhci\_hcd/1p, 10000M  
/: Bus 07.Port 1: Dev 1, Class=root\_hub, Driver=xhci\_hcd/1p, 480M  
/: Bus 06.Port 1: Dev 1, Class=root\_hub, Driver=xhci\_hcd/1p, 10000M  
/: Bus 05.Port 1: Dev 1, Class=root\_hub, Driver=xhci\_hcd/1p, 480M  
/: Bus 04.Port 1: Dev 1, Class=root\_hub, Driver=xhci\_hcd/1p, 10000M  
/: Bus 03.Port 1: Dev 1, Class=root\_hub, Driver=xhci\_hcd/1p, 480M  
/: Bus 02.Port 1: Dev 1, Class=root\_hub, Driver=xhci\_hcd/2p, 10000M  
 |\_\_ Port 2: Dev 3, If 0, Class=Vendor Specific Class, Driver=usbfs, 5000M &lt;&lt; this is the one  
/: Bus 01.Port 1: Dev 1, Class=root\_hub, Driver=xhci\_hcd/5p, 480M  
 |\_\_ Port 5: Dev 2, If 0, Class=Wireless, Driver=btusb, 12M  
 |\_\_ Port 5: Dev 2, If 1, Class=Wireless, Driver=btusb, 12M

Bus 02, Port 2 → Driver=xhci\_hcd → PCIe USB controller

```bash
readlink -f /sys/bus/usb/devices/usb2
```

/sys/devices/pci0000:00/0000:00:08.1/0000:c5:00.3/usb2

PCI address: **0000:c5:00.3**

Go to Data Center &gt; Resource Mappings &gt; Under PCI Devices Panel , click Add &gt; Choose Mapping on Node: Orange

Scroll down and pick the id like the above, which is **0000:c5:00.3**

give it a short **Name**: coralusb

click **Create**

[![image.png](https://wiki.kyluat.com/uploads/images/gallery/2025-05/scaled-1680-/s81image.png)](https://wiki.kyluat.com/uploads/images/gallery/2025-05/s81image.png)

Now go back to your VM and add your pci device into your vm hardware setting:

[![image.png](https://wiki.kyluat.com/uploads/images/gallery/2025-05/scaled-1680-/sdiimage.png)](https://wiki.kyluat.com/uploads/images/gallery/2025-05/sdiimage.png)

Pick your mapped device:

[![image.png](https://wiki.kyluat.com/uploads/images/gallery/2025-05/scaled-1680-/LYeimage.png)](https://wiki.kyluat.com/uploads/images/gallery/2025-05/LYeimage.png)

Done. Restart the VM.

Update on 29 May 2025, here is my frigate yaml configuration for both google coral and beelink ser7 gpu. This include go2rtc which will stream one connection to the camera and stream out to everything else.

```yaml
mqtt:
  enabled: false
go2rtc:
  webrtc:
    candidates:
      - 192.168.1.114:8555
      - portainer2.kyluat.lan:8555
      - frigate:8555
  streams:
    son_user001:
      - rtsp://user001:{FRIGATE_RTSP_PASSWORD}@192.168.1.100:554/stream2
      - tapo://{FRIGATE_TAPO_PASSWORD}@192.168.1.100
      - ffmpeg:son_user001#audio=opus
    son_user001_record:
      - ffmpeg:rtsp://user001:{FRIGATE_RTSP_PASSWORD}@192.168.1.100:554/stream2#video=copy
      - tapo://{FRIGATE_TAPO_PASSWORD}@192.168.1.100

    # son_user001_sub:
    #   - rtsp://user001:{{FRIGATE_RTSP_PASSWORD}}@192.168.1.100:554/stream2?timeout=92&rtsp_transport=tcp#video=copy
    #   - ffmpeg:son_user001#audio=opus
    son_user002:
      - rtsp://user002:{FRIGATE_RTSP_PASSWORD}@192.168.1.101:554/stream2
      - tapo://{FRIGATE_TAPO_PASSWORD}@192.168.1.101
      - ffmpeg:son_user002#audio=opus
    son_user002_record:
      - ffmpeg:rtsp://user002:{FRIGATE_RTSP_PASSWORD}@192.168.1.101:554/stream2#video=copy
      - tapo://{FRIGATE_TAPO_PASSWORD}@192.168.1.101
    # son_user002_sub:
    #   - rtsp://user002:{{FRIGATE_RTSP_PASSWORD}}@192.168.1.101:554/stream2?timeout=92&rtsp_transport=tcp#video=copy
    #   - ffmpeg:son_user002_sub#audio=opus
    son_user003:
      - rtsp://user003:{FRIGATE_RTSP_PASSWORD}@192.168.1.102:554/stream2
      - tapo://{FRIGATE_TAPO_PASSWORD}@192.168.1.102
      - ffmpeg:son_user003#audio=opus
    son_user003_record:
      - ffmpeg:rtsp://user003:{FRIGATE_RTSP_PASSWORD}@192.168.1.102:554/stream2#video=copy
      - tapo://{FRIGATE_TAPO_PASSWORD}@192.168.1.102
      
    # son_user003_sub:
    #   - rtsp://user003:{{FRIGATE_RTSP_PASSWORD}}@192.168.1.102:554/stream2?timeout=92&rtsp_transport=tcp#video=copy
    #   - ffmpeg:son_user003_sub#audio=opus
    # son_user004:
    #   - rtsp://admin:{FRIGATE_TAPO_PASSWORD}@192.168.1.190:554/cam/realmonitor?channel=1&subtype=0#video=copy
    son_user004:
      - rtsp://admin:{FRIGATE_TAPO_PASSWORD}@192.168.1.190:554/cam/realmonitor?channel=1&subtype=1#video=copy
      - ffmpeg:son_user004_sub#audio=opus
    # son_user005:
    #   - rtsp://admin:{FRIGATE_TAPO_PASSWORD}@192.168.1.181:554/cam/realmonitor?channel=1&subtype=0#video=copy
    son_user005:
      - rtsp://admin:{FRIGATE_TAPO_PASSWORD}@192.168.1.181:554/cam/realmonitor?channel=1&subtype=1#video=copy
      - ffmpeg:son_user005_sub#audio=opus
    # son_user006:
    #   - rtsp://admin:{FRIGATE_TAPO_PASSWORD}@192.168.1.182:554/cam/realmonitor?channel=1&subtype=0#video=copy # L2C67C0F
    son_user006:
      - rtsp://admin:{FRIGATE_TAPO_PASSWORD}@192.168.1.182:554/cam/realmonitor?channel=1&subtype=1#video=copy # L2C67C0F
      - ffmpeg:son_user006_sub#audio=opus

cameras:
  son_user004: # <------ Name the camera
    enabled: true
    ffmpeg:
      output_args:
        record: preset-record-generic-audio-aac
      inputs:
        - path: rtsp://127.0.0.1:8554/son_user004 # <----- The stream you want to use for detection
          input_args: preset-rtsp-restream
          roles:
            - record
        # - path: rtsp://127.0.0.1:8554/son_user004_sub # <----- The stream you want to use for detection
        #   input_args: preset-rtsp-restream
        #   roles:
            - detect
            - audio

    detect:
      enabled: true # <---- disable detection until you have a working camera feed
      fps: 5
    motion:
      threshold: 80
      contour_area: 100
      improve_contrast: false
    snapshots:
      enabled: true
      timestamp: true
      bounding_box: true
      retain:
        default: 90
    zones:
      person_zone:
        coordinates: 0.997,0.902,0.255,0.746,0.322,0.009,0.77,0.004,0.68,0.191,0.996,0.071
        loitering_time: 0
    birdseye:
      order: 1
    review:
      detections:
        required_zones: person_zone
      alerts:
        required_zones: person_zone
    objects: {}
  son_user005: # <------ Name the camera
    enabled: true
    ffmpeg:
      output_args:
        record: preset-record-generic-audio-aac
      inputs:
        - path: rtsp://127.0.0.1:8554/son_user005 # <----- The stream you want to use for detection
          input_args: preset-rtsp-restream
          roles:
            - record
        # - path: rtsp://127.0.0.1:8554/son_user005_sub # <----- The stream you want to use for detection
        #   input_args: preset-rtsp-restream
        #   roles:
            - detect
            - audio
    detect:
      enabled: true # <---- disable detection until you have a working camera feed
      fps: 5
    motion:
      threshold: 34
      contour_area: 43
      improve_contrast: false
    snapshots:
      enabled: true
      timestamp: true
      bounding_box: true
      retain:
        default: 90
    zones:
      person_zone:
        coordinates: 0.229,0.03,0.217,1,0.415,0.991,0.96,0.957,0.982,0.004
        loitering_time: 0
        inertia: 3
    birdseye:
      order: 1
    review:
      alerts:
        required_zones: person_zone
      detections:
        required_zones: person_zone
    objects: {}
  son_user006: # <------ Name the camera
    enabled: true
    ffmpeg:
      output_args:
        record: preset-record-generic-audio-aac
      inputs:
        - path: rtsp://127.0.0.1:8554/son_user006 # <----- The stream you want to use for detection
          input_args: preset-rtsp-restream
          roles:
            - record
        # - path: rtsp://127.0.0.1:8554/son_user006_sub # <----- The stream you want to use for detection
        #   input_args: preset-rtsp-restream
        #   roles:
            - detect
            - audio

    detect:
      enabled: true # <---- disable detection until you have a working camera feed
      fps: 5
    motion:
      threshold: 80
      contour_area: 100
      improve_contrast: true
      mask: 0.614,0.276,0.605,0.598,0.726,0.617,0.724,0.28
    snapshots:
      enabled: true
      timestamp: true
      bounding_box: true
      retain:
        default: 90
    zones:
      person_zone:
        coordinates: 0.099,0.257,0.1,0.997,1,1,1,0.29
        loitering_time: 0
    birdseye:
      order: 1
    review:
      alerts:
        required_zones: person_zone
      detections:
        required_zones: person_zone
    objects:
      mask: 0.727,0.219,0.725,0.392,0.914,0.41,0.896,0.207
  son_user001: # <------ Name the camera
    enabled: true
    ffmpeg:
      output_args:
        record: preset-record-generic-audio-aac
      inputs:
        - path: rtsp://127.0.0.1:8554/son_user001_record # <----- The stream you want to use for record
          input_args: preset-rtsp-restream
          roles:
            - record
        - path: rtsp://127.0.0.1:8554/son_user001 # <----- The stream you want to use for detect
          input_args: preset-rtsp-restream
          roles:
            - detect
            - audio
    record:
      enabled: true
      retain:
        days: 90       # Keep recordings for 7 days (adjust as needed)
        mode: all     # Options: motion | active_objects | all
    detect:
      enabled: true # <---- disable detection until you have a working camera feed
      fps: 5
    motion:
      threshold: 80
      contour_area: 100
      improve_contrast: true
    snapshots:
      enabled: true
      timestamp: true
      bounding_box: true
      retain:
        default: 90
    zones:
      plate:
        coordinates: 
          0.269,0,0.276,0.29,0,0.568,0.145,1,0.404,1,0.896,1,1,0.583,0.943,0.413,0.803,0.297,0.795,0
        loitering_time: 0
        inertia: 3
    birdseye:
      order: 1
    review:
      detections:
        required_zones: plate
      alerts:
        required_zones: plate
    objects: {}
  son_user002: # <------ Name the camera
    enabled: true
    ffmpeg:
      output_args:
        record: preset-record-generic-audio-aac
      inputs:
        - path: rtsp://127.0.0.1:8554/son_user002_record # <----- The stream you want to use for detection
          input_args: preset-rtsp-restream
          roles:
            - record
        - path: rtsp://127.0.0.1:8554/son_user002 # <----- The stream you want to use for detection
          input_args: preset-rtsp-restream
          roles:
            - detect
            - audio
    record:
      enabled: true
      retain:
        days: 90       # Keep recordings for 7 days (adjust as needed)
        mode: all     # Options: motion | active_objects | all
    detect:
      enabled: true # <---- disable detection until you have a working camera feed
      fps: 5
    motion:
      threshold: 80
      contour_area: 100
      improve_contrast: false
      mask:
        - 0,0,0.442,0,0.463,0.456,0.165,0.544,0,0.84
        - 0.667,0,0.675,0.274,0.999,0.399,0.998,0
    snapshots:
      enabled: true
      timestamp: true
      bounding_box: true
      retain:
        default: 90
    zones:
      plate:
        coordinates: 
          0.163,0.551,0.462,0.458,0.444,0.003,0.664,0,0.674,0.276,0.998,0.399,1,0.996,0,0.996,0.001,0.851
        loitering_time: 0
    birdseye:
      order: 2
    review:
      detections:
        required_zones: plate
      alerts:
        required_zones: plate
    objects: {}
  son_user003: # <------ Name the camera
    enabled: true
    ffmpeg:
      output_args:
        record: preset-record-generic-audio-aac
      inputs:
        - path: rtsp://127.0.0.1:8554/son_user003_record # <----- The stream you want to use for detection
          input_args: preset-rtsp-restream
          roles:
            - record
        - path: rtsp://127.0.0.1:8554/son_user003 # <----- The stream you want to use for detection
          input_args: preset-rtsp-restream
          roles:
            - detect
            - audio
    record:
      enabled: true
      retain:
        days: 90       # Keep recordings for 7 days (adjust as needed)
        mode: all     # Options: motion | active_objects | all
    detect:
      #enabled: false # <---- disable detection until you have a working camera feed
      fps: 5
    motion:
      threshold: 30
      contour_area: 10
      improve_contrast: true
      mask: 0.362,0.172,0.359,0.421,0.457,0.421,0.459,0.222
    snapshots:
      enabled: true
      timestamp: true
      bounding_box: true
      retain:
        default: 30
    zones:
      person_zone:
        coordinates: 
          0.467,0.087,0.606,0.078,0.613,0.332,0.89,0.109,1,0.106,0.999,0.997,0.001,0.999,0.005,0.047,0.23,0.117,0.337,0.599,0.457,0.421
        loitering_time: 0
        objects: person
        inertia: 3
    birdseye:
      order: 3
    review:
      alerts:
        required_zones: person_zone
      detections:
        required_zones: person_zone
    objects:
      mask: 0.472,0.542,0.48,0.013,0.541,0.013,0.524,0.52
record:
  enabled: true
  export:
    timelapse_args: -vf setpts=PTS/60 -r 25
  sync_recordings: true
  retain:
    days: 90
    mode: all
  alerts:
    retain:
      days: 90
      mode: motion
  detections:
    retain:
      days: 90
      mode: motion

detectors:
  coral:
    type: edgetpu
    device: usb

objects:
  track:
    - person
    - cat
    - dog

audio:
  enabled: false
  listen:
    - bark
    - fire_alarm
    - scream
    - speech
    - yell
    - dog
    - footsteps
    - laughter
    - pets
    - cat
    - meow
    - electric_piano
    - piano
    - telephone
    - television




birdseye:
  enabled: true
  width: 1280
  height: 720
  mode: continuous
  inactivity_threshold: 15
  layout:
    max_cameras: 6
    scaling_factor: 1.0




ffmpeg:
  hwaccel_args: preset-vaapi
  output_args:
    record: preset-record-generic-audio-aac



version: 0.16-0
camera_groups:
  SonA1:
    order: 1
    icon: LuFingerprint
    cameras:
      - son_user001
      - son_user002
      - son_user003
      - son_user004
      - son_user005
      - son_user006
  Bird:
    order: 2
    icon: LuBird
    cameras: birdseye
semantic_search:
  enabled: true
  reindex: false
  model_size: large
detect:
  enabled: true
face_recognition:
  enabled: true
  model_size: large
lpr:
  enabled: true
classification:
  bird:
    enabled: true

```

##### Firewall and Allow Ports for Dahua Cam:

When you first init setup your dahua cam, don't use pi hole dns, use 1.1.1.1 dns instead.

**<u>1.device that integrates only the P2P function.</u>**  
  
To use UDP hole punch technology for remote access, the firewall output of the device must allow the following ports:  
  
  
● UDP ports: 0-65535  
  
● TCP ports: 9116, 9118, 12366, 12367  
  
● Dahua servers use dynamic IP addresses, their domain names and functions are:

<div class="bbTable" id="bkmrk-domain-name-function"><table><tbody><tr><td>**Domain Name**</td><td>**Function**</td></tr><tr><td>easy4ipcloud.com</td><td>Device login and registration</td></tr><tr><td>easy4ip.com</td><td>Device login and registration</td></tr></tbody></table>

</div>  
  
**<u>2.Device supporting P2P and Cloud Business</u>**  
  
To use UDP hole punch technology for remote access and normal operation of video surveillance services, the firewall output of the device must allow the following ports:  
  
  
● UDP ports: 0-65535  
  
● TCP ports: 443, 9112, 9113, 9116, 9118, 10000, 12367, 15100, 15101, 15301, 15600, 15900, 16759  
  
● Dahua servers use dynamic IP addresses, their domain names and functions are:

<div class="bbTable" id="bkmrk-domain-name-function-1"><table><tbody><tr><td>**Domain Name**</td><td>**Function**</td></tr><tr><td>easy4ipcloud.com</td><td>Device login and registration</td></tr><tr><td>easy4ip.com</td><td>Device login and registration</td></tr><tr><td>dms.easy4ipcloud.com</td><td>Device login and registration</td></tr><tr><td>paas-dms-edge-fk.easy4ipcloud.com</td><td>Device login and registration</td></tr><tr><td>smartdeviceproxy-edge-fk.easy4ipcloud.com</td><td>Device login and registration</td></tr><tr><td>devaccess.easyipcloud.com</td><td>Device login and registration</td></tr><tr><td>dus.easy4ipcloud.com</td><td>Cloud upgrade of device firmware</td></tr><tr><td>aktualisieren.easy4ip.com</td><td>Cloud upgrade of device firmware</td></tr><tr><td>update.easyviewercloud.com</td><td>Cloud upgrade of device firmware</td></tr><tr><td>vrs.easy4ipcloud.com</td><td>Upload device images and videos</td></tr><tr><td>pps.easy4ipcloud.com</td><td>Upload device messages</td></tr><tr><td>das.easy4ipcloud.com</td><td>Upload device messages</td></tr><tr><td>das-fk.easy4ipcloud.com</td><td>Upload device messages</td></tr><tr><td>devicelogserver-fk.easy4ipcloud.com</td><td>Uploading device log</td></tr></tbody></table>

</div>

# Proxmox Passthrough - Beelink Ser 7

Tutorials:

[https://github.com/isc30/ryzen-gpu-passthrough-proxmox/tree/main](https://github.com/isc30/ryzen-gpu-passthrough-proxmox/tree/main)

Additional Information:

**Turn off Secure Boot** on VM:

on Host,

```bash
sudo apt update
sudo apt install ovmf

cp /usr/share/kvm/OVMF_VARS.fd /var/lib/qemu-server/139-vars.fd
```

or

```bash
cp /usr/share/OVMF/OVMF_VARS.fd /var/lib/qemu-server/139-vars.fd
```

```bash
nano /etc/pve/qemu-server/139.conf
```

must have:

```bash
efidisk0: local-lvm:vm-139-disk-1,efitype=4m,filename=/var/lib/qemu-server/139-vars.fd
```

u220187@portainer2:~$ sudo lshw -c video  
 \*-display   
 description: VGA compatible controller  
 product: Phoenix1  
 vendor: Advanced Micro Devices, Inc. \[AMD/ATI\]  
 physical id: 0  
 bus info: pci@0000:01:00.0  
 version: c2  
 width: 64 bits  
 clock: 33MHz  
 capabilities: pm pciexpress msi msix vga\_controller bus\_master cap\_list rom  
 configuration: driver=amdgpu latency=0  
 resources: iomemory:c00-bff iomemory:c00-bff irq:16 memory:c000000000-c00fffffff memory:c010000000-c0101fffff ioport:d000(size=256) memory:c1000000-c107ffff memory:c1080000-c1083fff

VM Hardware Configuration

[![image.png](https://wiki.kyluat.com/uploads/images/gallery/2025-05/scaled-1680-/iO9image.png)](https://wiki.kyluat.com/uploads/images/gallery/2025-05/iO9image.png)