Homelab Nghiên cứu và thử nghiệm công nghệ thông tin tại nhà. Mini PCs 3 con mini pcs beelink ser7: 41,832,000 1 con mini router n100: 3,437,500 Tổng thiệt hại: 45,269,000 Beelink SER7 7840Hs Gray ( 25-10-2023 )  Thương hiệu    Beelink • Model Number    SER7 • CPU            AMD Ryzen™ 7 7840HS Processor, 8 Cores/16 Threads, 5.1GHz • GPU             AMD Radeon 780M (Frequency 2700MHz) • RAM             Dual DDR5 Channel (SODIMM Slots×2, Up to 5600MHz, Max 64GB) • ROM            M.2 2280 PCIe 4.0 SSD ×2 • Kết nối             WiFi 6, BlueTooth 5.2, USB4 ×2, DP 1.4 ×1, HDMI 2.1 ×1, LAN 2.5G ×1, Type-C ×1, Audio Jack ×2, USB 3.2 ×1, USB 2.0 ×2, DC IN • Power            Magnetic Power Supply (With 19V/6.32A adapter) Orange (2-11-2023) Black ( 3-11-2023 ) Mini PC Router N100 PC router N100 Con này để bridge từ router qua và làm router chính. Ngoài ra, nó được chạy pi hole cho dns nameserver cache. Có thể chịu tải hơn 1000 thiết bị cùng lúc. Bạn nào mà thấy ram viettel quá tải trong trang admin thì hãy mua. N100  - CPU N100 - 4 port LAN 2.5G I226V - 1 khe ram laptop DDR5 - 1 HDMI , 1 Displayport - 1 M.2 NVME , 1 SATA - 1 khe sim , 1 port minipcie - 2 USB 2.0 , 2 USB 3.0 .  - DC 12V Cách sử dụng PC Router với RouterOS của MikroTik Routers Chuẩn bị: PC Router có ít nhất 2 cổng 2.5 Gbps Switch 2.5 Gbps 10 cổng (nếu xài nhiều máy) 2-10 Dây Cat6 Ethernet ( Ngắn thì tốt hơn dài, tùy cự ly sắp xếp các thiết bị ) Số điện thoại nhân viên kỹ thuật viettel Bước 1: Chuẩn phần mềm và kết nối dây nhợ Đầu tiên bạn cần phải cài winbox Kết nối dây wan bridge từ router viettel , cổng wan 1/eth1 qua pc router cổng eth1 Lấy 1 dây mạng nữa kết nối từ eth2 từ pc router qua máy windows của bạn để sử dụng WinBox Dây mạng kế tiếp là dây kết nối với switch ở cổng eth3 từ pc router Bước 2: Xem lý thuyết cơ bản cách setup từ thầy networking Setup cơ bản hoàn chỉnh hết y chang. Không thiếu bước nào từ đây: https://youtu.be/yV_XgdgykhU?feature=shared&t=1111 Test xem lan network ok chưa bằng cách ping thử qua các ip máy khác và router 192.168.1.1 Mở windows command prompt lên và test thử xem ip trong network lan có reply ngon chưa ping 192.168.1.1 ping 192.168.1.2 ping 192.168.1.3 ... Sau khi mạng lan của bạn đã ổn định như bình thường thì làm bước kế tiếp Vào trang admin viettel http://192.168.1.1/ disable WAN disable Wireless Bước 3: Lấy thông tin Username và Password PPPoe  Gọi điện thoại cho nhân viên kỷ thuật viettel Nói là cần tạo bridge và xài modem riêng, vui lòng anh / chị cung cấp thông tin username và password pppoe  Sau khi xác định username và password, bạn điền vào phần pppoe username và password trên winbox của bước 2 Xác nhận và nói với nhân viên kỷ thuật viettel đã điền thông tin chính xác, anh chị vui lòng mở bridge Nhân viên viettel đồng ý và sẽ chuyển cho router của bạn thành bridge mode. Sau khi quay xong thì bạn sẽ thấy kết quả là có chữ R bên trái và ip address Chúc bạn thành công sau khi đã nhận được tín hiệu pppoe và ip address của phần wan. Kết quả  PC router có thể handle được 200 connections đồng thời cùng 1 lúc, trước đó với router Viettel default thì 50 là đã tạch. Học được cách mua pc router, kết nối dây, xử lý pppoe với nhân viên viettel, config được routeros và winbox. Tốc độ vẫn vậy : 650 Mbps Download và 350 Mbps Up , Ping 2ms ( giảm 1ms ) Lỗi thường mắc phải Username và password nhà mạng sai Quên chọn Action là: masquerade trong phần NAT Rule Out Interface phải là pppoe-out1 trong phần Nat Rule Đi dây từ router viettel sai port. phải là từ port 1 của router viettel sang port 1 của pc router. Đọc thêm: Hướng dẫn mở port 80: https://www.youtube.com/watch?v=KPfU6rPMHPk FastTrack FastTrack: bỏ qua các bước check trong kernel đối với các established connection. Chế độ này giúp cpu load giảm và tăng tốc độ truyền tải. https://www.youtube.com/watch?v=5XLNh3rbhDY :delay 5 /ip firewall address-list remove [/ip firewall address-list find list=WAN] :local wanip [/ip address get [/ip address find where interface=pppoe-out1] address]; :set wanip [:pick $wanip 0 ([:len $wanip]-3) ]; :put $wanip; /ip firewall address-list add list=WAN address=$wanip Terraform Sử dụng terraform để tự động hóa tạo máy ảo tự động trên proxmox và cloud hetzner Tạo VM với Terraform và Proxmox Step 1: Tạo API Token và Lưu lại Token ID , Secret Login vào proxmox ve server  Chọn Datacenter ở cột trái Nhìn qua phải thì section Permissions > chọn API Token Chọn Add để tạo Api Token Add Token theo user root Privilege Seperation: Unchecked (bỏ check) Token Id: Điền tên terraform Nhấn Add Button Lưu lại các thông tin sau vì nó chỉ hiện một lần: Token ID: root@pam!teraform Secret: 8ac5928a-9f2f-49e0-90d4-7542f87b9361 Step 2: Tạo Folder và các files terraform-proxmox Sau khi lưu xong token id và secret thì bạn mở webstorm hay vscode lên, tạo project trống tên là terraform-proxmox ở ổ đĩa nào tùy bạn, mình chọn ổ đĩa F: Install plugin hổ trợ terraform language Tạo 3 file, provider.tf, credentials.auto.tfvars, srv-demo-1.tf file: provider.tf terraform { required_version = ">= 0.13.0" required_providers { proxmox = { source = "telmate/proxmox" version = ">= 2.9.14" } } } variable "proxmox_api_url" { type = string } variable "proxmox_api_token_id" { type = string sensitive = true } variable "proxmox_api_token_secret" { type = string sensitive = true } provider "proxmox" { pm_api_url = var.proxmox_api_url pm_token_id = var.proxmox_api_token_id pm_token_secret = var.proxmox_api_token_secret pm_tls_insecure = true } file: credentials.auto.tfvars proxmox_api_url = "https://gray.kyluat.lan:8006/api2/json" proxmox_api_token_id = "root@pam!teraform2" proxmox_api_token_secret = "8ac5928a-9f2f-49e0-90d4-7542f87b9361" Nhớ chỉnh sửa lại thông tin url, token id và token secret của bạn đã tạo. cái url thay thế bằng ip address server proxmox của bạn cũng đc. ví dụ: https://192.168.1.12:8006/api2/json file: srv-demo-1.tf resource "proxmox_vm_qemu" "srv_demo_1" { name = "srv-demo-1" desc = "Demo Server 1" vmid = "201" target_node = "gray" agent = 0 clone = "ubuntu-cloud" cores = 2 sockets = 1 cpu = "host" memory = 2048 network { model = "virtio" bridge = "vmbr0" } disk { type = "virtio" storage = "local-lvm" size = "2252M" } os_type = "cloud-init" ipconfig0 = "ip=dhcp" nameserver = "192.168.1.11" ciuser = "USERNAMEABC" sshkeys = < type: bình thường là virtio, nếu xài scsi thì phải sửa lại type = "scsi". điền thêm thông tin bên ngoài (trên dòng os_type) với: disk { type = "scsi" storage = "local-lvm" size = "2252M" } scsihw = "virtio-scsi-pci" os_type = "cloud-init" disks > size: phần này phải điền đúng với size của cloud image đã tạo. nếu không terraform tự tạo ra 2nd disk. Cài đặt terraform lên máy và cd tới folder project đó, sau đó đánh command  cd f:/terraform-proxmox/ terraform init sau đó đánh command sau để check xem terraform plan success hết variables hay không: terraform plan Nếu thấy mọi thứ xanh lè hết thì đúng rồi, trừ phi copy and paste mấy cái thông số sai. Kế tiếp nhấn command sau để apply: terraform apply --auto-approve Sau đó vào proxmox sẽ thấy vm srv_demo_1 như hình sau Kết quả: 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 >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 ) 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. 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/ 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   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 pvecm expect 1 pvecm expect 2 pvecm expect 3 Install và cấu hình proxmox Best Tutorial from Techno Tim https://www.youtube.com/watch?v=GoZaMgEgrHw&list=PL8cwSAAaP9W37Vnxkw6__sshVY-XohWNm Note: 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 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 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 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 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/ 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 Vào download page: 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 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 , link: 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/ file: 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 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 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 > qemu guest agent enable giống như hình 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 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: Vào 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  Đăng ký xong thì bạn vào email lấy thông tin ssh đăng nhập Download Putty , cấu hình ssh và SSH Tunnel để kết nối server đồng thời cài setup OS qua RealVNC Viewer Chọn Dedicated Server nào phù hợp? Performance Hetzner Servers: https://go.kyluat.com/M8oBN Đăng ký xong: Xem email, lưu thông tin tài khoản lại vào robot hetzner xem thử: https://go.kyluat.com/hq1gs Lưu lại thông tin server như public ip, gateway ip, netmask để tiện config 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 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 Download Proxmox Iso image , rename thành pve.iso Kết quả: 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: Good Youtube Tutorial: https://www.youtube.com/watch?v=zKk9dnAp8FM In Proxmox Node: 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 18d1:9302 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: Restart VM run lsusb to see if the vm has the USB Install Docker and Portainer Add this Docker Compose to install frigate 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 Twist your config like mine: make sure to change username , password and ip address. Below is the 3 tapo c110 configuration url address 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 > Settings > 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. 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  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 << 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  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 > Resource Mappings > Under PCI Devices Panel , click Add > 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 Now go back to your VM and add your pci device into your vm hardware setting: Pick your mapped device: 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. 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. 1.device that integrates only the P2P function. 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: Domain Name Function easy4ipcloud.com Device login and registration easy4ip.com Device login and registration 2.Device supporting P2P and Cloud Business 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: Domain Name Function easy4ipcloud.com Device login and registration easy4ip.com Device login and registration dms.easy4ipcloud.com Device login and registration paas-dms-edge-fk.easy4ipcloud.com Device login and registration smartdeviceproxy-edge-fk.easy4ipcloud.com Device login and registration devaccess.easyipcloud.com Device login and registration dus.easy4ipcloud.com Cloud upgrade of device firmware aktualisieren.easy4ip.com Cloud upgrade of device firmware update.easyviewercloud.com Cloud upgrade of device firmware vrs.easy4ipcloud.com Upload device images and videos pps.easy4ipcloud.com Upload device messages das.easy4ipcloud.com Upload device messages das-fk.easy4ipcloud.com Upload device messages devicelogserver-fk.easy4ipcloud.com Uploading device log Proxmox Passthrough - Beelink Ser 7 Tutorials: https://github.com/isc30/ryzen-gpu-passthrough-proxmox/tree/main Additional Information: Turn off Secure Boot on VM: on Host,  sudo apt update sudo apt install ovmf cp /usr/share/kvm/OVMF_VARS.fd /var/lib/qemu-server/139-vars.fd or   cp /usr/share/OVMF/OVMF_VARS.fd /var/lib/qemu-server/139-vars.fd   nano /etc/pve/qemu-server/139.conf must have:    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 Home-Rack Tạo cheap home-rack server tại nhà Hàng Server Rack Thanh Lý 56 x Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GHz (2 Sockets) 1 TB NVME Samsung Enterprise 126 GB RAM DDR4 Giá tầm 13-15tr ( bằng 1 con mini pcs bình thường nhưng mạnh hơn rất nhiều ) Vagrant Vagrant install và một số command hay xài Install VirtualBox Vagrant Ubuntu Cloud Image Commands vagrant up vagrant ssh vagrant halt vagrant snapshot save [options] [vm-name]   Software Synology Drive Hard Disk Space bị quá tải Synology Drive Hard Disk tự nhiên bị quá tải vì Synology Drive Repo Folder chứa quá nhiều Versions  Điều cần làm là tắt Versions thông qua trình Drive Admin Bật ssh và vào ssh xóa folder trong volume2/@synologydrive/@sync/repo Chỉnh schedule task xóa files với Empty Recycle Bin Disable Recycle Bin cho các folder hay ổ đĩa Riêng phần ssh vào xóa files thì đây là command: sudo -i đánh password cd volume2/@synologydrive/@sync rm -rf repo còn muốn check folder size thì cứ đánh command sau: du -h -d1 1 là số depth Rancher Grafana Monitor Problems Problems: Readiness probe failed: Get grafana unhealthy Post "http://rancher-monitoring-prometheus.cattle-monitoring-system:9090/api/v1/query_range": dial tcp 10.43.3.173:9090: connect: connection refused Solutions: Vấn đề là ta đang xài local dev và sẽ không có https support, vì thế khi install grafana monitoring cần phải set lại https to false: +        https: +          enabled: false +          insecureSkipVerify: false +          useServiceAccountCredentials: false Better Solution: - Delete Grafana since it's too heavy Smart Home Tuya Smart Plug with Wifi. Mua ở đâu, setup Api làm sao? Mới múc con smart plug để theo dõi tiền điện mỗi tháng là bao nhiêu Mình mua tại đây (no affiliate): https://go.kyluat.com/43lN4 Còn này xài wifi nên cứ gắm vào ổ điện và cài đặt wifi trên app là đc Chức năng hửu dụng: Tắt mở remote mọi lúc mọi nơi miễn sao có wifi / internet Cài đặt thông báo số điện kwh hay số dollar limit theo thời gian quy định( ví dụ: 1 ngày mà xài quá số lượng điện cho phép thì email hay push notification tới điện thoại mình ) Access vào api cloud platform tuya để code tùy chỉnh control on/off , xem current stats,... Dưới này là thống kê trên smart life app kết nối với Smart Plug của Tuya. Về Tuya API platform: bạn cần đăng ký account:  https://auth.tuya.com/ Lúc đăng ký nhớ lưu ý là phải chọn Western America Data Center chứ ko phải China nha. Và sau đó khi xài SDK Nodejs hay ngôn ngữ khác thì bạn sử dụng link openapi của US: baseUrl: https://openapi.tuyaus.com 2. Vào cloud platform mà tạo access authorization key và secret Mở project của bạn lên Lưu thông tin access id, access secret và điền ip address của nhà bạn vào để bảo mật. 3. Liên kết smart life app tới tài khoản cloud  Sau khi nhấn add app account thì bạn xài app smart life đã cài device của bạn , nhấn vào dấu cộng (+) , chọn Scan để scan qr và cho phép Cloud Platform của Tuya liên kết vào. Sau khi liên kết hoàn tất, bạn cần lấy device id và test trên cloud explorer iot core của tuya: 4. test với cloud explorer của nó: https://us.platform.tuya.com/cloud/explorer Sau đây là code mình đã test và sucess: bạn thay thế accessKey, secretKey và device_id. import { TuyaContext } from '@tuya/tuya-connector-nodejs'; /** * api env entrypoint * * 'https://openapi.tuyaus.com', // US */ const context = new TuyaContext({ baseUrl: 'https://openapi.tuyaus.com', accessKey: 'yu4wydsasdasdsadjd5a5k', secretKey: '92c35b701casdasdasd8a58d8e8e', }); const main = async () => { // get access token const token = await context.client.init(); const device_id = "eb5acbfcasdasdasdasdasd61d51az"; const res = await context.request({ path: `/v1.0/devices/${device_id}/status`, method: 'GET', query: { key1: 'value1', key2: 'value2' } }); // convert result to human readable format const resultStats = res.result.map((item: any) => { return { code: item.code, value: item.value } }); // power in kwh, voltage in V, current in mA // write display in good human readable format from the result with unit name const humanReadableResult = resultStats.map((item: any) => { switch (item.code) { case 'cur_power': return { code: 'Power', value: `${item.value / 10}W` } case 'cur_voltage': return { code: 'Voltage', value: `${item.value/10}V` } case 'cur_current': return { code: 'Current', value: `${item.value}mA` } default: return { code: item.code, value: item.value } } }); const optimizedResult = []; // return only the 3 values that are needed humanReadableResult.forEach((item: any) => { if (item.code === 'Power' || item.code === 'Voltage' || item.code === 'Current') { optimizedResult.push(item); } }); console.log(optimizedResult); // get logs of device const lastMonthUnixTimestamp = Math.floor(Date.now() / 1000) - 30 * 24 * 60 * 60; const currentUnixTimestamp = Math.floor(Date.now() / 1000); const logs = await context.request({ path: `/v2.0/cloud/thing/${device_id}/logs`, method: 'GET', query: { type: 1, start_time: lastMonthUnixTimestamp, end_time: currentUnixTimestamp, query_type: 1, size: 20, } }); console.log(logs); }; main().catch(err => { console.log(err); }); Kết quả Networking My Home Network Architecture   27 tháng 5 năm 2024 Đang cố gắng nâng cấp tốc độ mạng từ 1 Gig lên 10 Gig  Remote Shutdown on via LAN or LOCAL Network for WINDOWS 10/11 Enable remote Shutdown on Window 10 Window Information WIN+R  msinfo32 To do: Set Password and Account for Window to be accessible for the remote  Enable firewall discovery  Set policy for local shutdown Video instruction: https://www.youtube.com/watch?v=UCphBNYMc4U WIN+E RIGHT CLICK on THIS PC Select MANAGE Go to  System Tools > Local Users and Groups > Users  Right Click on your Account PC Name and Set New Password. Make sure you rembember the password so that on the next logon you could enter. Next, you will need to set the policy for local: Open Registry Editor Find the Path and create new value as following: Value name: LocalAccountTokenFilterPolicy Value data: 1 Base: Hexadecimal Continue to search: manage advanced sharing settings Check Turn on Network discovery Good, CMD and run as Adminstrator The commands are useful for local shutdown or app usage: net use \\TargetPC /user:PCUSERNAME PASSWORD To remote shutdown the targetpc: shutdown /m \\TARGETPC /s Thats all. You have enabled the remote shutdown pc on windows 10 or 11 net rpc shutdown -I 192.168.1.99 -U "USERNAME%PASSWORD" USERNAME is your PC USERNAME PASSWORD is the password you have setted on the previous step Some notes if you are encountering WOL problem with BIOS and WOL Settings: WOL Fixed! For me was the Windows settings that fixed the type of shutdown somehow BIOS... Make screenshots Update BIOS Set settings how they were before update Set Advanced\APM Configuration\ErP Ready = DISABLED Set Advanced\APM Configuration\Power on by PCI-E = ENABLED WINDOWS... Open Powershell/CMD with ADMIN rights Run: REG ADD "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Power" /V HiberbootEnabled /T REG_dWORD /D 0 /F Open device manager, find your NIC, open, drivers tab - Update driver. If nothing found, download directly from manufacturer website Once updated, reboot. After reboot, open NIC properties\Power Management tab: Tick all boxes - Allow computer to turn off device, allow to wake up, only allow magic packet. Open NIC properties\Advanced tab and (where available): Set Enable PME = ENABLED Set Energy Efficient Ethernet / Green etc = DISABLED Wake on Magic Packet = ENABLED Wake on Pattern Match = ENABLED Reboot, then after reboot shutdown. Pihole + Zerotier + ZeroNSD Purpose: To have Zerotier act as VPN when we go outside and still able to visit home network with its dns name server resolved. Setup Pihole on VM Setup Zerotier on VM Setup ZeroNSD on VM Notes: Zerotier Installation and Settings: Tutorial: https://www.youtube.com/watch?v=1pTsgWNae88   Portainer Docker Compose Yaml: version: "3" volumes: ztncui: zt1: services: ztncui: image: keynetworks/ztncui container_name: ztncui environment: - USER_UID=998 #adjust to your system - USER_GID=100 #adjust to your system - NODE_ENV=production - HTTPS_PORT=3443 - ZTNCUI_PASSWD=[YOURPASSWORD] #change this - MYDOMAIN=[YOUR.DOMAIN.NAME/SUBDOMAIN.DOMAIN.NAME] #change this to the domain you want to use for the controller - MYADDR=[YOUR.PUBLIC.IP.HERE] #this is optional. if you use it, this is the public IP your ISP gave you volumes: - ztncui:/opt/key-networks/ztncui/etc - zt1:/var/lib/zerotier-one ports: - 3443:3443 #dashboard port - 3180:3180 Easy setting up new network address: 192.168.2.0/24 subset Pihole Settings: When install New instance of Pihole, you need to config DNS > Interfaces Settings > Permit all origins [X] checked Turn of dhcp. Next, you will need to route between pihole eth0 and zerotier interfaces: https://zerotier.atlassian.net/wiki/spaces/SD/pages/224395274/Route+between+ZeroTier+and+Physical+Networks PHY_IFACE=eth0; ZT_IFACE=zt3f2teohp sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE sudo iptables -A FORWARD -i eth0 -o zt3f2teohp -m state --state RELATED,ESTABLISHED -j ACCEPT sudo iptables -A FORWARD -i zt3f2teohp -o eth0 -j ACCEPT Go to your zerotier network : 192.168.2.0/24 is Zerotier Subnet  192.168.1.0/24 is Your local subnet that point to gateway of Pihole IP which is ( 192.168.2.1 ). Make sure when you install zerotier client on linux , please re-assign the ip address is 192.168.2.1 which is easier to remember. result: Change your DNS to pihole zerotier ip: From now on, when you access from your phone with zerotier vpn , you will be able to visit ip address on your lan network. Setup OpenWRT trên Proxmox: Tạo Switch Ports để xài cho các lỗ cắm Ethernet còn dư Cách setup trên Proxmox:  Blog post: https://community.bigbeartechworld.com/t/setting-up-openwrt-on-a-virtual-machine-with-proxmox/257 Image File: generic-ext4-rootfs.img.gz https://downloads.openwrt.org/releases/23.05.2/targets/x86/64/ Cài đặt theo cấu hình như tutorial này: https://gist.github.com/dragonfire1119/f3acd42414abfff762d2dad5e50f7cc6 Tắt máy và add thêm các cổng trên VM Proxmox, như hình dưới mình có 2 cổng, 1 cổng kết nối mạng và một cổng làm switch tới máy khác. Bước một tạo thêm Bridge Port trên Node, vào rack2 -> System -> Network -> chọn Create -> Linux Bridge  Bạn có thể thấy 2 network device, eno1, eno2 tương ứng cho vmbr0, vmbr1: Nếu không có hiện các device eno1, eno2 thì có thể là tên khác tùy theo hardware / cpu manufacturer. Còn không có các device gì hết thì bạn thử cắm ethernet vào switch trước cho nó nhận ( nhớ restart lại ) Kết tiếp vào VM Openwrt của bạn , phần hardware, thêm vào vmbr1 vmbr2 vmbr3 (nếu có 4 ports ethernet) Đăng nhập vào web browser ui của openwrt trên trình duyệt: vào phần network interfaces Tạo / Sửa interface: Cập nhập dns ip: 2 DNS IP là mình tạo 2 instance Pihole, một cái làm Primary local dns, 1 cái làm secondary để phụ trợ cho cái primary dns. Primary DNS đi trước, secondary DNS ip đi sau.  Save  Vào Device Tab và chọn configure... cho Bridge Lan Thêm / Check vào ports cần làm switch ports Save Save & Apply Ssh vào máy và đánh các command sau để cài đặt các package cần thiết cho vm: opkg update opkg install qemu-ga Restart lại VM Synology DSM USB Ethernet 2.5 Gbps Mình muốn synology ethernet speed từ 1 Gbps lên 2.5 Gbps Mình đã mua con USB Type A 2.5Gbps của Ugreen tại đây: https://go.kyluat.com/0dRtm Driver RTL8152 trên : https://github.com/bb-qq/r8152 Bạn có thể download bản mình đang test: https://github.com/bb-qq/r8152/releases/tag/2.14.0-3 Vào package manager và click vào manual install sau đó paste link url của file r8152-apollolake-2.14.0-3.spk Nếu bạn xài system os khác dsm khác phiên bản 6.2 trở lên thì research chọn đúng driver mới hơn Sau khi Install và Manual Run driver trên package center, mình vào control panel -> Network -> Network Interface để điều chỉnh settings ip address và set service order lên đầu: Mình vẫn giữ nguyên dây cũ và thêm vào dây mới để tiện khi nào usb sau khi bị cúp điện nó không nhận nữa thì vẫn vào được. Vấn đề của usb eth là khi bạn reboot lại thì synology fake của mình nó không nhận ra nữa vì thế mình cần phải re-install/re-run service của driver. Set MTU 9000 nhé, mình không biết cái này mày hướng dẫn thì nó bảo nên set thế cho performance tăng: Dahua IP Address Sử dụng Dahua Config Tool để tìm kiếm ip của dahua devices trong network: https://dahuawiki.com/ConfigTool Mua các device rẻ thì tự config ip không được nên phải xài trình này kiếm. Raspberry Pi Raspberry Pi + PiHole + Wifi + KEEPALIVE Phụ kiện: https://hshop.vn/bo-phu-kien-co-ban-cho-raspberry-pi-zero-2-w-basic-accessories/ Raspberry PI Zero 2W Nguồn Zin: https://go.kyluat.com/nF7yY Thẻ nhớ: https://go.kyluat.com/oGLNS Màn hình thì khỏi vì chả bao giờ nhìn. Ở nhà bạn thì cần có bluetooth keyboard và mouse bluetooth nếu có.  Tổng thiệt hại: 980k cho lần đầu, lần sau thì mua rẻ hơn và có sẵn mấy cái nguồn, dây nhợi để cài đặt rồi. việc còn lại cho nó chạy và ssh / VNC vào thôi Đầu tiên thì cứ múc vài linh kiện cơ bản để bắt đầu. Sau khi mua xong thì mình nghĩ lần sau mình mua thì mình sẽ loại bỏ mấy cái dây nhợ như mini hdmi to hdmi, vỏ nhôm heatsink vì cũng giảm cỡ 10 độ. 40 cái pin vì cũng ko cần =]].  Cài đặt: Pihole NUT Server Setup KeepAlive cho Secondary DNS cho Pihole để dự phòng việc tắt tất cả servers Test thử trường hợp cúp điện -> UPS bật -> script tắt tất cả hệ thống đúng để không ảnh hưởng database và các k3s nodes Khi có lại nguồn điện thì script tự động wake tất cả máy và vm, tự động mở lại các nodes và phần mềm. 1. Cài Đặt Pi OS xong thì sẽ cần phải chỉnh static ip với wlan0 Cách 1: Sử dụng command nmcli để đổi ip address của wifi ip sudo nmcli c show sudo nmcli c mod KyLuat ipv4.addresses 192.168.1.7/24 ipv4.method manual sudo reboot Cách 2: Sử dụng NetworkManager TUI tool NetworkManager's tool sudo nmtui 2. Setup Docker và Portainer Tham khảo trên trang docker để install docker: https://docs.docker.com/engine/install/raspberry-pi-os/ Tham khảo trên trang này để install portainer: https://pimylifeup.com/raspberry-pi-portainer/ 3. Docker Pi Hole as Backup Pi Hole Cài đặt pi hole lên portainer: Portainer stack / Docker Compose Yaml: # More info at https://github.com/pi-hole/docker-pi-hole/ and https://docs.pi-hole.net/ services: pihole: container_name: pihole image: pihole/pihole:2023.05.2 ports: # DNS Ports - "53:53/tcp" - "53:53/udp" # Default HTTP Port - "80:80/tcp" # Default HTTPs Port. FTL will generate a self-signed certificate - "443:443/tcp" # Uncomment the line below if you are using Pi-hole as your DHCP server #- "67:67/udp" # Uncomment the line below if you are using Pi-hole as your NTP server #- "123:123/udp" environment: # Set the appropriate timezone for your location (https://en.wikipedia.org/wiki/List_of_tz_database_time_zones), e.g: TZ: 'Asia/Ho_Chi_Minh' # Set a password to access the web interface. Not setting one will result in a random password being assigned FTLCONF_webserver_api_password: 'anythingispossible' # If using Docker's default `bridge` network setting the dns listening mode should be set to 'all' FTLCONF_dns_listeningMode: 'all' # Volumes store your data between container upgrades volumes: # For persisting Pi-hole's databases and common configuration file - './etc-pihole:/etc/pihole' # Uncomment the below if you have custom dnsmasq config files that you want to persist. Not needed for most starting fresh with Pi-hole v6. If you're upgrading from v5 you and have used this directory before, you should keep it enabled for the first v6 container start to allow for a complete migration. It can be removed afterwards. Needs environment variable FTLCONF_misc_etc_dnsmasq_d: 'true' #- './etc-dnsmasq.d:/etc/dnsmasq.d' cap_add: # See https://github.com/pi-hole/docker-pi-hole#note-on-capabilities # Required if you are using Pi-hole as your DHCP server, else not needed - NET_ADMIN # Required if you are using Pi-hole as your NTP client to be able to set the host's system time - SYS_TIME # Optional, if Pi-hole should get some more processing time - SYS_NICE restart: unless-stopped 4. Keepalive Keepalive là một service để khi tắt máy master thì có auto máy backup chạy. Keepalive tạo một ip ảo chung để xài. ví dụ: 192.168.1.2 là master , 192.168.1.3 là backup. thì ip ảo có thể tạo là 192.168.1.4 (nếu chưa có máy nào khác sử dụng ) Cài đặt keepalive trên master pihole và backup pihole machine: sudo apt update sudo apt install keepalived sudo apt install libipset13 Xác định interface của network: ip a ssh vào master pihole machine và đánh ip a vào sẽ thấy eth0 là interface.  sudo nano /etc/keepalived/keepalived.conf copy & paste nội dung sau vào notepad và chỉnh sửa interface và ip address, password 8 ký tự. Master: vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 55 priority 150 advert_int 1 unicast_src_ip 192.168.1.2 unicast_peer { 192.168.1.3 } authentication { auth_type PASS auth_pass KyLuatTT } virtual_ipaddress { 192.168.1.20/24 } } Giải thích:  interface eth0 , thay thế eth0 thành interface của bạn. bình thường là eth0, wifi có thể là wlan0. proxmox vm thì tùy, có thể là ensp1... virtual_router_id 55 , số 55 có thể là số nào cũng đc miễn sau nó khớp với backup node.  priority 150 : số càng cao thì càng ưu tiên độ quan trọng. unicast_src_ip 192.168.1.2 < ip của máy master unicast_peer: những node còn lại. Hiện tại là 1 node backup thì để 192.168.1.3 . còn nhiều hơn thì xuống dòng và 192.168.1.4  unicast_peer { 192.168.1.3 192.168.1.4 } auth_pass KyLuatTT : 8 ký tự . phải giống nhau với các node keepalive config khác virtual_ipaddress: là public ip để sử dụng. Keepalive sẽ tao ra một public ip riêng khác với node master và các node con. Ip này sẽ được sử dụng trong dns và khi shutdown node nào thì tùy vào priority keepalive sẽ chuyển giao nhiệm vụ cho node nào đang alive. Backup Node keepalive.conf Tương tự như master config, cài đặt keepalive và sau đó tạo config: sudo nano /etc/keepalived/keepalived.conf paste và chỉnh sửa sao cho đúng ip của backup node . ví dụ: 192.168.1.3 . còn unicast_peer thì có ip của master ip , nếu có nhiều hơn 2 node thì điền thêm ip vào để cho keepalive tự kiếm list và priority chuyển state master. vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 55 priority 100 advert_int 1 unicast_src_ip 192.168.1.3 unicast_peer { 192.168.1.2 } authentication { auth_type PASS auth_pass KyLuatTT } virtual_ipaddress { 192.168.1.20/24 } } Enable service cho keepalive chạy mỗi khi os startup ( đánh trên master và backup node ) sudo systemctl enable --now keepalived.service sudo systemctl start keepalived.service xem status backup hay master: sudo systemctl status keepalived.service Thử command tắt service trên master node coi có chuyển qua backup node không: Trên master node: sudo systemctl stop keepalived.service Trên máy đang code, mở terminal lên để ping: ping -t 192.168.1.20 Mỗi lần tắt service của master node thì backup node sẽ chuyển status state thành master: Hình trên là cấu hình Sơn đang xài chứ chả liên quan đến config mẫu đã đưa nên ip nó khác. Mũi tên vàng là khi master node tắt. Mũi tên xanh là khi master node lại mở lên. 5. Cài đặt obital-sync để sync pihole master với backup pihole version: '3' services: orbital-sync: container_name: orbital-sync image: mattwebbio/orbital-sync:1 environment: PRIMARY_HOST_BASE_URL: 'http://192.168.1.2' PRIMARY_HOST_PASSWORD: 'EEEEEEE' SECONDARY_HOSTS_1_BASE_URL: 'http://192.168.1.3' SECONDARY_HOSTS_1_PASSWORD: 'BBBBBBB' INTERVAL_MINUTES: 15 EEEEEE là pass ku pihole master BBBBB là pass ku pihole backup Okay giờ thì xài DNS với 192.168.1.20 thoải mái. Tắt máy master thì vẫn còn con Pi nó hoạt động. 6. Cài đặt UPSNAP Upsnap tiện để Wake Up On Lan và Shutdown trên nền tảng web. Dễ dàng sử dụng để tắt và mở máy. dưới này là upsnap docker compose yaml: version: "3.9" services: upsnap: image: ghcr.io/seriousm4x/upsnap:latest container_name: UpSnap mem_limit: 512m cpu_shares: 768 entrypoint: /bin/sh -c "./upsnap serve --http 0.0.0.0:4000" healthcheck: test: curl -fs "http://localhost:4000/api/health" || exit 1 network_mode: host restart: on-failure:5 environment: - TZ=Asia/Ho_Chi_Minh volumes: - /home/SON/docker/upsnap:/app/pb_data:rw 3D Printing Bambu Lab A1 Common Issues: Things You Should Do Before Any Serious Print These are issues i've experienced and want to take note.  Calibration: Calibrate Your Filament Before Usage Learn here Change the K Value to : 0.03 and the value step: 0.001 Pick the best line which has good k factor for the printer The above are two filament , one wood color filament is PLA on my P1S printer, and one gray color is PETG on A1 Printer. It's hard to tell the differences between the lines so take a look carefully around 0.02 to 0.018 , you will see the differences between them and other lines. Once you've seen it, please take the value and fill in the Calibration Page on Bambu Studio , and give it a good brand name of the filament to record it and use it in the future. My choice of K factor of A1 , Petg Filament by Kingroon is 0.03 and PLA filament by Kingroon for P1S printer is 0.019 After you've updated your filament k factor on the device, please proceed to the flow calibration. Same thing with the flow calibration: Adjust your flow ratio in the project filament and save it. for A1's Kingroon PETG, k factor: 0.03, flow ratio: 0.9975 for P1S's Jamg He PLA Matte, The value of K Factor is still 0.019 and with flow ratio is 0.98 P1S's Kingroon PLA Matte, k factor: 0.019 and flow ratio is  1.029 Here are some screenshot that i took to measure the surface by: Take a look with different angle with your lightning room Touch and feel the surface Use your phone to focus and zoom in to see the lines on the surface. Pick the best one and save the record! Too low Z Offset / Wrong Temp for PETG Problem with Z Offset + Temperature + Max Volumetric speed If your z offset is too far or too close , it could cause the rough surface. Thats why when you need to know how to benchmark the z offset by 0.025 each setting , you can increase the number or decrease it.  ======== z offset increase/decease settings could be ...0.06, 0.04, 0.02, 0, -0.02, -0.04, -0.06... Filament: PETG Printing Speed Mode: Luminous Z Offset: 0.06 / or could decrease by 0.05 if you want to test best fit for more filament  Temp: 265 Max Volumetric Speed: 12 mm3/s ;===== for Textured PEI Plate , lower the nozzle as the nozzle was touching topmost of the texture when homing == ;curr_bed_type={curr_bed_type} {if curr_bed_type=="Textured PEI Plate"} G29.1 Z{0.06} ; for Textured PEI Plate {endif} Result: Good Print Surface PLA  Z offset: 0.03