<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://tech.uvoo.io/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Busk</id>
	<title>UVOO Tech Wiki - User contributions
 [en]</title>
	<link rel="self" type="application/atom+xml" href="https://tech.uvoo.io/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Busk"/>
	<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php/Special:Contributions/Busk"/>
	<updated>2026-08-04T01:35:19Z</updated>
	<subtitle>User contributions
</subtitle>
	<generator>MediaWiki 1.35.2</generator>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Kube-virt_-_k8s_in_k8s&amp;diff=5735</id>
		<title>Kube-virt - k8s in k8s</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Kube-virt_-_k8s_in_k8s&amp;diff=5735"/>
		<updated>2026-08-02T15:11:02Z</updated>

		<summary type="html">&lt;p&gt;Busk: Created page with &amp;quot;One of the most popular and powerful use cases for KubeVirt, often referred to as **Kubernetes-in-Kubernetes** or **Tenant Clusters**.  In this architecture, your underlying b...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;One of the most popular and powerful use cases for KubeVirt, often referred to as **Kubernetes-in-Kubernetes** or **Tenant Clusters**.&lt;br /&gt;
&lt;br /&gt;
In this architecture, your underlying bare-metal Kubernetes cluster acts as the **infrastructure management layer** (the control plane for hardware), and KubeVirt provisions VMs that join together to form separate, isolated **tenant Kubernetes clusters**.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## Why Do This? (Key Benefits)&lt;br /&gt;
&lt;br /&gt;
* **Multi-Tenancy &amp;amp; Hard Isolation:** Containers share the host kernel. If you need strict security boundaries between teams or environments (e.g., Prod vs. Dev), VMs provide hardware-level virtualization isolation.&lt;br /&gt;
* **Infrastructure-as-Code (GitOps):** You can manage the lifecycle of entire target Kubernetes clusters declaratively using standard `kubectl` commands or GitOps pipelines (ArgoCD/Flux).&lt;br /&gt;
* **Cluster API (CAPI) Integration:** Using the **Cluster API Provider KubeVirt (CAPK)**, you can declare a target Kubernetes cluster in YAML, and CAPI + KubeVirt will automatically spin up the VMs, run `cloud-init` to install Kubernetes on them, and join them into a fully functional tenant cluster.&lt;br /&gt;
* **Testing &amp;amp; Sandbox Environments:** It allows developers to spin up ephemeral, full-featured Kubernetes clusters (with custom kernel modules or CNI configurations) without needing real physical hardware.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## How the Architecture Looks&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
┌────────────────────────────────────────────────────────────────────────┐&lt;br /&gt;
│                      BARE-METAL KUBERNETES CLUSTER                     │&lt;br /&gt;
│  (Management Cluster: Physical Servers + Storage + KubeVirt Operator)  │&lt;br /&gt;
│                                                                        │&lt;br /&gt;
│  ┌──────────────────────────────────────────────────────────────────┐  │&lt;br /&gt;
│  │                    TENANT KUBERNETES CLUSTER                     │  │&lt;br /&gt;
│  │                                                                  │  │&lt;br /&gt;
│  │   ┌────────────────────┐              ┌────────────────────┐     │  │&lt;br /&gt;
│  │   │ KubeVirt VM 1      │              │ KubeVirt VM 2      │     │  │&lt;br /&gt;
│  │   │ (Tenant Control)   │              │ (Tenant Worker)    │     │  │&lt;br /&gt;
│  │   │                    │              │                    │     │  │&lt;br /&gt;
│  │   │ ┌────────────────┐ │   Network    │ ┌────────────────┐ │     │  │&lt;br /&gt;
│  │   │ │ Tenant K8s API │ ◄────────────────►│ Tenant Pods    │ │     │  │&lt;br /&gt;
│  │   │ └────────────────┘ │ (Overlay/VLAN) │ └────────────────┘ │     │  │&lt;br /&gt;
│  │   └────────────────────┘              └────────────────────┘     │  │&lt;br /&gt;
│  └──────────────────────────────────────────────────────────────────┘  │&lt;br /&gt;
└────────────────────────────────────────────────────────────────────────┘&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## Typical Workflow&lt;br /&gt;
&lt;br /&gt;
1. **Deploy Bare-Metal K8s:** You set up physical servers with a Kubernetes distribution (e.g., Talos, RKE2, OpenShift, or upstream K8s).&lt;br /&gt;
2. **Install KubeVirt:** Deploy the KubeVirt operator on the bare-metal cluster.&lt;br /&gt;
3. **Use Cluster API (CAPK):** Apply a manifest defining a tenant cluster (e.g., 1 Control Plane VM, 3 Worker VMs).&lt;br /&gt;
4. **Bootstrapping via cloud-init:** KubeVirt boots the VMs, and `cloud-init` runs scripts (like `kubeadm join` or `k3s`) to wire the nodes into the new nested cluster.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## Things to Consider&lt;br /&gt;
&lt;br /&gt;
* **Nested Virtualization / Overhead:** Ensure hardware-assisted virtualization (`/dev/kvm`) is available on your bare-metal nodes so KubeVirt runs near native speed.&lt;br /&gt;
* **Networking:** You’ll need a CNI or plugin like **Multus** or **OVN-Kubernetes** on the bare-metal cluster to assign dedicated IPs or VLANs to the VM nodes so the tenant cluster can route traffic cleanly.&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Openssl&amp;diff=5734</id>
		<title>Openssl</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Openssl&amp;diff=5734"/>
		<updated>2026-08-01T22:06:24Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;openssl s_client -connect docker2:993 -servername docker2 &amp;lt;/dev/null 2&amp;gt;/dev/null | openssl x509 -noout -subject&lt;br /&gt;
&lt;br /&gt;
https://www.digitalocean.com/community/tutorials/openssl-essentials-working-with-ssl-certificates-private-keys-and-csrs&lt;br /&gt;
&lt;br /&gt;
https://www.openssl.org/docs/manmaster/man5/x509v3_config.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
openssl s_client -connect ldaps.example.com:636 -showcerts &amp;lt;/dev/null 2&amp;gt;/dev/null | openssl x509 -noout -ext subjectAltName&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
echo -n | openssl s_client -connect google.com:443 2&amp;gt;/dev/null | openssl x509 -noout -text | grep -E 'Subject:|X509v3 Subject Alternative Name:'&lt;br /&gt;
openssl s_client -connect www.uvoo.me:443&lt;br /&gt;
echo | openssl s_client -showcerts -servername www.uvoo.me -connect www.uvoo.me:443 2&amp;gt;/dev/null | openssl x509 -inform pem -noout -text&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Quicks like get subject alt names&lt;br /&gt;
```&lt;br /&gt;
openssl x509 -text -in my.crt.pem&lt;br /&gt;
openssl x509 -noout -ext subjectAltName&lt;br /&gt;
openssl x509 -noout -dates&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
# self signed cert pem&lt;br /&gt;
```&lt;br /&gt;
fqdn=${FQDN:-autogenerated-selfsigned-cert}; openssl req -x509 -nodes -days 3650 -newkey rsa:4096 -keyout selfsigned.key -out selfsigned.crt -subj &amp;quot;/CN=$fqdn&amp;quot; -addext &amp;quot;subjectAltName = DNS:$fqdn&amp;quot;&lt;br /&gt;
&lt;br /&gt;
cat selfsigned.crt selfsigned.key &amp;gt;&amp;gt; aaa.pem&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
# Extract Certs from .pfx PKCS#12&lt;br /&gt;
```&lt;br /&gt;
  openssl pkcs12 -passin env:PASSIN -in ${cn}.pfx -nocerts -nodes &amp;gt; ${cn}.key.pem&lt;br /&gt;
  openssl pkcs12 -passin env:PASSIN -in ${cn}.pfx -clcerts -nokeys &amp;gt; ${cn}.crt.pem&lt;br /&gt;
  openssl pkcs12 -passin env:PASSIN -in ${cn}.pfx -cacerts -nokeys -chain &amp;gt; ${cn}.ca.crt.pem&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
# validate&lt;br /&gt;
 https://link.medium.com/9Cif8SlO9ub&lt;br /&gt;
&lt;br /&gt;
# Pem&lt;br /&gt;
```&lt;br /&gt;
Donwload pem&lt;br /&gt;
openssl rsa -in ~/myhost.example.com.pem -out ~/myhost.example.com.pem.key&lt;br /&gt;
and replace encrypted private key at bottom in ~/myhost.example.com.pem with ~/myhost.example.com.pem.key&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
# pkcs12&lt;br /&gt;
```&lt;br /&gt;
echo -n | openssl s_client -showcerts -connect $HOST:$PORTNUMBER -servername $SERVERNAME \&lt;br /&gt;
    | openssl x509 &amp;gt; /tmp/$SERVERNAME.cert&lt;br /&gt;
&lt;br /&gt;
openssl pkcs12 -in &amp;lt;filename.pfx&amp;gt; -nocerts -nodes | sed -ne '/-BEGIN PRIVATE KEY-/,/-END PRIVATE KEY-/p' &amp;gt; &amp;lt;clientcert.key&amp;gt;&lt;br /&gt;
openssl pkcs12 -in &amp;lt;filename.pfx&amp;gt; -clcerts -nokeys | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' &amp;gt; &amp;lt;clientcert.cer&amp;gt;&lt;br /&gt;
openssl pkcs12 -in &amp;lt;filename.pfx&amp;gt; -cacerts -nokeys -chain | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' &amp;gt; &amp;lt;cacerts.cer&amp;gt;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Expiration dates&lt;br /&gt;
```&lt;br /&gt;
host=example.com; port=443; echo &amp;quot;Q&amp;quot; | openssl s_client -servername $host -connect $host:$port | openssl x509 -noout -dates&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Show Certs&lt;br /&gt;
```&lt;br /&gt;
host=example.com; port=443; echo &amp;quot;Q&amp;quot; | openssl s_client -showcerts -connect $host:$port&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Get CA cert PEM from URL and use with curl&lt;br /&gt;
```&lt;br /&gt;
host=example.com; port=443; echo quit | openssl s_client -showcerts -servername server -connect $host:$port &amp;gt; cacert.pem&lt;br /&gt;
host=example.com; port=443; curl -vv --cacert cacert.pem https://$host:$port/notifications/health&lt;br /&gt;
```&lt;br /&gt;
```&lt;br /&gt;
openssl pkcs12 -in example.io.pfx -out example.io.pem -nodes&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
# PKS&lt;br /&gt;
```&lt;br /&gt;
# kb.dev.example.com.pks&lt;br /&gt;
host=kb.dev.example.com; openssl pkcs12 -in $host.pfx -out $host.key -nocerts -nodes&lt;br /&gt;
host=kb.dev.example.com; openssl pkcs12 -in $host.pfx -out $host.crt -clcerts -nokeys&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
openssl pkcs12 -in &amp;lt;filename.pfx&amp;gt; -nocerts -nodes | sed -ne '/-BEGIN PRIVATE KEY-/,/-END PRIVATE KEY-/p' &amp;gt; &amp;lt;clientcert.key&amp;gt;&lt;br /&gt;
openssl pkcs12 -in &amp;lt;filename.pfx&amp;gt; -clcerts -nokeys | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' &amp;gt; &amp;lt;clientcert.cer&amp;gt;&lt;br /&gt;
openssl pkcs12 -in &amp;lt;filename.pfx&amp;gt; -cacerts -nokeys -chain | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' &amp;gt; &amp;lt;cacerts.cer&amp;gt;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
cipher scans&lt;br /&gt;
```&lt;br /&gt;
echo quit | openssl s_client -connect www.uvoo.io:443 -msg -debug 2&amp;gt;/dev/null | grep &amp;quot;Cipher    :&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Self signed https certs&lt;br /&gt;
```&lt;br /&gt;
View &amp;amp; Download in Firefox&lt;br /&gt;
PEM (cert)PEM (chain)&lt;br /&gt;
export API_HOST=example.com&lt;br /&gt;
echo quit | openssl s_client -showcerts -servername &amp;quot;${API_HOST}&amp;quot; -connect &amp;quot;${API_HOST}&amp;quot;:443 &amp;gt; cacert.pem&lt;br /&gt;
curl --cacert cacert.pem --location --silent https://${API_HOST}&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://www.redhat.com/sysadmin/6-openssl-commands&lt;br /&gt;
&lt;br /&gt;
# Extract cert and key&lt;br /&gt;
```&lt;br /&gt;
openssl pkcs12 -in domain.pfx -clcerts -nokeys -out domain.crt&lt;br /&gt;
openssl pkcs12 -in domain.pfx -nocerts -nodes  -out domain.key   &lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
# Update your Apache configuration file with:&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&amp;lt;VirtualHost 192.168.0.1:443&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
 SSLEngine on&lt;br /&gt;
 SSLCertificateFile /path/to/domain.crt&lt;br /&gt;
 SSLCertificateKeyFile /path/to/domain.key&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
echo quit | openssl s_client -connect log.example.com:6514&lt;br /&gt;
echo &amp;quot;Q&amp;quot; | openssl s_client -servername google.com -connect google.com:443 | openssl x509 -noout -dates&lt;br /&gt;
host=example.com; port=443; echo &amp;quot;Q&amp;quot; | openssl s_client -servername $host -connect $host:$port | openssl x509 -noout -dates&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
echo quit | openssl s_client -showcerts -servername server -connect google.com:443 &amp;gt; cacert.pem&lt;br /&gt;
true | openssl s_client -connect google.com:443 2&amp;gt;/dev/null | openssl x509&lt;br /&gt;
rm -f cert.pem &amp;amp;&amp;amp; echo -n | openssl s_client -connect google.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' &amp;gt; ./cert.pem&lt;br /&gt;
```&lt;br /&gt;
curl --cacert google.pem https://google.com&lt;br /&gt;
&lt;br /&gt;
Get cipher&lt;br /&gt;
```&lt;br /&gt;
echo quit | openssl s_client -connect lb.examle.com:443 2&amp;gt;/dev/null | grep -i cipher&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
openssl s_client -connect 10.x.x.x:6514&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
PKI&lt;br /&gt;
```&lt;br /&gt;
#!/usr/bin/env bash&lt;br /&gt;
set -eu&lt;br /&gt;
# ref: https://datacenteroverlords.com/2012/03/01/creating-your-own-ssl-certificate-authority/&lt;br /&gt;
&lt;br /&gt;
bits=4096&lt;br /&gt;
# cert_cn=insights.example.com&lt;br /&gt;
ca_dir=ca&lt;br /&gt;
keys_dir=ca/keys&lt;br /&gt;
mkdir -p $ca_dir&lt;br /&gt;
mkdir -p $keys_dir&lt;br /&gt;
# cd $ca_dir&lt;br /&gt;
ca_subject=&amp;quot;-subj \&amp;quot;/C=US/ST=Utah/L=Lehi/O=Example/OU=IT/CN=ca.example.com\&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
create_CA(){&lt;br /&gt;
  echo &amp;quot;Configuring rootca certs for issueing certs to nodes via CN/fqdn.&amp;quot;&lt;br /&gt;
  openssl genrsa -out $ca_dir/ca.key $bits&lt;br /&gt;
  openssl genrsa -des3 -out $ca_dir/ca.key $bits&lt;br /&gt;
  # openssl genrsa -nodes -out $ca_dir/ca.key $bits&lt;br /&gt;
  # openssl req -x509 -new -nodes -key $ca_dir/ca.key -sha256 -days 10240 -out $ca_dir/ca.pem $ca_subject&lt;br /&gt;
  openssl req -x509 -new -nodes -key $ca_dir/ca.key -sha256 -days 10240 -out $ca_dir/ca.crt -subj &amp;quot;/C=US/ST=Utah/L=Lehi/O=Example/OU=IT/CN=ca.example.com&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
create_client(){&lt;br /&gt;
  cert_cn=$1&lt;br /&gt;
  echo &amp;quot;Configuring certs for nodes with CN/fqdn.&amp;quot;&lt;br /&gt;
  openssl genrsa -out $keys_dir/${cert_cn}.key $bits&lt;br /&gt;
  openssl req -new -key $keys_dir/${cert_cn}.key -out $keys_dir/${cert_cn}.csr -subj &amp;quot;/C=US/ST=Utah/L=Lehi/O=Example/OU=IT/CN=$cert_cn&amp;quot;&lt;br /&gt;
  openssl x509 -req -in $keys_dir/${cert_cn}.csr -CA $ca_dir/ca.crt -CAkey $ca_dir/ca.key -CAcreateserial -out $keys_dir/${cert_cn}.crt -days 730 -sha256&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
copy_keys_to_rsyslog(){&lt;br /&gt;
  cert_cn=$1&lt;br /&gt;
  cp $keys_dir/${cert_cn}.key ../files/etc/rsyslog.d/keys/&lt;br /&gt;
  cp $keys_dir/${cert_cn}.crt ../files/etc/rsyslog.d/keys/&lt;br /&gt;
  cp $ca_dir/ca.crt ../files/etc/rsyslog.d/keys/&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
create_CA&lt;br /&gt;
create_client insights.example.com&lt;br /&gt;
copy_keys_to_rsyslog insights.example.com&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Notes&lt;br /&gt;
&lt;br /&gt;
# sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
# Shadow&lt;br /&gt;
```&lt;br /&gt;
openssl passwd -6 -salt ly7/kMnF  yourpass&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
LDAP&lt;br /&gt;
```&lt;br /&gt;
openssl s_client -showcerts -connect ldap.yourdomain.com:636&lt;br /&gt;
```&lt;br /&gt;
# Refs&lt;br /&gt;
- https://deliciousbrains.com/ssl-certificate-authority-for-local-https-development/#becoming-certificate-authority&lt;br /&gt;
- https://github.com/OpenVPN/easy-rsa/blob/master/README.quickstart.md&lt;br /&gt;
- https://www.feistyduck.com/library/openssl-cookbook/online/ch-testing-with-openssl.html&lt;br /&gt;
&lt;br /&gt;
# More&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
openssl s_client -connect 127.0.0.1:8443 -tls1_3&lt;br /&gt;
&lt;br /&gt;
openssl s_client -showcerts -servername www.example.com -connect www.example.com:443 &amp;lt;/dev/null&lt;br /&gt;
&lt;br /&gt;
openssl s_client -showcerts -connect www.example.com:443 &amp;lt;/dev/nul&lt;br /&gt;
&lt;br /&gt;
$ echo | \&lt;br /&gt;
    openssl s_client -servername www.example.com -connect www.example.com:443 2&amp;gt;/dev/null | \&lt;br /&gt;
    openssl x509 -text&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
openssl verify -verbose -CAfile _.example.com.crt _.example.com.crt&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
get cert&lt;br /&gt;
```&lt;br /&gt;
openssl x509 -in a.crt -text -certopt no_header,no_pubkey,no_subject,no_issuer,no_signame,no_version,no_serial,no_validity,no&lt;br /&gt;
_extensions,no_sigdump,no_aux,no_extensions&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
pkcs12 from key and crt&lt;br /&gt;
```&lt;br /&gt;
openssl pkcs12 -export -out keyStore.p12 -inkey my.key -in my.crt&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Swap_space&amp;diff=5733</id>
		<title>Swap space</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Swap_space&amp;diff=5733"/>
		<updated>2026-08-01T21:03:21Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;# Linux&lt;br /&gt;
&lt;br /&gt;
## Disable swap&lt;br /&gt;
&lt;br /&gt;
# Disable swap immediately&lt;br /&gt;
sudo swapoff -a&lt;br /&gt;
&lt;br /&gt;
# Comment out or remove any swap entries from /etc/fstab to persist on reboot&lt;br /&gt;
sudo sed -i.bak '/\bswap\b/s/^/#/' /etc/fstab&lt;br /&gt;
&lt;br /&gt;
## Clear swap&lt;br /&gt;
```&lt;br /&gt;
free -m &lt;br /&gt;
swapoff -a&lt;br /&gt;
# wait about 30 seconds&lt;br /&gt;
swapon -a&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## Check swappiness&lt;br /&gt;
```&lt;br /&gt;
sysctl -a | grep swap&lt;br /&gt;
vm.swappiness = 10&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Gitlab_runner_LXD&amp;diff=5732</id>
		<title>Gitlab runner LXD</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Gitlab_runner_LXD&amp;diff=5732"/>
		<updated>2026-08-01T20:10:13Z</updated>

		<summary type="html">&lt;p&gt;Busk: Created page with &amp;quot;https://docs.gitlab.com/runner/executors/custom_examples/lxd/  You need to **install the `gitlab-runner` apt package first**.  Installing the package creates the `gitlab-runne...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;https://docs.gitlab.com/runner/executors/custom_examples/lxd/&lt;br /&gt;
&lt;br /&gt;
You need to **install the `gitlab-runner` apt package first**.&lt;br /&gt;
&lt;br /&gt;
Installing the package creates the `gitlab-runner` system user and the `/etc/gitlab-runner/` directory structure where `config.toml` lives.&lt;br /&gt;
&lt;br /&gt;
Here is the step-by-step order of operations to get everything set up correctly:&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## Step 1: Install the GitLab Runner Package&lt;br /&gt;
&lt;br /&gt;
Run these commands on your host machine to add GitLab's official repository and install the runner:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
# 1. Download and run the official GitLab repository setup script&lt;br /&gt;
curl -L &amp;quot;https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh&amp;quot; | sudo bash&lt;br /&gt;
&lt;br /&gt;
# 2. Install the gitlab-runner package&lt;br /&gt;
sudo apt-get install gitlab-runner&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## Step 2: Create the LXD Executor Scripts&lt;br /&gt;
&lt;br /&gt;
Next, create your wrapper scripts for the custom executor (e.g., in `/opt/gitlab-runner/`).&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
# Create directory for custom executor scripts&lt;br /&gt;
sudo mkdir -p /opt/gitlab-runner&lt;br /&gt;
&lt;br /&gt;
# Create the prepare, run, and cleanup scripts&lt;br /&gt;
sudo touch /opt/gitlab-runner/lxd-prepare.sh&lt;br /&gt;
sudo touch /opt/gitlab-runner/lxd-run.sh&lt;br /&gt;
sudo touch /opt/gitlab-runner/lxd-cleanup.sh&lt;br /&gt;
&lt;br /&gt;
# Make them executable&lt;br /&gt;
sudo chmod +x /opt/gitlab-runner/lxd-*.sh&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
*(Paste the script contents into these files and ensure the LXD TLS certificate generation step you performed earlier is configured under the `gitlab-runner` system user's home directory so it can authenticate against LXD).*&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## Step 3: Register and Configure `config.toml`&lt;br /&gt;
&lt;br /&gt;
Finally, register the runner with your GitLab instance, which will automatically generate or update `/etc/gitlab-runner/config.toml`.&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
# Register the runner (you'll need a registration token from GitLab UI)&lt;br /&gt;
sudo gitlab-runner register \&lt;br /&gt;
  --non-interactive \&lt;br /&gt;
  --url &amp;quot;https://gitlab.com/&amp;quot; \&lt;br /&gt;
  --token &amp;quot;YOUR_RUNNER_AUTHENTICATION_TOKEN&amp;quot; \&lt;br /&gt;
  --executor &amp;quot;custom&amp;quot; \&lt;br /&gt;
  --description &amp;quot;lxd-restricted-runner&amp;quot; \&lt;br /&gt;
  --custom-prepare-exec &amp;quot;/opt/gitlab-runner/lxd-prepare.sh&amp;quot; \&lt;br /&gt;
  --custom-run-exec &amp;quot;/opt/gitlab-runner/lxd-run.sh&amp;quot; \&lt;br /&gt;
  --custom-cleanup-exec &amp;quot;/opt/gitlab-runner/lxd-cleanup.sh&amp;quot;&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Once registered, you can edit `/etc/gitlab-runner/config.toml` directly if you need to fine-tune concurrency limits or execution parameters.&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Kubernetes_Bare_Metal&amp;diff=5731</id>
		<title>Kubernetes Bare Metal</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Kubernetes_Bare_Metal&amp;diff=5731"/>
		<updated>2026-08-01T19:26:06Z</updated>

		<summary type="html">&lt;p&gt;Busk: Created page with &amp;quot;https://www.digitalocean.com/community/tutorials/bare-metal-kubernetes  You probably want to use cloud-init like this Ubuntu 24.04  `cloud-init` configuration for provisioning...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;https://www.digitalocean.com/community/tutorials/bare-metal-kubernetes&lt;br /&gt;
&lt;br /&gt;
You probably want to use cloud-init like this Ubuntu 24.04&lt;br /&gt;
&lt;br /&gt;
`cloud-init` configuration for provisioning Kubernetes nodes on **Ubuntu 24.04 LTS**.&lt;br /&gt;
&lt;br /&gt;
This script handles:&lt;br /&gt;
&lt;br /&gt;
* Disabling swap (required by `kubelet`)&lt;br /&gt;
* Enabling necessary kernel modules (`overlay`, `br_netfilter`)&lt;br /&gt;
* Setting required `sysctl` networking parameters&lt;br /&gt;
* Installing and configuring `containerd` with the `SystemdCgroup` driver enabled&lt;br /&gt;
* Adding the official `pkgs.k8s.io` repository (configured for Kubernetes **v1.30**)&lt;br /&gt;
* Installing and locking (`apt-mark hold`) `kubelet`, `kubeadm`, and `kubectl`&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## Cloud-Init YAML (`user-data`)&lt;br /&gt;
&lt;br /&gt;
```yaml&lt;br /&gt;
#cloud-config&lt;br /&gt;
package_update: true&lt;br /&gt;
package_upgrade: false&lt;br /&gt;
&lt;br /&gt;
packages:&lt;br /&gt;
  - apt-transport-https&lt;br /&gt;
  - ca-certificates&lt;br /&gt;
  - curl&lt;br /&gt;
  - gpg&lt;br /&gt;
  - containerd&lt;br /&gt;
&lt;br /&gt;
write_files:&lt;br /&gt;
  # Enable required kernel modules for container networking&lt;br /&gt;
  - path: /etc/modules-load.d/k8s.conf&lt;br /&gt;
    permissions: '0644'&lt;br /&gt;
    content: |&lt;br /&gt;
      overlay&lt;br /&gt;
      br_netfilter&lt;br /&gt;
&lt;br /&gt;
  # Set sysctl rules for iptables bridge &amp;amp; IP forwarding&lt;br /&gt;
  - path: /etc/sysctl.d/k8s.conf&lt;br /&gt;
    permissions: '0644'&lt;br /&gt;
    content: |&lt;br /&gt;
      net.bridge.bridge-nf-call-iptables  = 1&lt;br /&gt;
      net.bridge.bridge-nf-call-ip6tables = 1&lt;br /&gt;
      net.ipv4.ip_forward                 = 1&lt;br /&gt;
&lt;br /&gt;
runcmd:&lt;br /&gt;
  # 1. Disable swap immediately and persistently across reboots&lt;br /&gt;
  - swapoff -a&lt;br /&gt;
  - sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab&lt;br /&gt;
&lt;br /&gt;
  # 2. Load kernel modules and apply sysctl settings&lt;br /&gt;
  - modprobe overlay&lt;br /&gt;
  - modprobe br_netfilter&lt;br /&gt;
  - sysctl --system&lt;br /&gt;
&lt;br /&gt;
  # 3. Configure containerd with SystemdCgroup enabled&lt;br /&gt;
  - mkdir -p /etc/containerd&lt;br /&gt;
  - containerd config default | tee /etc/containerd/config.toml &amp;gt; /dev/null&lt;br /&gt;
  - sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml&lt;br /&gt;
  - systemctl restart containerd&lt;br /&gt;
  - systemctl enable containerd&lt;br /&gt;
&lt;br /&gt;
  # 4. Add official Kubernetes v1.30 apt repository&lt;br /&gt;
  - mkdir -p -m 755 /etc/apt/keyrings&lt;br /&gt;
  - curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg&lt;br /&gt;
  - chmod 644 /etc/apt/keyrings/kubernetes-apt-keyring.gpg&lt;br /&gt;
  - echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' | tee /etc/apt/sources.list.d/kubernetes.list&lt;br /&gt;
&lt;br /&gt;
  # 5. Install Kubernetes binaries and prevent auto-upgrades&lt;br /&gt;
  - apt-get update&lt;br /&gt;
  - apt-get install -y kubelet kubeadm kubectl&lt;br /&gt;
  - apt-mark hold kubelet kubeadm kubectl&lt;br /&gt;
  - systemctl enable --now kubelet&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## Next Steps After Boot&lt;br /&gt;
&lt;br /&gt;
Once your machine finishes running `cloud-init`, choose your role:&lt;br /&gt;
&lt;br /&gt;
### For the Control Plane (Master Node)&lt;br /&gt;
&lt;br /&gt;
Initialize the cluster with your control plane IP and preferred pod CIDR (e.g., Flannel/Calico):&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo kubeadm init --pod-network-cidr=10.244.0.0/16&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
### For Worker Nodes&lt;br /&gt;
&lt;br /&gt;
Run the `kubeadm join` command provided at the end of your control plane's `kubeadm init` output.&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=AWS_vs_Azure&amp;diff=5730</id>
		<title>AWS vs Azure</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=AWS_vs_Azure&amp;diff=5730"/>
		<updated>2026-08-01T15:46:53Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Here is how the core AWS services map directly to their Azure counterparts across key infrastructure categories:&lt;br /&gt;
&lt;br /&gt;
### Core Service Mapping&lt;br /&gt;
&lt;br /&gt;
| Category | AWS Service | Azure Equivalent | Description |&lt;br /&gt;
| --- | --- | --- | --- |&lt;br /&gt;
| **Compute** | **EC2** | Virtual Machines (VMs) | On-demand virtual instances/servers. |&lt;br /&gt;
|  | **AWS Lambda** | Azure Functions | Event-driven serverless compute. |&lt;br /&gt;
|  | **Elastic Beanstalk** | Azure App Service | Managed PaaS for web app deployment. |&lt;br /&gt;
| **Containers** | **EKS** | Azure Kubernetes Service (AKS) | Managed Kubernetes engine. |&lt;br /&gt;
|  | **ECS / Fargate** | Azure Container Apps / ACI | Serverless container execution. |&lt;br /&gt;
|  | **ECR** | Azure Container Registry (ACR) | Docker/OCI image repository. |&lt;br /&gt;
| **Storage** | **S3** | Azure Blob Storage | Scalable object storage. |&lt;br /&gt;
|  | **EBS** | Azure Managed Disks | Block storage attached to compute instances. |&lt;br /&gt;
|  | **EFS / FSx** | Azure Files | Fully managed network file shares (NFS/SMB). |&lt;br /&gt;
|  | **S3 Glacier** | Azure Archive Storage | Cold/archival storage for backups. |&lt;br /&gt;
| **Databases** | **RDS** | Azure SQL Database / Flexible Server | Managed relational databases (PostgreSQL, MySQL, SQL Server). |&lt;br /&gt;
|  | **DynamoDB** | Azure Cosmos DB | Fully managed NoSQL key-value/document database. |&lt;br /&gt;
|  | **ElastiCache** | Azure Cache for Redis | In-memory caching. |&lt;br /&gt;
| **Networking** | **VPC** | Virtual Network (VNet) | Isolated private cloud networking. |&lt;br /&gt;
|  | **Route 53** | Azure DNS | Managed DNS routing service. |&lt;br /&gt;
|  | **Direct Connect** | Azure ExpressRoute | Dedicated private link to on-premise hardware. |&lt;br /&gt;
|  | **ALB / NLB** | Application Gateway / Load Balancer | Layer 7 (HTTP/HTTPS) and Layer 4 load balancing. |&lt;br /&gt;
| **Identity &amp;amp; Security** | **AWS IAM** | Microsoft Entra ID (Azure AD) + RBAC | Identity management, auth, and role definitions. |&lt;br /&gt;
|  | **AWS KMS** | Azure Key Vault | Key, secret, and certificate management. |&lt;br /&gt;
|  | **AWS Shield / WAF** | Azure DDoS Protection / Web Application Firewall | DDoS defense and application security. |&lt;br /&gt;
| **Analytics &amp;amp; AI** | **Redshift** | Azure Synapse Analytics | Cloud data warehousing. |&lt;br /&gt;
|  | **Amazon SageMaker** | Azure Machine Learning | Platform for building, training, and deploying ML models. |&lt;br /&gt;
|  | **AWS Glue** | Azure Data Factory | Managed ETL and data integration pipelines. |&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
### Key Structural Differences&lt;br /&gt;
&lt;br /&gt;
* **Identity Model:** AWS centers permissions around IAM policies attached to users/roles via JSON documents. Azure heavily relies on Microsoft Entra ID with Role-Based Access Control (RBAC) applied across standard scope hierarchies (Management Groups → Subscriptions → Resource Groups → Resources).&lt;br /&gt;
* **Resource Management:** Azure mandates that every resource resides within a **Resource Group** for unified lifecycle management. AWS tags resources globally or groups them logically, but lacks the strict single-container grouping model native to Azure.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
**for most greenfield projects, standard microservices, and general container workloads, Fargate is the default best choice.**&lt;br /&gt;
&lt;br /&gt;
The reduced configuration, lack of node management (no OS patching, no AMI rotations, no cluster autoscaling setup), and per-task scaling make it the lower-overhead option for developer velocity.&lt;br /&gt;
&lt;br /&gt;
However, saying it’s *only* when resources are &amp;quot;mostly pegged&amp;quot; misses a few critical non-cost boundaries where Fargate simply cannot be used or becomes significantly more expensive.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
### Non-Cost Constraints (When Fargate Is Not an Option)&lt;br /&gt;
&lt;br /&gt;
Sometimes you **must** use EC2 regardless of price or utilization:&lt;br /&gt;
&lt;br /&gt;
1. **GPU / Specialized Hardware Workloads:** Machine learning inference/training (NVIDIA GPUs), high-performance media encoding, or AWS Inferentia/Trainium hardware require EC2 instance types. Fargate doesn't support GPU pass-through.&lt;br /&gt;
2. **Custom Daemon / Host-Level Monitoring:** If you rely on daemonsets/agents that must run at the host OS level (e.g., specific kernel-level eBPF tracing, custom security agents, or system-wide log forwarders), Fargate’s serverless boundary prevents host access. Sidecar containers are required on Fargate instead.&lt;br /&gt;
3. **Privileged Mode &amp;amp; Kernel Tweaks:** Tasks requiring Linux `--privileged` access, custom kernel module loading, raw network sockets, or `sysctl` modifications are blocked by Fargate’s isolation boundary.&lt;br /&gt;
4. **Extreme Local Disk I/O:** Fargate task storage tops out at 200 GB of ephemeral storage. If your app requires terabytes of high-speed local NVMe scratch disk (like `i3en` or `z1d` instances), you need EC2.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
### Cost Decision Matrix&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
                    Is the workload continuous &amp;amp; predictable?&lt;br /&gt;
                                  /          \&lt;br /&gt;
                                 /            \&lt;br /&gt;
                                YES            NO (Bursty / Batch / Variable)&lt;br /&gt;
                               /                \&lt;br /&gt;
      Are you running high-volume baseline?      --&amp;gt;  Use FARGATE&lt;br /&gt;
                 /          \                         (Zero idle capacity waste)&lt;br /&gt;
                /            \&lt;br /&gt;
              YES             NO&lt;br /&gt;
              /                \&lt;br /&gt;
    Are you using 3-yr Savings  --&amp;gt;  Use FARGATE &lt;br /&gt;
    Plans + tight bin-packing?       (Engineering time &amp;gt; ~20% savings)&lt;br /&gt;
            /&lt;br /&gt;
          YES&lt;br /&gt;
          /&lt;br /&gt;
     Use EC2&lt;br /&gt;
(Save up to 50%+)&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
### Summary Checklist&lt;br /&gt;
&lt;br /&gt;
| Dimension | Default Choice | Shift to EC2 when... |&lt;br /&gt;
| --- | --- | --- |&lt;br /&gt;
| **Operational Effort** | **Fargate** (Zero node maintenance) | You already have robust node automation (e.g., Karpenter/Cluster Autoscaler) and dedicated DevOps resource. |&lt;br /&gt;
| **Scale Mechanism** | **Fargate** (Fast task provisioning) | Scaling is predictable and you can handle warm node pools. |&lt;br /&gt;
| **Hardware** | **Fargate** (Standard CPU/ARM + RAM) | You require GPUs, host storage, or kernel/privileged access. |&lt;br /&gt;
| **Cost at Scale** | **Fargate** (No waste from idle nodes) | Your monthly compute bill is large enough ($5k–$10k+/mo) that saving 30–50% pays for the engineering time to manage nodes. |&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=AWS_vs_Azure&amp;diff=5729</id>
		<title>AWS vs Azure</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=AWS_vs_Azure&amp;diff=5729"/>
		<updated>2026-08-01T15:46:15Z</updated>

		<summary type="html">&lt;p&gt;Busk: Created page with &amp;quot;**for most greenfield projects, standard microservices, and general container workloads, Fargate is the default best choice.**  The reduced configuration, lack of node managem...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;**for most greenfield projects, standard microservices, and general container workloads, Fargate is the default best choice.**&lt;br /&gt;
&lt;br /&gt;
The reduced configuration, lack of node management (no OS patching, no AMI rotations, no cluster autoscaling setup), and per-task scaling make it the lower-overhead option for developer velocity.&lt;br /&gt;
&lt;br /&gt;
However, saying it’s *only* when resources are &amp;quot;mostly pegged&amp;quot; misses a few critical non-cost boundaries where Fargate simply cannot be used or becomes significantly more expensive.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
### Non-Cost Constraints (When Fargate Is Not an Option)&lt;br /&gt;
&lt;br /&gt;
Sometimes you **must** use EC2 regardless of price or utilization:&lt;br /&gt;
&lt;br /&gt;
1. **GPU / Specialized Hardware Workloads:** Machine learning inference/training (NVIDIA GPUs), high-performance media encoding, or AWS Inferentia/Trainium hardware require EC2 instance types. Fargate doesn't support GPU pass-through.&lt;br /&gt;
2. **Custom Daemon / Host-Level Monitoring:** If you rely on daemonsets/agents that must run at the host OS level (e.g., specific kernel-level eBPF tracing, custom security agents, or system-wide log forwarders), Fargate’s serverless boundary prevents host access. Sidecar containers are required on Fargate instead.&lt;br /&gt;
3. **Privileged Mode &amp;amp; Kernel Tweaks:** Tasks requiring Linux `--privileged` access, custom kernel module loading, raw network sockets, or `sysctl` modifications are blocked by Fargate’s isolation boundary.&lt;br /&gt;
4. **Extreme Local Disk I/O:** Fargate task storage tops out at 200 GB of ephemeral storage. If your app requires terabytes of high-speed local NVMe scratch disk (like `i3en` or `z1d` instances), you need EC2.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
### Cost Decision Matrix&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
                    Is the workload continuous &amp;amp; predictable?&lt;br /&gt;
                                  /          \&lt;br /&gt;
                                 /            \&lt;br /&gt;
                                YES            NO (Bursty / Batch / Variable)&lt;br /&gt;
                               /                \&lt;br /&gt;
      Are you running high-volume baseline?      --&amp;gt;  Use FARGATE&lt;br /&gt;
                 /          \                         (Zero idle capacity waste)&lt;br /&gt;
                /            \&lt;br /&gt;
              YES             NO&lt;br /&gt;
              /                \&lt;br /&gt;
    Are you using 3-yr Savings  --&amp;gt;  Use FARGATE &lt;br /&gt;
    Plans + tight bin-packing?       (Engineering time &amp;gt; ~20% savings)&lt;br /&gt;
            /&lt;br /&gt;
          YES&lt;br /&gt;
          /&lt;br /&gt;
     Use EC2&lt;br /&gt;
(Save up to 50%+)&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
### Summary Checklist&lt;br /&gt;
&lt;br /&gt;
| Dimension | Default Choice | Shift to EC2 when... |&lt;br /&gt;
| --- | --- | --- |&lt;br /&gt;
| **Operational Effort** | **Fargate** (Zero node maintenance) | You already have robust node automation (e.g., Karpenter/Cluster Autoscaler) and dedicated DevOps resource. |&lt;br /&gt;
| **Scale Mechanism** | **Fargate** (Fast task provisioning) | Scaling is predictable and you can handle warm node pools. |&lt;br /&gt;
| **Hardware** | **Fargate** (Standard CPU/ARM + RAM) | You require GPUs, host storage, or kernel/privileged access. |&lt;br /&gt;
| **Cost at Scale** | **Fargate** (No waste from idle nodes) | Your monthly compute bill is large enough ($5k–$10k+/mo) that saving 30–50% pays for the engineering time to manage nodes. |&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Saltstack_docker&amp;diff=5728</id>
		<title>Saltstack docker</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Saltstack_docker&amp;diff=5728"/>
		<updated>2026-07-31T07:15:26Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;```&lt;br /&gt;
services:&lt;br /&gt;
  salt-master:&lt;br /&gt;
    image: saltstack/salt:latest&lt;br /&gt;
    container_name: salt-master&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;4505:4505&amp;quot;&lt;br /&gt;
      - &amp;quot;4506:4506&amp;quot;&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./config/master:/etc/salt/master:ro&lt;br /&gt;
      - salt-pki:/etc/salt/pki&lt;br /&gt;
      - ./srv/salt:/srv/salt&lt;br /&gt;
      - ./srv/pillar:/srv/pillar&lt;br /&gt;
      - salt-cache:/var/cache/salt&lt;br /&gt;
      - salt-run:/var/run/salt&lt;br /&gt;
&lt;br /&gt;
  watchtower:&lt;br /&gt;
    image: containrrr/watchtower&lt;br /&gt;
    container_name: watchtower&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    environment:&lt;br /&gt;
      # Run at 2:00 AM every night&lt;br /&gt;
      # Format: Seconds Minutes Hours DayOfMonth Month DayOfWeek&lt;br /&gt;
      - WATCHTOWER_SCHEDULE=0 0 2 * * *&lt;br /&gt;
      # Remove old unpatched image layers from disk after updating&lt;br /&gt;
      - WATCHTOWER_CLEANUP=true&lt;br /&gt;
      # Check for base image updates regardless of local tag&lt;br /&gt;
      - WATCHTOWER_INCLUDE_RESTARTING=true&lt;br /&gt;
    volumes:&lt;br /&gt;
      # CRITICAL: This must point to the rootless user's socket, not /var/run!&lt;br /&gt;
      # Replace '1001' with the output of `id -u`&lt;br /&gt;
      - /run/user/1001/docker.sock:/var/run/docker.sock&lt;br /&gt;
    # Restrict Watchtower to ONLY update the salt-master container&lt;br /&gt;
    command: salt-master&lt;br /&gt;
&lt;br /&gt;
volumes:&lt;br /&gt;
  salt-pki:&lt;br /&gt;
  salt-cache:&lt;br /&gt;
  salt-run:&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
set -e&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# CONFIGURATION&lt;br /&gt;
# ==========================================&lt;br /&gt;
# Replace with your Dockerized Salt Master's IP or DNS name&lt;br /&gt;
SALT_MASTER=&amp;quot;mysalt.example.com&amp;quot; &lt;br /&gt;
&lt;br /&gt;
# Uses the machine's hostname by default, or you can hardcode a name (e.g., &amp;quot;web-server-01&amp;quot;)&lt;br /&gt;
MINION_ID=$(hostname) &lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
if [[ $EUID -ne 0 ]]; then&lt;br /&gt;
   echo &amp;quot;Error: This script must be run as root. Try using: sudo $0&amp;quot;&lt;br /&gt;
   exit 1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Installing prerequisites...&amp;quot;&lt;br /&gt;
apt-get update&lt;br /&gt;
apt-get install -y curl gnupg&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Adding Salt Project repository for Ubuntu 24.04 LTS (Noble)...&amp;quot;&lt;br /&gt;
mkdir -p /etc/apt/keyrings&lt;br /&gt;
curl -fsSL -o /etc/apt/keyrings/salt-archive-keyring-2023.gpg \&lt;br /&gt;
  https://repo.saltproject.io/salt/py3/ubuntu/24.04/amd64/SALT-PROJECT-GPG-PUBKEY-2023.gpg&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;deb [signed-by=/etc/apt/keyrings/salt-archive-keyring-2023.gpg arch=amd64] https://repo.saltproject.io/salt/py3/ubuntu/24.04/amd64/3006 noble main&amp;quot; \&lt;br /&gt;
  | tee /etc/apt/sources.list.d/salt.list &amp;gt; /dev/null&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Installing Salt Minion...&amp;quot;&lt;br /&gt;
apt-get update&lt;br /&gt;
apt-get install -y salt-minion&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Configuring Minion to connect to $SALT_MASTER...&amp;quot;&lt;br /&gt;
mkdir -p /etc/salt/minion.d&lt;br /&gt;
echo &amp;quot;master: $SALT_MASTER&amp;quot; &amp;gt; /etc/salt/minion.d/master.conf&lt;br /&gt;
echo &amp;quot;$MINION_ID&amp;quot; &amp;gt; /etc/salt/minion_id&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Enabling and starting Salt Minion service...&amp;quot;&lt;br /&gt;
systemctl enable --now salt-minion&lt;br /&gt;
systemctl restart salt-minion&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==================================================&amp;quot;&lt;br /&gt;
echo &amp;quot;Success! The Salt Minion ($MINION_ID) is running.&amp;quot;&lt;br /&gt;
echo &amp;quot;It has sent its public key to $SALT_MASTER.&amp;quot;&lt;br /&gt;
echo &amp;quot;You must now log into the Master server and accept this key.&amp;quot;&lt;br /&gt;
echo &amp;quot;==================================================&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
# List pending keys to verify the minion showed up&lt;br /&gt;
docker compose exec salt-master salt-key -L&lt;br /&gt;
&lt;br /&gt;
# Accept the specific minion key&lt;br /&gt;
docker compose exec salt-master salt-key -a&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Saltstack_docker&amp;diff=5727</id>
		<title>Saltstack docker</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Saltstack_docker&amp;diff=5727"/>
		<updated>2026-07-31T07:14:03Z</updated>

		<summary type="html">&lt;p&gt;Busk: Created page with &amp;quot;``` #!/bin/bash set -e  # ========================================== # CONFIGURATION # ========================================== # Replace with your Dockerized Salt Master's...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;```&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
set -e&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# CONFIGURATION&lt;br /&gt;
# ==========================================&lt;br /&gt;
# Replace with your Dockerized Salt Master's IP or DNS name&lt;br /&gt;
SALT_MASTER=&amp;quot;mysalt.example.com&amp;quot; &lt;br /&gt;
&lt;br /&gt;
# Uses the machine's hostname by default, or you can hardcode a name (e.g., &amp;quot;web-server-01&amp;quot;)&lt;br /&gt;
MINION_ID=$(hostname) &lt;br /&gt;
# ==========================================&lt;br /&gt;
&lt;br /&gt;
if [[ $EUID -ne 0 ]]; then&lt;br /&gt;
   echo &amp;quot;Error: This script must be run as root. Try using: sudo $0&amp;quot;&lt;br /&gt;
   exit 1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Installing prerequisites...&amp;quot;&lt;br /&gt;
apt-get update&lt;br /&gt;
apt-get install -y curl gnupg&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Adding Salt Project repository for Ubuntu 24.04 LTS (Noble)...&amp;quot;&lt;br /&gt;
mkdir -p /etc/apt/keyrings&lt;br /&gt;
curl -fsSL -o /etc/apt/keyrings/salt-archive-keyring-2023.gpg \&lt;br /&gt;
  https://repo.saltproject.io/salt/py3/ubuntu/24.04/amd64/SALT-PROJECT-GPG-PUBKEY-2023.gpg&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;deb [signed-by=/etc/apt/keyrings/salt-archive-keyring-2023.gpg arch=amd64] https://repo.saltproject.io/salt/py3/ubuntu/24.04/amd64/3006 noble main&amp;quot; \&lt;br /&gt;
  | tee /etc/apt/sources.list.d/salt.list &amp;gt; /dev/null&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Installing Salt Minion...&amp;quot;&lt;br /&gt;
apt-get update&lt;br /&gt;
apt-get install -y salt-minion&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Configuring Minion to connect to $SALT_MASTER...&amp;quot;&lt;br /&gt;
mkdir -p /etc/salt/minion.d&lt;br /&gt;
echo &amp;quot;master: $SALT_MASTER&amp;quot; &amp;gt; /etc/salt/minion.d/master.conf&lt;br /&gt;
echo &amp;quot;$MINION_ID&amp;quot; &amp;gt; /etc/salt/minion_id&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Enabling and starting Salt Minion service...&amp;quot;&lt;br /&gt;
systemctl enable --now salt-minion&lt;br /&gt;
systemctl restart salt-minion&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==================================================&amp;quot;&lt;br /&gt;
echo &amp;quot;Success! The Salt Minion ($MINION_ID) is running.&amp;quot;&lt;br /&gt;
echo &amp;quot;It has sent its public key to $SALT_MASTER.&amp;quot;&lt;br /&gt;
echo &amp;quot;You must now log into the Master server and accept this key.&amp;quot;&lt;br /&gt;
echo &amp;quot;==================================================&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
# List pending keys to verify the minion showed up&lt;br /&gt;
docker compose exec salt-master salt-key -L&lt;br /&gt;
&lt;br /&gt;
# Accept the specific minion key&lt;br /&gt;
docker compose exec salt-master salt-key -a&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Rootless_docker&amp;diff=5726</id>
		<title>Rootless docker</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Rootless_docker&amp;diff=5726"/>
		<updated>2026-07-31T02:30:32Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Works on Ubuntu 24.04&lt;br /&gt;
&lt;br /&gt;
https://docs.docker.com/engine/security/rootless/&lt;br /&gt;
&lt;br /&gt;
install-rootless-docker-on-ubuntu.sh&lt;br /&gt;
```&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
set -e&lt;br /&gt;
&lt;br /&gt;
SERVICE_USER=&amp;quot;dockeruser&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# 1. Ensure script is run with sudo/root privileges&lt;br /&gt;
if [[ $EUID -ne 0 ]]; then&lt;br /&gt;
   echo &amp;quot;Error: This script must be run as root. Try using: sudo $0&amp;quot;&lt;br /&gt;
   exit 1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 2. PRE-SCRIPT SECTION&lt;br /&gt;
# ==========================================&lt;br /&gt;
echo &amp;quot;==&amp;gt; Running pre-installation tasks...&amp;quot;&lt;br /&gt;
# Add any commands you want to run before the setup begins right here.&lt;br /&gt;
# For example, you could source an external script if it exists:&lt;br /&gt;
# if [ -f &amp;quot;./pre-install.sh&amp;quot; ]; then&lt;br /&gt;
#     source ./pre-install.sh&lt;br /&gt;
# fi&lt;br /&gt;
#&lt;br /&gt;
# apt-get remove -y docker.io || true  # Example: remove old conflicting packages&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 3. DOCKER-CE &amp;amp; DEPENDENCY INSTALLATION&lt;br /&gt;
# ==========================================&lt;br /&gt;
echo &amp;quot;==&amp;gt; Setting up Docker's official apt repository...&amp;quot;&lt;br /&gt;
apt-get update&lt;br /&gt;
apt-get install -y ca-certificates curl&lt;br /&gt;
install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
echo \&lt;br /&gt;
  &amp;quot;deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \&lt;br /&gt;
  $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;$VERSION_CODENAME&amp;quot;) stable&amp;quot; | \&lt;br /&gt;
  tee /etc/apt/sources.list.d/docker.list &amp;gt; /dev/null&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Installing docker-ce and rootless dependencies...&amp;quot;&lt;br /&gt;
apt-get update&lt;br /&gt;
apt-get install -y \&lt;br /&gt;
  docker-ce docker-ce-cli containerd.io \&lt;br /&gt;
  docker-buildx-plugin docker-compose-plugin \&lt;br /&gt;
  docker-ce-rootless-extras uidmap dbus-user-session slirp4netns&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ==========================================&lt;br /&gt;
# 4. SYSTEM CONFIGURATION &amp;amp; ROOTLESS SETUP&lt;br /&gt;
# ==========================================&lt;br /&gt;
echo &amp;quot;==&amp;gt; Configuring Ubuntu 24.04 unprivileged user namespaces...&amp;quot;&lt;br /&gt;
sysctl -w kernel.unprivileged_userns_clone=1&lt;br /&gt;
echo &amp;quot;kernel.unprivileged_userns_clone=1&amp;quot; &amp;gt; /etc/sysctl.d/50-rootless-docker.conf&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Stopping and disabling rootful Docker to prevent socket conflicts...&amp;quot;&lt;br /&gt;
systemctl stop docker.service docker.socket || true&lt;br /&gt;
systemctl disable docker.service docker.socket || true&lt;br /&gt;
rm -f /var/run/docker.sock&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Creating dedicated user: $SERVICE_USER...&amp;quot;&lt;br /&gt;
if id &amp;quot;$SERVICE_USER&amp;quot; &amp;amp;&amp;gt;/dev/null; then&lt;br /&gt;
    echo &amp;quot;User $SERVICE_USER already exists, skipping creation.&amp;quot;&lt;br /&gt;
else&lt;br /&gt;
    useradd -m -s /bin/bash &amp;quot;$SERVICE_USER&amp;quot;&lt;br /&gt;
    echo &amp;quot;User $SERVICE_USER created successfully.&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Enabling user lingering (ensures containers run without active SSH session)...&amp;quot;&lt;br /&gt;
loginctl enable-linger &amp;quot;$SERVICE_USER&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Wait a moment for systemd to initialize the new user's DBUS environment&lt;br /&gt;
sleep 2&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Installing Rootless Docker as $SERVICE_USER...&amp;quot;&lt;br /&gt;
sudo -i -u &amp;quot;$SERVICE_USER&amp;quot; bash &amp;lt;&amp;lt; 'EOF'&lt;br /&gt;
    # Define systemd runtime variables for the user session&lt;br /&gt;
    export XDG_RUNTIME_DIR=&amp;quot;/run/user/$(id -u)&amp;quot;&lt;br /&gt;
    export DBUS_SESSION_BUS_ADDRESS=&amp;quot;unix:path=${XDG_RUNTIME_DIR}/bus&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # Run the rootless installer&lt;br /&gt;
    dockerd-rootless-setuptool.sh install&lt;br /&gt;
&lt;br /&gt;
    # Configure .bashrc for future logins&lt;br /&gt;
    if ! grep -q &amp;quot;DOCKER_HOST&amp;quot; ~/.bashrc; then&lt;br /&gt;
        echo 'export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock' &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
        echo 'export PATH=/usr/bin:$PATH' &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
    fi&lt;br /&gt;
&lt;br /&gt;
    # Start and enable the systemd service for Docker&lt;br /&gt;
    systemctl --user enable --now docker&lt;br /&gt;
&lt;br /&gt;
    echo &amp;quot;==&amp;gt; Rootless Docker installed successfully for $(whoami)!&amp;quot;&lt;br /&gt;
    docker info | grep -i rootless&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Script complete!&amp;quot;&lt;br /&gt;
echo &amp;quot;To manage your containers, switch to the new user by running:&amp;quot;&lt;br /&gt;
echo &amp;quot;sudo su - $SERVICE_USER&amp;quot;&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Rootless_docker&amp;diff=5725</id>
		<title>Rootless docker</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Rootless_docker&amp;diff=5725"/>
		<updated>2026-07-31T02:01:46Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Works on Ubuntu 24.04&lt;br /&gt;
&lt;br /&gt;
https://docs.docker.com/engine/security/rootless/&lt;br /&gt;
&lt;br /&gt;
install-rootless-docker-on-ubuntu.sh&lt;br /&gt;
```&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
set -e&lt;br /&gt;
&lt;br /&gt;
SERVICE_USER=&amp;quot;dockeruser&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# 1. Ensure script is run with sudo/root privileges&lt;br /&gt;
if [[ $EUID -ne 0 ]]; then&lt;br /&gt;
   echo &amp;quot;Error: This script must be run as root. Try using: sudo $0&amp;quot;&lt;br /&gt;
   exit 1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Installing dependencies...&amp;quot;&lt;br /&gt;
apt-get update&lt;br /&gt;
apt-get install -y uidmap dbus-user-session slirp4netns docker-ce-rootless-extras&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Configuring Ubuntu 24.04 unprivileged user namespaces...&amp;quot;&lt;br /&gt;
sysctl -w kernel.unprivileged_userns_clone=1&lt;br /&gt;
echo &amp;quot;kernel.unprivileged_userns_clone=1&amp;quot; &amp;gt; /etc/sysctl.d/50-rootless-docker.conf&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Stopping and disabling rootful Docker to prevent socket conflicts...&amp;quot;&lt;br /&gt;
systemctl stop docker.service docker.socket || true&lt;br /&gt;
systemctl disable docker.service docker.socket || true&lt;br /&gt;
rm -f /var/run/docker.sock&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Creating dedicated user: $SERVICE_USER...&amp;quot;&lt;br /&gt;
if id &amp;quot;$SERVICE_USER&amp;quot; &amp;amp;&amp;gt;/dev/null; then&lt;br /&gt;
    echo &amp;quot;User $SERVICE_USER already exists, skipping creation.&amp;quot;&lt;br /&gt;
else&lt;br /&gt;
    useradd -m -s /bin/bash &amp;quot;$SERVICE_USER&amp;quot;&lt;br /&gt;
    echo &amp;quot;User $SERVICE_USER created successfully.&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Enabling user lingering (ensures containers run without active SSH session)...&amp;quot;&lt;br /&gt;
loginctl enable-linger &amp;quot;$SERVICE_USER&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Wait a moment for systemd to initialize the new user's DBUS environment&lt;br /&gt;
sleep 2&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Installing Rootless Docker as $SERVICE_USER...&amp;quot;&lt;br /&gt;
# We use sudo to switch users and explicitly set XDG_RUNTIME_DIR so systemctl --user works&lt;br /&gt;
sudo -i -u &amp;quot;$SERVICE_USER&amp;quot; bash &amp;lt;&amp;lt; 'EOF'&lt;br /&gt;
    # Define systemd runtime variables for the user session&lt;br /&gt;
    export XDG_RUNTIME_DIR=&amp;quot;/run/user/$(id -u)&amp;quot;&lt;br /&gt;
    export DBUS_SESSION_BUS_ADDRESS=&amp;quot;unix:path=${XDG_RUNTIME_DIR}/bus&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # Run the rootless installer&lt;br /&gt;
    dockerd-rootless-setuptool.sh install&lt;br /&gt;
&lt;br /&gt;
    # Configure .bashrc for future logins&lt;br /&gt;
    if ! grep -q &amp;quot;DOCKER_HOST&amp;quot; ~/.bashrc; then&lt;br /&gt;
        echo 'export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock' &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
        echo 'export PATH=/usr/bin:$PATH' &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
    fi&lt;br /&gt;
&lt;br /&gt;
    # Start and enable the systemd service for Docker&lt;br /&gt;
    systemctl --user enable --now docker&lt;br /&gt;
&lt;br /&gt;
    echo &amp;quot;==&amp;gt; Rootless Docker installed successfully for $(whoami)!&amp;quot;&lt;br /&gt;
    docker info | grep -i rootless&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Script complete!&amp;quot;&lt;br /&gt;
echo &amp;quot;To manage your containers, switch to the new user by running:&amp;quot;&lt;br /&gt;
echo &amp;quot;sudo su - $SERVICE_USER&amp;quot;&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Rootless_docker&amp;diff=5724</id>
		<title>Rootless docker</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Rootless_docker&amp;diff=5724"/>
		<updated>2026-07-31T02:00:06Z</updated>

		<summary type="html">&lt;p&gt;Busk: Created page with &amp;quot;Works on Ubuntu 24.04  install-rootless-docker-on-ubuntu.sh ``` #!/bin/bash set -e  SERVICE_USER=&amp;quot;dockeruser&amp;quot;  # 1. Ensure script is run with sudo/root privileges if  $EUID...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Works on Ubuntu 24.04&lt;br /&gt;
&lt;br /&gt;
install-rootless-docker-on-ubuntu.sh&lt;br /&gt;
```&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
set -e&lt;br /&gt;
&lt;br /&gt;
SERVICE_USER=&amp;quot;dockeruser&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# 1. Ensure script is run with sudo/root privileges&lt;br /&gt;
if [[ $EUID -ne 0 ]]; then&lt;br /&gt;
   echo &amp;quot;Error: This script must be run as root. Try using: sudo $0&amp;quot;&lt;br /&gt;
   exit 1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Installing dependencies...&amp;quot;&lt;br /&gt;
apt-get update&lt;br /&gt;
apt-get install -y uidmap dbus-user-session slirp4netns docker-ce-rootless-extras&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Configuring Ubuntu 24.04 unprivileged user namespaces...&amp;quot;&lt;br /&gt;
sysctl -w kernel.unprivileged_userns_clone=1&lt;br /&gt;
echo &amp;quot;kernel.unprivileged_userns_clone=1&amp;quot; &amp;gt; /etc/sysctl.d/50-rootless-docker.conf&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Stopping and disabling rootful Docker to prevent socket conflicts...&amp;quot;&lt;br /&gt;
systemctl stop docker.service docker.socket || true&lt;br /&gt;
systemctl disable docker.service docker.socket || true&lt;br /&gt;
rm -f /var/run/docker.sock&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Creating dedicated user: $SERVICE_USER...&amp;quot;&lt;br /&gt;
if id &amp;quot;$SERVICE_USER&amp;quot; &amp;amp;&amp;gt;/dev/null; then&lt;br /&gt;
    echo &amp;quot;User $SERVICE_USER already exists, skipping creation.&amp;quot;&lt;br /&gt;
else&lt;br /&gt;
    useradd -m -s /bin/bash &amp;quot;$SERVICE_USER&amp;quot;&lt;br /&gt;
    echo &amp;quot;User $SERVICE_USER created successfully.&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Enabling user lingering (ensures containers run without active SSH session)...&amp;quot;&lt;br /&gt;
loginctl enable-linger &amp;quot;$SERVICE_USER&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Wait a moment for systemd to initialize the new user's DBUS environment&lt;br /&gt;
sleep 2&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Installing Rootless Docker as $SERVICE_USER...&amp;quot;&lt;br /&gt;
# We use sudo to switch users and explicitly set XDG_RUNTIME_DIR so systemctl --user works&lt;br /&gt;
sudo -i -u &amp;quot;$SERVICE_USER&amp;quot; bash &amp;lt;&amp;lt; 'EOF'&lt;br /&gt;
    # Define systemd runtime variables for the user session&lt;br /&gt;
    export XDG_RUNTIME_DIR=&amp;quot;/run/user/$(id -u)&amp;quot;&lt;br /&gt;
    export DBUS_SESSION_BUS_ADDRESS=&amp;quot;unix:path=${XDG_RUNTIME_DIR}/bus&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # Run the rootless installer&lt;br /&gt;
    dockerd-rootless-setuptool.sh install&lt;br /&gt;
&lt;br /&gt;
    # Configure .bashrc for future logins&lt;br /&gt;
    if ! grep -q &amp;quot;DOCKER_HOST&amp;quot; ~/.bashrc; then&lt;br /&gt;
        echo 'export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock' &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
        echo 'export PATH=/usr/bin:$PATH' &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
    fi&lt;br /&gt;
&lt;br /&gt;
    # Start and enable the systemd service for Docker&lt;br /&gt;
    systemctl --user enable --now docker&lt;br /&gt;
&lt;br /&gt;
    echo &amp;quot;==&amp;gt; Rootless Docker installed successfully for $(whoami)!&amp;quot;&lt;br /&gt;
    docker info | grep -i rootless&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;==&amp;gt; Script complete!&amp;quot;&lt;br /&gt;
echo &amp;quot;To manage your containers, switch to the new user by running:&amp;quot;&lt;br /&gt;
echo &amp;quot;sudo su - $SERVICE_USER&amp;quot;&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Tpm2&amp;diff=5723</id>
		<title>Tpm2</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Tpm2&amp;diff=5723"/>
		<updated>2026-07-31T01:03:51Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ubuntu 24.04&lt;br /&gt;
ls -l /dev/tpm*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
# 1. Update your package lists and install the Clevis toolset&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install clevis clevis-tpm2 clevis-luks clevis-initramfs&lt;br /&gt;
&lt;br /&gt;
# 2. Bind your LUKS partition to the TPM (specifying sha256 to prevent errors)&lt;br /&gt;
sudo clevis luks bind -d /dev/nvme0n1p3 tpm2 '{&amp;quot;pcr_bank&amp;quot;:&amp;quot;sha256&amp;quot;,&amp;quot;pcr_ids&amp;quot;:&amp;quot;1,4,7&amp;quot;}'&lt;br /&gt;
&lt;br /&gt;
# 3. Rebuild the boot image so the Clevis decryption hooks load during early boot&lt;br /&gt;
sudo update-initramfs -u -k all&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
reboot&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Tpm2&amp;diff=5722</id>
		<title>Tpm2</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Tpm2&amp;diff=5722"/>
		<updated>2026-07-30T22:22:57Z</updated>

		<summary type="html">&lt;p&gt;Busk: Created page with &amp;quot;Ubuntu 24.04 ls -l /dev/tpm* sudo apt install libtss2-rc0t64 libtss2-esys-3.0.2-0t64 tpm2-tools systemd-cryptenroll --tpm2-device=list lsblk -f | grep -i luk sudo systemd-cryp...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ubuntu 24.04&lt;br /&gt;
ls -l /dev/tpm*&lt;br /&gt;
sudo apt install libtss2-rc0t64 libtss2-esys-3.0.2-0t64 tpm2-tools&lt;br /&gt;
systemd-cryptenroll --tpm2-device=list&lt;br /&gt;
lsblk -f | grep -i luk&lt;br /&gt;
sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=1+4+7 /dev/nvme0n1p3&lt;br /&gt;
sudo reboot&lt;br /&gt;
sudo update-initramfs -u -k all&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Codex_gemini_install_cli&amp;diff=5721</id>
		<title>Codex gemini install cli</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Codex_gemini_install_cli&amp;diff=5721"/>
		<updated>2026-07-26T02:01:05Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;# Debian/Ubuntu&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
sudo apt-get remove -y nodejs npm&lt;br /&gt;
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -&lt;br /&gt;
sudo apt-get install -y nodejs&lt;br /&gt;
&lt;br /&gt;
mkdir -p ~/.npm-global&lt;br /&gt;
npm config set prefix '~/.npm-global'&lt;br /&gt;
export PATH=~/.npm-global/bin:$PATH&lt;br /&gt;
echo 'export PATH=~/.npm-global/bin:$PATH' &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
&lt;br /&gt;
npm install -g npm@latest&lt;br /&gt;
npm install -g --allow-scripts=@github/keytar,node-pty @openai/codex @google/gemini-cli&lt;br /&gt;
&lt;br /&gt;
codex --version&lt;br /&gt;
gemini --version&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Codex_gemini_install_cli&amp;diff=5720</id>
		<title>Codex gemini install cli</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Codex_gemini_install_cli&amp;diff=5720"/>
		<updated>2026-07-26T01:57:23Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;# Debian/Ubuntu&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
sudo apt-get remove -y nodejs npm&lt;br /&gt;
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -&lt;br /&gt;
sudo apt-get install -y nodejs&lt;br /&gt;
sudo npm install -g npm@latest&lt;br /&gt;
sudo npm install -g npm@latest @openai/codex @google/gemini-cli&lt;br /&gt;
codex --version&lt;br /&gt;
gemini --version&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Kubectl_sniff&amp;diff=5719</id>
		<title>Kubectl sniff</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Kubectl_sniff&amp;diff=5719"/>
		<updated>2026-07-25T21:16:09Z</updated>

		<summary type="html">&lt;p&gt;Busk: Created page with &amp;quot;kubectl debug -i my-container-77c5f975d8-mt7mm -n my-ns  --image=nicolaka/netshoot   --target=my-container   --profile=netadmin   -- tcpdump -i any -nn -A -s 0 'tcp port 8080'...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;kubectl debug -i my-container-77c5f975d8-mt7mm -n my-ns  --image=nicolaka/netshoot   --target=my-container   --profile=netadmin   -- tcpdump -i any -nn -A -s 0 'tcp port 8080' | grep -iE 'X-Forwarded-For|Host:'&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Cka_kubeadm_init_upgrade&amp;diff=5718</id>
		<title>Cka kubeadm init upgrade</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Cka_kubeadm_init_upgrade&amp;diff=5718"/>
		<updated>2026-07-24T17:30:10Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;## Prep Ubuntu 24.04 &amp;amp; 22.04 Node&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
set -eu&lt;br /&gt;
&lt;br /&gt;
k8s_minor_version=1.31&lt;br /&gt;
&lt;br /&gt;
prep_k8s_node(){&lt;br /&gt;
  sudo apt update &amp;amp;&amp;amp; sudo apt upgrade -y&lt;br /&gt;
  sudo apt install apt-transport-https curl -y&lt;br /&gt;
&lt;br /&gt;
  # https://kubernetes.io/docs/setup/production-environment/container-runtimes/&lt;br /&gt;
  sudo apt install containerd -y&lt;br /&gt;
  sudo mkdir -p /etc/containerd&lt;br /&gt;
  containerd config default | sudo tee /etc/containerd/config.toml &amp;gt; /dev/null&lt;br /&gt;
  #  Instruct containerd to use the Systemd cgroup hierarchy (typically cgroupv2) for managing container resources.&lt;br /&gt;
  sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml&lt;br /&gt;
  sudo systemctl restart containerd&lt;br /&gt;
  echo &amp;quot;net.ipv4.ip_forward = 1&amp;quot; | /etc/sysctl.d/k8s.conf&lt;br /&gt;
  sudo sysctl --system&lt;br /&gt;
&lt;br /&gt;
  # https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#installing-kubeadm-kubelet-and-kubectl&lt;br /&gt;
  curl -fsSL https://pkgs.k8s.io/core:/stable:/v${k8s_minor_version}/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg&lt;br /&gt;
  echo &amp;quot;deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v${k8s_minor_version}/deb/ /&amp;quot; | sudo tee /etc/apt/sources.list.d/kubernetes.list&lt;br /&gt;
  sudo apt update&lt;br /&gt;
  sudo apt install -y kubelet kubeadm kubectl&lt;br /&gt;
  sudo apt-mark hold kubelet kubeadm kubectl&lt;br /&gt;
&lt;br /&gt;
  swapon -s # returns summary text if swap is enabled&lt;br /&gt;
  sudo swapoff -a&lt;br /&gt;
  sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab&lt;br /&gt;
&lt;br /&gt;
  # overlay is already modprobed by containerd&lt;br /&gt;
  sudo modprobe br_netfilter&lt;br /&gt;
  echo -e &amp;quot;br_netfilter&amp;quot; | sudo tee /etc/modules-load.d/k8s.conf&lt;br /&gt;
  lsmod | grep overlay&lt;br /&gt;
  lsmod | grep br_netfilter&lt;br /&gt;
&lt;br /&gt;
  echo &amp;quot;export KUBECONFIG=/etc/kubernetes/admin.conf&amp;quot; &amp;gt;&amp;gt; ~/.bashrc&lt;br /&gt;
  sudo reboot&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
prep_k8s_node&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## Install kubeadm kubectl kubelet&lt;br /&gt;
&lt;br /&gt;
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#installing-kubeadm-kubelet-and-kubectl&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
sudo apt-get update&lt;br /&gt;
# apt-transport-https may be a dummy package; if so, you can skip that package&lt;br /&gt;
sudo apt-get install -y apt-transport-https ca-certificates curl gpg&lt;br /&gt;
&lt;br /&gt;
# If the directory `/etc/apt/keyrings` does not exist, it should be created before the curl command, read the note below.&lt;br /&gt;
# sudo mkdir -p -m 755 /etc/apt/keyrings&lt;br /&gt;
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.32/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg&lt;br /&gt;
&lt;br /&gt;
# This overwrites any existing configuration in /etc/apt/sources.list.d/kubernetes.list&lt;br /&gt;
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.32/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list&lt;br /&gt;
&lt;br /&gt;
sudo apt-get update&lt;br /&gt;
sudo apt-get install -y kubelet kubeadm kubectl&lt;br /&gt;
sudo apt-mark hold kubelet kubeadm kubectl&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## Init Control Plane&lt;br /&gt;
&lt;br /&gt;
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#initializing-your-control-plane-node&lt;br /&gt;
&lt;br /&gt;
HA with LB for control see - https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/high-availability/ - --control-plane-endpoint&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
kubeadm init --apiserver-advertise-address &amp;lt;local ip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## Cilium&lt;br /&gt;
&lt;br /&gt;
This is only needed on one node in the cluster for admin functions if wanted as helm is what installs cilium agent on k8s nodes&lt;br /&gt;
&lt;br /&gt;
https://kubernetes.io/docs/tasks/administer-cluster/network-policy-provider/cilium-network-policy/&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
https://kubernetes.io/docs/tasks/administer-cluster/network-policy-provider/cilium-network-policy/&lt;br /&gt;
sudo tar xzvfC cilium-linux-amd64.tar.gz /usr/local/bin&lt;br /&gt;
rm cilium-linux-amd64.tar.gz&lt;br /&gt;
cilium install &amp;amp;&amp;amp; cilium wait status&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## Join worker node&lt;br /&gt;
```&lt;br /&gt;
kubeadm join&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## Enable metrics-server api for kubectl top node&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
helm search hub metrics-server -o yaml&lt;br /&gt;
helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server/&lt;br /&gt;
helm install metrics-server metrics-server/metrics-server --set args[0]='--kubelet-insecure-tls'&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Docker_install_ubuntu&amp;diff=5717</id>
		<title>Docker install ubuntu</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Docker_install_ubuntu&amp;diff=5717"/>
		<updated>2026-07-15T17:05:45Z</updated>

		<summary type="html">&lt;p&gt;Busk: Created page with &amp;quot;``` sudo apt update sudo apt install -y ca-certificates curl gnupg  sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;```&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y ca-certificates curl gnupg&lt;br /&gt;
&lt;br /&gt;
sudo install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
sudo chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Lxc_launch&amp;diff=5716</id>
		<title>Lxc launch</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Lxc_launch&amp;diff=5716"/>
		<updated>2026-07-15T17:00:03Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;lxc launch images:debian/11 bullseye-vm --vm&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
lxc --target lxdnode1 init ubuntu:22.04 --vm -c limits.cpu=6 -c limits.memory=12GB docker&lt;br /&gt;
lxc config device override docker root size=100GB&lt;br /&gt;
lxc start docker&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
lxc launch images:debian/11 docker-server --vm -c limits.cpu=4 -c limits.memory=12GiB -d root,size=50GiB&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
s. Assumptions: 1) One zfs pool called ‘default’ that lives on the hard drive at /var/lib/lxd/disks/default.img. 2) Running as root. 3) Growing pool ‘default’ from 25GB to 45GB. Stop all running containers. #truncate -s +20G /var/lib/lxd/disks/default.img #zpool set autoexpand=on default #zpool status -vg default 4a. Note th…&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
lxc init images:ubuntu/focal ${VM} -p default -p vm --vm&lt;br /&gt;
lxc config set ${VM} limits.cpu ${CPU}&lt;br /&gt;
lxc config set ${VM} limits.memory ${MEM}&lt;br /&gt;
lxc config device override ${VM} root size=${DISK}&lt;br /&gt;
lxc start ${VM}&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
# Centos7&lt;br /&gt;
```&lt;br /&gt;
lxc launch images:centos/7/amd64 centos7 &lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Envoy_from_nginx_for_ingress&amp;diff=5715</id>
		<title>Envoy from nginx for ingress</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Envoy_from_nginx_for_ingress&amp;diff=5715"/>
		<updated>2026-06-22T05:29:40Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;go install github.com/kubernetes-sigs/ingress2gateway@latest&lt;br /&gt;
&lt;br /&gt;
# Translate an existing NGINX ingress into Gateway API manifests&lt;br /&gt;
ingress2gateway print --providers ingress-nginx &amp;gt; new-envoy-routes.yaml&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ingress-to-envoy-gateway.sh&lt;br /&gt;
```&lt;br /&gt;
#!/usr/bin/env bash&lt;br /&gt;
set -euo pipefail&lt;br /&gt;
&lt;br /&gt;
usage() {&lt;br /&gt;
  cat &amp;lt;&amp;lt;'USAGE'&lt;br /&gt;
Usage:&lt;br /&gt;
  scripts/ingress-to-envoy-gateway.sh -n NAMESPACE INGRESS [options]&lt;br /&gt;
&lt;br /&gt;
Converts one Kubernetes Ingress into Gateway API resources for Envoy Gateway.&lt;br /&gt;
By default the script prints YAML. Use --apply to apply it.&lt;br /&gt;
&lt;br /&gt;
Options:&lt;br /&gt;
  --gateway NAME                 Gateway name. Default: INGRESS-gateway&lt;br /&gt;
  --gateway-namespace NAMESPACE  Gateway namespace. Default: Ingress namespace&lt;br /&gt;
  --use-existing-gateway         Do not emit a Gateway; attach routes to --gateway&lt;br /&gt;
  --gateway-class NAME           GatewayClass name. Default: eg&lt;br /&gt;
  --issuer NAME                  ClusterIssuer name for generated Certificates. Default: letsencrypt-prod&lt;br /&gt;
  --emit-certificate             Emit cert-manager Certificate resources for Ingress TLS secrets.&lt;br /&gt;
                                  With --use-existing-gateway, Certificates are emitted in&lt;br /&gt;
                                  the Gateway namespace and --apply patches the Gateway&lt;br /&gt;
                                  HTTPS listener certificateRefs.&lt;br /&gt;
  --force-tls                    Route to the HTTPS listener even if the Ingress has no TLS block&lt;br /&gt;
  --tls-secret NAME              TLS Secret/Certificate name to use with --force-tls&lt;br /&gt;
  --backend-tls none|system|ca   Handle nginx backend-protocol=HTTPS. Default: none&lt;br /&gt;
  --backend-tls-hostname NAME    SNI/validation hostname for BackendTLSPolicy. Default: first Ingress host&lt;br /&gt;
  --backend-tls-ca-configmap NAME&lt;br /&gt;
                                  ConfigMap with ca.crt when --backend-tls=ca&lt;br /&gt;
  --apply                        Apply generated YAML instead of printing it&lt;br /&gt;
  -h, --help                     Show this help&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
  # Preview conversion for uapp/ucontrol-ui.&lt;br /&gt;
  scripts/ingress-to-envoy-gateway.sh -n uapp ucontrol-ui --backend-tls system&lt;br /&gt;
&lt;br /&gt;
  # Apply conversion.&lt;br /&gt;
  scripts/ingress-to-envoy-gateway.sh -n uapp ucontrol-ui --backend-tls system --apply&lt;br /&gt;
&lt;br /&gt;
  # Attach uapp/ucontrol-ui to an existing central Gateway.&lt;br /&gt;
  scripts/ingress-to-envoy-gateway.sh -n uapp ucontrol-ui \&lt;br /&gt;
    --use-existing-gateway \&lt;br /&gt;
    --gateway default-gateway \&lt;br /&gt;
    --gateway-namespace example-io \&lt;br /&gt;
    --backend-tls system&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
  - The original Ingress is not changed or deleted.&lt;br /&gt;
  - DNS must be moved to the new Envoy Gateway IP after verification.&lt;br /&gt;
  - nginx.ingress.kubernetes.io/backend-protocol=HTTPS requires BackendTLSPolicy.&lt;br /&gt;
    Use --backend-tls system for publicly trusted backend certs, or --backend-tls ca&lt;br /&gt;
    with --backend-tls-ca-configmap for private CAs.&lt;br /&gt;
USAGE&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
die() {&lt;br /&gt;
  printf 'error: %s\n' &amp;quot;$*&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
  exit 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
need() {&lt;br /&gt;
  command -v &amp;quot;$1&amp;quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || die &amp;quot;missing required command: $1&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
default_kubectl() {&lt;br /&gt;
  if [[ -x /snap/kubectl/current/kubectl ]]; then&lt;br /&gt;
    printf '%s\n' /snap/kubectl/current/kubectl&lt;br /&gt;
  else&lt;br /&gt;
    printf '%s\n' kubectl&lt;br /&gt;
  fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
yaml_quote() {&lt;br /&gt;
  printf '%s' &amp;quot;$1&amp;quot; | sed &amp;quot;s/'/''/g; s/^/'/; s/$/'/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
resource_name() {&lt;br /&gt;
  printf '%s' &amp;quot;$1&amp;quot; | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9.-]+/-/g; s/^-+//; s/-+$//' | cut -c1-63&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
resolve_service_port() {&lt;br /&gt;
  local svc=&amp;quot;$1&amp;quot;&lt;br /&gt;
  local port_name=&amp;quot;$2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;$kubectl_cmd&amp;quot; get svc -n &amp;quot;$namespace&amp;quot; &amp;quot;$svc&amp;quot; -o json |&lt;br /&gt;
    jq -r --arg name &amp;quot;$port_name&amp;quot; '&lt;br /&gt;
      .spec.ports[] | select(.name == $name) | .port&lt;br /&gt;
    ' | head -n 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
gateway_has_cert_ref() {&lt;br /&gt;
  local secret=&amp;quot;$1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;$kubectl_cmd&amp;quot; get gateway -n &amp;quot;$gateway_namespace&amp;quot; &amp;quot;$gateway&amp;quot; -o json |&lt;br /&gt;
    jq -e --arg secret &amp;quot;$secret&amp;quot; '&lt;br /&gt;
      .spec.listeners[]&lt;br /&gt;
      | select(.name == &amp;quot;https&amp;quot;)&lt;br /&gt;
      | (.tls.certificateRefs // [])&lt;br /&gt;
      | any(.name == $secret)&lt;br /&gt;
    ' &amp;gt;/dev/null&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
patch_gateway_cert_ref() {&lt;br /&gt;
  local secret=&amp;quot;$1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  if gateway_has_cert_ref &amp;quot;$secret&amp;quot;; then&lt;br /&gt;
    printf 'Gateway %s/%s already references TLS secret %s\n' &amp;quot;$gateway_namespace&amp;quot; &amp;quot;$gateway&amp;quot; &amp;quot;$secret&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
    return&lt;br /&gt;
  fi&lt;br /&gt;
&lt;br /&gt;
  &amp;quot;$kubectl_cmd&amp;quot; patch gateway &amp;quot;$gateway&amp;quot; -n &amp;quot;$gateway_namespace&amp;quot; --type json \&lt;br /&gt;
    -p=&amp;quot;[{\&amp;quot;op\&amp;quot;:\&amp;quot;add\&amp;quot;,\&amp;quot;path\&amp;quot;:\&amp;quot;/spec/listeners/1/tls/certificateRefs/-\&amp;quot;,\&amp;quot;value\&amp;quot;:{\&amp;quot;name\&amp;quot;:\&amp;quot;$secret\&amp;quot;}}]&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
namespace=&amp;quot;&amp;quot;&lt;br /&gt;
ingress=&amp;quot;&amp;quot;&lt;br /&gt;
gateway=&amp;quot;&amp;quot;&lt;br /&gt;
gateway_namespace=&amp;quot;&amp;quot;&lt;br /&gt;
create_gateway=&amp;quot;true&amp;quot;&lt;br /&gt;
gateway_class=&amp;quot;eg&amp;quot;&lt;br /&gt;
issuer=&amp;quot;letsencrypt-prod&amp;quot;&lt;br /&gt;
emit_certificate=&amp;quot;false&amp;quot;&lt;br /&gt;
backend_tls=&amp;quot;none&amp;quot;&lt;br /&gt;
backend_tls_hostname=&amp;quot;&amp;quot;&lt;br /&gt;
backend_tls_ca_configmap=&amp;quot;&amp;quot;&lt;br /&gt;
force_tls=&amp;quot;false&amp;quot;&lt;br /&gt;
tls_secret_override=&amp;quot;&amp;quot;&lt;br /&gt;
apply=&amp;quot;false&amp;quot;&lt;br /&gt;
kubectl_cmd=&amp;quot;${KUBECTL:-$(default_kubectl)}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
while [[ $# -gt 0 ]]; do&lt;br /&gt;
  case &amp;quot;$1&amp;quot; in&lt;br /&gt;
    -n|--namespace)&lt;br /&gt;
      namespace=&amp;quot;${2:-}&amp;quot;&lt;br /&gt;
      shift 2&lt;br /&gt;
      ;;&lt;br /&gt;
    --gateway)&lt;br /&gt;
      gateway=&amp;quot;${2:-}&amp;quot;&lt;br /&gt;
      shift 2&lt;br /&gt;
      ;;&lt;br /&gt;
    --gateway-namespace)&lt;br /&gt;
      gateway_namespace=&amp;quot;${2:-}&amp;quot;&lt;br /&gt;
      shift 2&lt;br /&gt;
      ;;&lt;br /&gt;
    --use-existing-gateway)&lt;br /&gt;
      create_gateway=&amp;quot;false&amp;quot;&lt;br /&gt;
      shift&lt;br /&gt;
      ;;&lt;br /&gt;
    --gateway-class)&lt;br /&gt;
      gateway_class=&amp;quot;${2:-}&amp;quot;&lt;br /&gt;
      shift 2&lt;br /&gt;
      ;;&lt;br /&gt;
    --issuer)&lt;br /&gt;
      issuer=&amp;quot;${2:-}&amp;quot;&lt;br /&gt;
      shift 2&lt;br /&gt;
      ;;&lt;br /&gt;
    --emit-certificate)&lt;br /&gt;
      emit_certificate=&amp;quot;true&amp;quot;&lt;br /&gt;
      shift&lt;br /&gt;
      ;;&lt;br /&gt;
    --force-tls)&lt;br /&gt;
      force_tls=&amp;quot;true&amp;quot;&lt;br /&gt;
      shift&lt;br /&gt;
      ;;&lt;br /&gt;
    --tls-secret)&lt;br /&gt;
      tls_secret_override=&amp;quot;${2:-}&amp;quot;&lt;br /&gt;
      shift 2&lt;br /&gt;
      ;;&lt;br /&gt;
    --backend-tls)&lt;br /&gt;
      backend_tls=&amp;quot;${2:-}&amp;quot;&lt;br /&gt;
      shift 2&lt;br /&gt;
      ;;&lt;br /&gt;
    --backend-tls-hostname)&lt;br /&gt;
      backend_tls_hostname=&amp;quot;${2:-}&amp;quot;&lt;br /&gt;
      shift 2&lt;br /&gt;
      ;;&lt;br /&gt;
    --backend-tls-ca-configmap)&lt;br /&gt;
      backend_tls_ca_configmap=&amp;quot;${2:-}&amp;quot;&lt;br /&gt;
      shift 2&lt;br /&gt;
      ;;&lt;br /&gt;
    --apply)&lt;br /&gt;
      apply=&amp;quot;true&amp;quot;&lt;br /&gt;
      shift&lt;br /&gt;
      ;;&lt;br /&gt;
    -h|--help)&lt;br /&gt;
      usage&lt;br /&gt;
      exit 0&lt;br /&gt;
      ;;&lt;br /&gt;
    -*)&lt;br /&gt;
      die &amp;quot;unknown option: $1&amp;quot;&lt;br /&gt;
      ;;&lt;br /&gt;
    *)&lt;br /&gt;
      if [[ -n &amp;quot;$ingress&amp;quot; ]]; then&lt;br /&gt;
        die &amp;quot;unexpected extra argument: $1&amp;quot;&lt;br /&gt;
      fi&lt;br /&gt;
      ingress=&amp;quot;$1&amp;quot;&lt;br /&gt;
      shift&lt;br /&gt;
      ;;&lt;br /&gt;
  esac&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
[[ -n &amp;quot;$namespace&amp;quot; ]] || die &amp;quot;namespace is required&amp;quot;&lt;br /&gt;
[[ -n &amp;quot;$ingress&amp;quot; ]] || die &amp;quot;ingress name is required&amp;quot;&lt;br /&gt;
case &amp;quot;$backend_tls&amp;quot; in&lt;br /&gt;
  none|system|ca) ;;&lt;br /&gt;
  *) die &amp;quot;--backend-tls must be one of: none, system, ca&amp;quot; ;;&lt;br /&gt;
esac&lt;br /&gt;
if [[ &amp;quot;$backend_tls&amp;quot; == &amp;quot;ca&amp;quot; &amp;amp;&amp;amp; -z &amp;quot;$backend_tls_ca_configmap&amp;quot; ]]; then&lt;br /&gt;
  die &amp;quot;--backend-tls-ca-configmap is required when --backend-tls=ca&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
if [[ &amp;quot;$force_tls&amp;quot; == &amp;quot;true&amp;quot; &amp;amp;&amp;amp; -z &amp;quot;$tls_secret_override&amp;quot; ]]; then&lt;br /&gt;
  die &amp;quot;--tls-secret is required when --force-tls is set&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
need jq&lt;br /&gt;
need sed&lt;br /&gt;
need tr&lt;br /&gt;
need cut&lt;br /&gt;
need head&lt;br /&gt;
if [[ &amp;quot;$kubectl_cmd&amp;quot; == */* ]]; then&lt;br /&gt;
  [[ -x &amp;quot;$kubectl_cmd&amp;quot; ]] || die &amp;quot;kubectl is not executable: $kubectl_cmd&amp;quot;&lt;br /&gt;
else&lt;br /&gt;
  need &amp;quot;$kubectl_cmd&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
gateway=&amp;quot;${gateway:-$(resource_name &amp;quot;${ingress}-gateway&amp;quot;)}&amp;quot;&lt;br /&gt;
gateway_namespace=&amp;quot;${gateway_namespace:-$namespace}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ingress_json=&amp;quot;$(&amp;quot;$kubectl_cmd&amp;quot; get ingress -n &amp;quot;$namespace&amp;quot; &amp;quot;$ingress&amp;quot; -o json)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
mapfile -t hosts &amp;lt; &amp;lt;(jq -r '.spec.rules[]?.host // empty' &amp;lt;&amp;lt;&amp;lt;&amp;quot;$ingress_json&amp;quot; | awk 'NF' | sort -u)&lt;br /&gt;
[[ &amp;quot;${#hosts[@]}&amp;quot; -gt 0 ]] || die &amp;quot;Ingress has no host rules&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if [[ -z &amp;quot;$backend_tls_hostname&amp;quot; ]]; then&lt;br /&gt;
  backend_tls_hostname=&amp;quot;${hosts[0]}&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
mapfile -t tls_secrets &amp;lt; &amp;lt;(jq -r '.spec.tls[]?.secretName // empty' &amp;lt;&amp;lt;&amp;lt;&amp;quot;$ingress_json&amp;quot; | awk 'NF' | sort -u)&lt;br /&gt;
if [[ -n &amp;quot;$tls_secret_override&amp;quot; ]]; then&lt;br /&gt;
  tls_secrets=(&amp;quot;$tls_secret_override&amp;quot;)&lt;br /&gt;
fi&lt;br /&gt;
has_tls=&amp;quot;false&amp;quot;&lt;br /&gt;
if [[ &amp;quot;${#tls_secrets[@]}&amp;quot; -gt 0 || &amp;quot;$force_tls&amp;quot; == &amp;quot;true&amp;quot; ]]; then&lt;br /&gt;
  has_tls=&amp;quot;true&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
if [[ &amp;quot;$create_gateway&amp;quot; == &amp;quot;false&amp;quot; &amp;amp;&amp;amp; &amp;quot;$has_tls&amp;quot; == &amp;quot;true&amp;quot; ]]; then&lt;br /&gt;
  emit_certificate=&amp;quot;true&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
ssl_redirect=&amp;quot;$(&lt;br /&gt;
  jq -r '&lt;br /&gt;
    .metadata.annotations[&amp;quot;nginx.ingress.kubernetes.io/ssl-redirect&amp;quot;] //&lt;br /&gt;
    .metadata.annotations[&amp;quot;nginx.ingress.kubernetes.io/force-ssl-redirect&amp;quot;] //&lt;br /&gt;
    &amp;quot;false&amp;quot;&lt;br /&gt;
  ' &amp;lt;&amp;lt;&amp;lt;&amp;quot;$ingress_json&amp;quot;&lt;br /&gt;
)&amp;quot;&lt;br /&gt;
backend_protocol=&amp;quot;$(jq -r '.metadata.annotations[&amp;quot;nginx.ingress.kubernetes.io/backend-protocol&amp;quot;] // &amp;quot;HTTP&amp;quot;' &amp;lt;&amp;lt;&amp;lt;&amp;quot;$ingress_json&amp;quot; | tr '[:lower:]' '[:upper:]')&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if [[ &amp;quot;$backend_protocol&amp;quot; == &amp;quot;HTTPS&amp;quot; &amp;amp;&amp;amp; &amp;quot;$backend_tls&amp;quot; == &amp;quot;none&amp;quot; ]]; then&lt;br /&gt;
  printf 'warning: %s/%s uses nginx backend-protocol=HTTPS; generated route will need BackendTLSPolicy or backend HTTP support.\n' &amp;quot;$namespace&amp;quot; &amp;quot;$ingress&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
tmp=&amp;quot;$(mktemp)&amp;quot;&lt;br /&gt;
trap 'rm -f &amp;quot;$tmp&amp;quot;' EXIT&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  if [[ &amp;quot;$create_gateway&amp;quot; == &amp;quot;true&amp;quot; ]]; then&lt;br /&gt;
    cat &amp;lt;&amp;lt;EOF&lt;br /&gt;
apiVersion: gateway.networking.k8s.io/v1&lt;br /&gt;
kind: Gateway&lt;br /&gt;
metadata:&lt;br /&gt;
  name: $gateway&lt;br /&gt;
  namespace: $gateway_namespace&lt;br /&gt;
  labels:&lt;br /&gt;
    app.kubernetes.io/managed-by: ingress-to-envoy-gateway&lt;br /&gt;
    app.kubernetes.io/source-ingress: $ingress&lt;br /&gt;
spec:&lt;br /&gt;
  gatewayClassName: $gateway_class&lt;br /&gt;
  listeners:&lt;br /&gt;
    - name: http&lt;br /&gt;
      port: 80&lt;br /&gt;
      protocol: HTTP&lt;br /&gt;
      allowedRoutes:&lt;br /&gt;
        namespaces:&lt;br /&gt;
          from: Same&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
    if [[ &amp;quot;$has_tls&amp;quot; == &amp;quot;true&amp;quot; ]]; then&lt;br /&gt;
      cat &amp;lt;&amp;lt;'EOF'&lt;br /&gt;
    - name: https&lt;br /&gt;
      port: 443&lt;br /&gt;
      protocol: HTTPS&lt;br /&gt;
      tls:&lt;br /&gt;
        mode: Terminate&lt;br /&gt;
        certificateRefs:&lt;br /&gt;
EOF&lt;br /&gt;
      for secret in &amp;quot;${tls_secrets[@]}&amp;quot;; do&lt;br /&gt;
        printf '          - name: %s\n' &amp;quot;$secret&amp;quot;&lt;br /&gt;
      done&lt;br /&gt;
      cat &amp;lt;&amp;lt;'EOF'&lt;br /&gt;
      allowedRoutes:&lt;br /&gt;
        namespaces:&lt;br /&gt;
          from: Same&lt;br /&gt;
EOF&lt;br /&gt;
    fi&lt;br /&gt;
    printf '%s\n' '---'&lt;br /&gt;
  fi&lt;br /&gt;
&lt;br /&gt;
  cat &amp;lt;&amp;lt;EOF&lt;br /&gt;
apiVersion: gateway.networking.k8s.io/v1&lt;br /&gt;
kind: HTTPRoute&lt;br /&gt;
metadata:&lt;br /&gt;
  name: $ingress&lt;br /&gt;
  namespace: $namespace&lt;br /&gt;
  labels:&lt;br /&gt;
    app.kubernetes.io/managed-by: ingress-to-envoy-gateway&lt;br /&gt;
    app.kubernetes.io/source-ingress: $ingress&lt;br /&gt;
spec:&lt;br /&gt;
  hostnames:&lt;br /&gt;
EOF&lt;br /&gt;
  for host in &amp;quot;${hosts[@]}&amp;quot;; do&lt;br /&gt;
    printf '    - %s\n' &amp;quot;$(yaml_quote &amp;quot;$host&amp;quot;)&amp;quot;&lt;br /&gt;
  done&lt;br /&gt;
  cat &amp;lt;&amp;lt;EOF&lt;br /&gt;
  parentRefs:&lt;br /&gt;
    - name: $gateway&lt;br /&gt;
      namespace: $gateway_namespace&lt;br /&gt;
      sectionName: $([[ &amp;quot;$has_tls&amp;quot; == &amp;quot;true&amp;quot; ]] &amp;amp;&amp;amp; printf 'https' || printf 'http')&lt;br /&gt;
  rules:&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
  route_count=&amp;quot;$(jq '[.spec.rules[]?.http.paths[]?] | length' &amp;lt;&amp;lt;&amp;lt;&amp;quot;$ingress_json&amp;quot;)&amp;quot;&lt;br /&gt;
  [[ &amp;quot;$route_count&amp;quot; != &amp;quot;0&amp;quot; ]] || die &amp;quot;Ingress has no HTTP paths&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  for i in $(seq 0 &amp;quot;$((route_count - 1))&amp;quot;); do&lt;br /&gt;
    item=&amp;quot;$(jq -c &amp;quot;[.spec.rules[]?.http.paths[]?][$i]&amp;quot; &amp;lt;&amp;lt;&amp;lt;&amp;quot;$ingress_json&amp;quot;)&amp;quot;&lt;br /&gt;
    path=&amp;quot;$(jq -r '.path // &amp;quot;/&amp;quot;' &amp;lt;&amp;lt;&amp;lt;&amp;quot;$item&amp;quot;)&amp;quot;&lt;br /&gt;
    path_type=&amp;quot;$(jq -r '.pathType // &amp;quot;Prefix&amp;quot;' &amp;lt;&amp;lt;&amp;lt;&amp;quot;$item&amp;quot;)&amp;quot;&lt;br /&gt;
    svc=&amp;quot;$(jq -r '.backend.service.name // empty' &amp;lt;&amp;lt;&amp;lt;&amp;quot;$item&amp;quot;)&amp;quot;&lt;br /&gt;
    port_number=&amp;quot;$(jq -r '.backend.service.port.number // empty' &amp;lt;&amp;lt;&amp;lt;&amp;quot;$item&amp;quot;)&amp;quot;&lt;br /&gt;
    port_name=&amp;quot;$(jq -r '.backend.service.port.name // empty' &amp;lt;&amp;lt;&amp;lt;&amp;quot;$item&amp;quot;)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    [[ -n &amp;quot;$svc&amp;quot; ]] || die &amp;quot;path $i has no Service backend&amp;quot;&lt;br /&gt;
    if [[ -z &amp;quot;$port_number&amp;quot; &amp;amp;&amp;amp; -n &amp;quot;$port_name&amp;quot; ]]; then&lt;br /&gt;
      port_number=&amp;quot;$(resolve_service_port &amp;quot;$svc&amp;quot; &amp;quot;$port_name&amp;quot;)&amp;quot;&lt;br /&gt;
      [[ -n &amp;quot;$port_number&amp;quot; ]] || die &amp;quot;could not resolve named port $svc/$port_name&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
    [[ -n &amp;quot;$port_number&amp;quot; ]] || die &amp;quot;path $i has no Service port&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    case &amp;quot;$path_type&amp;quot; in&lt;br /&gt;
      Prefix) gateway_path_type=&amp;quot;PathPrefix&amp;quot; ;;&lt;br /&gt;
      Exact) gateway_path_type=&amp;quot;Exact&amp;quot; ;;&lt;br /&gt;
      ImplementationSpecific) gateway_path_type=&amp;quot;PathPrefix&amp;quot; ;;&lt;br /&gt;
      *) gateway_path_type=&amp;quot;PathPrefix&amp;quot; ;;&lt;br /&gt;
    esac&lt;br /&gt;
&lt;br /&gt;
    cat &amp;lt;&amp;lt;EOF&lt;br /&gt;
    - matches:&lt;br /&gt;
        - path:&lt;br /&gt;
            type: $gateway_path_type&lt;br /&gt;
            value: $(yaml_quote &amp;quot;$path&amp;quot;)&lt;br /&gt;
      backendRefs:&lt;br /&gt;
        - name: $svc&lt;br /&gt;
          port: $port_number&lt;br /&gt;
EOF&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
  if [[ &amp;quot;$has_tls&amp;quot; == &amp;quot;true&amp;quot; ]] &amp;amp;&amp;amp; { [[ &amp;quot;$ssl_redirect&amp;quot; == &amp;quot;true&amp;quot; ]] || [[ &amp;quot;$force_tls&amp;quot; == &amp;quot;true&amp;quot; ]]; }; then&lt;br /&gt;
    cat &amp;lt;&amp;lt;EOF&lt;br /&gt;
---&lt;br /&gt;
apiVersion: gateway.networking.k8s.io/v1&lt;br /&gt;
kind: HTTPRoute&lt;br /&gt;
metadata:&lt;br /&gt;
  name: $(resource_name &amp;quot;${ingress}-https-redirect&amp;quot;)&lt;br /&gt;
  namespace: $namespace&lt;br /&gt;
  labels:&lt;br /&gt;
    app.kubernetes.io/managed-by: ingress-to-envoy-gateway&lt;br /&gt;
    app.kubernetes.io/source-ingress: $ingress&lt;br /&gt;
spec:&lt;br /&gt;
  hostnames:&lt;br /&gt;
EOF&lt;br /&gt;
    for host in &amp;quot;${hosts[@]}&amp;quot;; do&lt;br /&gt;
      printf '    - %s\n' &amp;quot;$(yaml_quote &amp;quot;$host&amp;quot;)&amp;quot;&lt;br /&gt;
    done&lt;br /&gt;
    cat &amp;lt;&amp;lt;EOF&lt;br /&gt;
  parentRefs:&lt;br /&gt;
    - name: $gateway&lt;br /&gt;
      namespace: $gateway_namespace&lt;br /&gt;
      sectionName: http&lt;br /&gt;
  rules:&lt;br /&gt;
    - filters:&lt;br /&gt;
        - type: RequestRedirect&lt;br /&gt;
          requestRedirect:&lt;br /&gt;
            scheme: https&lt;br /&gt;
            statusCode: 301&lt;br /&gt;
      matches:&lt;br /&gt;
        - path:&lt;br /&gt;
            type: PathPrefix&lt;br /&gt;
            value: /&lt;br /&gt;
EOF&lt;br /&gt;
  fi&lt;br /&gt;
&lt;br /&gt;
  if [[ &amp;quot;$backend_protocol&amp;quot; == &amp;quot;HTTPS&amp;quot; &amp;amp;&amp;amp; &amp;quot;$backend_tls&amp;quot; != &amp;quot;none&amp;quot; ]]; then&lt;br /&gt;
    mapfile -t https_services &amp;lt; &amp;lt;(&lt;br /&gt;
      jq -r '.spec.rules[]?.http.paths[]?.backend.service.name // empty' &amp;lt;&amp;lt;&amp;lt;&amp;quot;$ingress_json&amp;quot; |&lt;br /&gt;
        awk 'NF' | sort -u&lt;br /&gt;
    )&lt;br /&gt;
    for svc in &amp;quot;${https_services[@]}&amp;quot;; do&lt;br /&gt;
      cat &amp;lt;&amp;lt;EOF&lt;br /&gt;
---&lt;br /&gt;
apiVersion: gateway.networking.k8s.io/v1&lt;br /&gt;
kind: BackendTLSPolicy&lt;br /&gt;
metadata:&lt;br /&gt;
  name: $(resource_name &amp;quot;${ingress}-${svc}-backend-tls&amp;quot;)&lt;br /&gt;
  namespace: $namespace&lt;br /&gt;
  labels:&lt;br /&gt;
    app.kubernetes.io/managed-by: ingress-to-envoy-gateway&lt;br /&gt;
    app.kubernetes.io/source-ingress: $ingress&lt;br /&gt;
spec:&lt;br /&gt;
  targetRefs:&lt;br /&gt;
    - group: &amp;quot;&amp;quot;&lt;br /&gt;
      kind: Service&lt;br /&gt;
      name: $svc&lt;br /&gt;
  validation:&lt;br /&gt;
    hostname: $(yaml_quote &amp;quot;$backend_tls_hostname&amp;quot;)&lt;br /&gt;
EOF&lt;br /&gt;
      if [[ &amp;quot;$backend_tls&amp;quot; == &amp;quot;system&amp;quot; ]]; then&lt;br /&gt;
        cat &amp;lt;&amp;lt;'EOF'&lt;br /&gt;
    wellKnownCACertificates: System&lt;br /&gt;
EOF&lt;br /&gt;
      else&lt;br /&gt;
        cat &amp;lt;&amp;lt;EOF&lt;br /&gt;
    caCertificateRefs:&lt;br /&gt;
      - group: &amp;quot;&amp;quot;&lt;br /&gt;
        kind: ConfigMap&lt;br /&gt;
        name: $backend_tls_ca_configmap&lt;br /&gt;
EOF&lt;br /&gt;
      fi&lt;br /&gt;
    done&lt;br /&gt;
  fi&lt;br /&gt;
&lt;br /&gt;
  if [[ &amp;quot;$emit_certificate&amp;quot; == &amp;quot;true&amp;quot; &amp;amp;&amp;amp; &amp;quot;$has_tls&amp;quot; == &amp;quot;true&amp;quot; ]]; then&lt;br /&gt;
    for secret in &amp;quot;${tls_secrets[@]}&amp;quot;; do&lt;br /&gt;
      mapfile -t cert_hosts &amp;lt; &amp;lt;(&lt;br /&gt;
        jq -r --arg secret &amp;quot;$secret&amp;quot; '&lt;br /&gt;
          .spec.tls[]? | select(.secretName == $secret) | .hosts[]?&lt;br /&gt;
        ' &amp;lt;&amp;lt;&amp;lt;&amp;quot;$ingress_json&amp;quot; | awk 'NF' | sort -u&lt;br /&gt;
      )&lt;br /&gt;
      [[ &amp;quot;${#cert_hosts[@]}&amp;quot; -gt 0 ]] || cert_hosts=(&amp;quot;${hosts[@]}&amp;quot;)&lt;br /&gt;
      cat &amp;lt;&amp;lt;EOF&lt;br /&gt;
---&lt;br /&gt;
apiVersion: cert-manager.io/v1&lt;br /&gt;
kind: Certificate&lt;br /&gt;
metadata:&lt;br /&gt;
  name: $secret&lt;br /&gt;
  namespace: $([[ &amp;quot;$create_gateway&amp;quot; == &amp;quot;false&amp;quot; ]] &amp;amp;&amp;amp; printf '%s' &amp;quot;$gateway_namespace&amp;quot; || printf '%s' &amp;quot;$namespace&amp;quot;)&lt;br /&gt;
  labels:&lt;br /&gt;
    app.kubernetes.io/managed-by: ingress-to-envoy-gateway&lt;br /&gt;
    app.kubernetes.io/source-ingress: $ingress&lt;br /&gt;
spec:&lt;br /&gt;
  secretName: $secret&lt;br /&gt;
  dnsNames:&lt;br /&gt;
EOF&lt;br /&gt;
      for host in &amp;quot;${cert_hosts[@]}&amp;quot;; do&lt;br /&gt;
        printf '    - %s\n' &amp;quot;$(yaml_quote &amp;quot;$host&amp;quot;)&amp;quot;&lt;br /&gt;
      done&lt;br /&gt;
      cat &amp;lt;&amp;lt;EOF&lt;br /&gt;
  issuerRef:&lt;br /&gt;
    group: cert-manager.io&lt;br /&gt;
    kind: ClusterIssuer&lt;br /&gt;
    name: $issuer&lt;br /&gt;
EOF&lt;br /&gt;
    done&lt;br /&gt;
  fi&lt;br /&gt;
} &amp;gt;&amp;quot;$tmp&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if [[ &amp;quot;$apply&amp;quot; == &amp;quot;true&amp;quot; ]]; then&lt;br /&gt;
  &amp;quot;$kubectl_cmd&amp;quot; apply -f &amp;quot;$tmp&amp;quot;&lt;br /&gt;
  if [[ &amp;quot;$create_gateway&amp;quot; == &amp;quot;false&amp;quot; &amp;amp;&amp;amp; &amp;quot;$has_tls&amp;quot; == &amp;quot;true&amp;quot; ]]; then&lt;br /&gt;
    for secret in &amp;quot;${tls_secrets[@]}&amp;quot;; do&lt;br /&gt;
      patch_gateway_cert_ref &amp;quot;$secret&amp;quot;&lt;br /&gt;
    done&lt;br /&gt;
  fi&lt;br /&gt;
else&lt;br /&gt;
  cat &amp;quot;$tmp&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Envoy_from_nginx_for_ingress&amp;diff=5714</id>
		<title>Envoy from nginx for ingress</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Envoy_from_nginx_for_ingress&amp;diff=5714"/>
		<updated>2026-06-22T02:18:10Z</updated>

		<summary type="html">&lt;p&gt;Busk: Created page with &amp;quot;go install github.com/kubernetes-sigs/ingress2gateway@latest  # Translate an existing NGINX ingress into Gateway API manifests ingress2gateway print --providers ingress-nginx...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;go install github.com/kubernetes-sigs/ingress2gateway@latest&lt;br /&gt;
&lt;br /&gt;
# Translate an existing NGINX ingress into Gateway API manifests&lt;br /&gt;
ingress2gateway print --providers ingress-nginx &amp;gt; new-envoy-routes.yaml&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=AI_notes&amp;diff=5713</id>
		<title>AI notes</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=AI_notes&amp;diff=5713"/>
		<updated>2026-06-20T10:24:51Z</updated>

		<summary type="html">&lt;p&gt;Busk: Created page with &amp;quot;https://youtu.be/sOPDGQjFcuM?is=pGCLuNECaFYHC2xa&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;https://youtu.be/sOPDGQjFcuM?is=pGCLuNECaFYHC2xa&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Docker_install&amp;diff=5712</id>
		<title>Docker install</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Docker_install&amp;diff=5712"/>
		<updated>2026-06-19T23:10:20Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;# Install&lt;br /&gt;
&lt;br /&gt;
## Ubuntu Docker-CE Install using zfs for data mount&lt;br /&gt;
```&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
set -e&lt;br /&gt;
&lt;br /&gt;
DATASET_NAME=&amp;quot;tank-nvme/docker&amp;quot;&lt;br /&gt;
DOCKER_DIR=&amp;quot;/var/lib/docker&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if ! sudo zfs list &amp;quot;${DATASET_NAME%%/*}&amp;quot; &amp;amp;&amp;gt;/dev/null; then&lt;br /&gt;
    echo &amp;quot;Error: ZFS pool '${DATASET_NAME%%/*}' does not exist.&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if sudo zfs list &amp;quot;$DATASET_NAME&amp;quot; &amp;amp;&amp;gt;/dev/null; then&lt;br /&gt;
    echo &amp;quot;ZFS dataset $DATASET_NAME already exists.&amp;quot;&lt;br /&gt;
else&lt;br /&gt;
    sudo zfs create -o mountpoint=legacy &amp;quot;$DATASET_NAME&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# Add Docker's official GPG key:&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install ca-certificates curl&lt;br /&gt;
sudo install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
sudo chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
# Add the repository to Apt sources:&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sudo apt-get update&lt;br /&gt;
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&lt;br /&gt;
sudo systemctl stop docker&lt;br /&gt;
sudo systemctl stop docker.socket&lt;br /&gt;
&lt;br /&gt;
sudo mkdir -p &amp;quot;$DOCKER_DIR&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if ! mountpoint -q &amp;quot;$DOCKER_DIR&amp;quot;; then&lt;br /&gt;
    sudo mount -t zfs &amp;quot;$DATASET_NAME&amp;quot; &amp;quot;$DOCKER_DIR&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if ! grep -q &amp;quot;$DATASET_NAME&amp;quot; /etc/fstab; then&lt;br /&gt;
    echo &amp;quot;$DATASET_NAME $DOCKER_DIR zfs defaults 0 0&amp;quot; | sudo tee -a /etc/fstab &amp;gt; /dev/null&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
sudo mkdir -p /etc/docker&lt;br /&gt;
sudo tee /etc/docker/daemon.json &amp;gt; /dev/null &amp;lt;&amp;lt;EOF&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;storage-driver&amp;quot;: &amp;quot;zfs&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo systemctl start docker&lt;br /&gt;
sleep 5&lt;br /&gt;
sudo docker run hello-world&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Docker_install&amp;diff=5711</id>
		<title>Docker install</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Docker_install&amp;diff=5711"/>
		<updated>2026-06-19T23:08:21Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;# Install&lt;br /&gt;
&lt;br /&gt;
## Ubuntu Install using zfs for data&lt;br /&gt;
```&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
set -e&lt;br /&gt;
&lt;br /&gt;
DATASET_NAME=&amp;quot;tank-nvme/docker&amp;quot;&lt;br /&gt;
DOCKER_DIR=&amp;quot;/var/lib/docker&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if ! sudo zfs list &amp;quot;${DATASET_NAME%%/*}&amp;quot; &amp;amp;&amp;gt;/dev/null; then&lt;br /&gt;
    echo &amp;quot;Error: ZFS pool '${DATASET_NAME%%/*}' does not exist.&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if sudo zfs list &amp;quot;$DATASET_NAME&amp;quot; &amp;amp;&amp;gt;/dev/null; then&lt;br /&gt;
    echo &amp;quot;ZFS dataset $DATASET_NAME already exists.&amp;quot;&lt;br /&gt;
else&lt;br /&gt;
    sudo zfs create -o mountpoint=legacy &amp;quot;$DATASET_NAME&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# Add Docker's official GPG key:&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install ca-certificates curl&lt;br /&gt;
sudo install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
sudo chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
# Add the repository to Apt sources:&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sudo apt-get update&lt;br /&gt;
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&lt;br /&gt;
sudo systemctl stop docker&lt;br /&gt;
sudo systemctl stop docker.socket&lt;br /&gt;
&lt;br /&gt;
sudo mkdir -p &amp;quot;$DOCKER_DIR&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if ! mountpoint -q &amp;quot;$DOCKER_DIR&amp;quot;; then&lt;br /&gt;
    sudo mount -t zfs &amp;quot;$DATASET_NAME&amp;quot; &amp;quot;$DOCKER_DIR&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if ! grep -q &amp;quot;$DATASET_NAME&amp;quot; /etc/fstab; then&lt;br /&gt;
    echo &amp;quot;$DATASET_NAME $DOCKER_DIR zfs defaults 0 0&amp;quot; | sudo tee -a /etc/fstab &amp;gt; /dev/null&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
sudo mkdir -p /etc/docker&lt;br /&gt;
sudo tee /etc/docker/daemon.json &amp;gt; /dev/null &amp;lt;&amp;lt;EOF&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;storage-driver&amp;quot;: &amp;quot;zfs&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo systemctl start docker&lt;br /&gt;
sleep 5&lt;br /&gt;
sudo docker run hello-world&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Docker_install&amp;diff=5710</id>
		<title>Docker install</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Docker_install&amp;diff=5710"/>
		<updated>2026-06-19T23:07:23Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
set -e&lt;br /&gt;
&lt;br /&gt;
DATASET_NAME=&amp;quot;tank-nvme/docker&amp;quot;&lt;br /&gt;
DOCKER_DIR=&amp;quot;/var/lib/docker&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if ! sudo zfs list &amp;quot;${DATASET_NAME%%/*}&amp;quot; &amp;amp;&amp;gt;/dev/null; then&lt;br /&gt;
    echo &amp;quot;Error: ZFS pool '${DATASET_NAME%%/*}' does not exist.&amp;quot; &amp;gt;&amp;amp;2&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if sudo zfs list &amp;quot;$DATASET_NAME&amp;quot; &amp;amp;&amp;gt;/dev/null; then&lt;br /&gt;
    echo &amp;quot;ZFS dataset $DATASET_NAME already exists.&amp;quot;&lt;br /&gt;
else&lt;br /&gt;
    sudo zfs create -o mountpoint=legacy &amp;quot;$DATASET_NAME&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# Add Docker's official GPG key:&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install ca-certificates curl&lt;br /&gt;
sudo install -m 0755 -d /etc/apt/keyrings&lt;br /&gt;
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc&lt;br /&gt;
sudo chmod a+r /etc/apt/keyrings/docker.asc&lt;br /&gt;
&lt;br /&gt;
# Add the repository to Apt sources:&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&lt;br /&gt;
Types: deb&lt;br /&gt;
URIs: https://download.docker.com/linux/ubuntu&lt;br /&gt;
Suites: $(. /etc/os-release &amp;amp;&amp;amp; echo &amp;quot;${UBUNTU_CODENAME:-$VERSION_CODENAME}&amp;quot;)&lt;br /&gt;
Components: stable&lt;br /&gt;
Architectures: $(dpkg --print-architecture)&lt;br /&gt;
Signed-By: /etc/apt/keyrings/docker.asc&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sudo apt-get update&lt;br /&gt;
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin&lt;br /&gt;
&lt;br /&gt;
sudo systemctl stop docker&lt;br /&gt;
sudo systemctl stop docker.socket&lt;br /&gt;
&lt;br /&gt;
sudo mkdir -p &amp;quot;$DOCKER_DIR&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if ! mountpoint -q &amp;quot;$DOCKER_DIR&amp;quot;; then&lt;br /&gt;
    sudo mount -t zfs &amp;quot;$DATASET_NAME&amp;quot; &amp;quot;$DOCKER_DIR&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
if ! grep -q &amp;quot;$DATASET_NAME&amp;quot; /etc/fstab; then&lt;br /&gt;
    echo &amp;quot;$DATASET_NAME $DOCKER_DIR zfs defaults 0 0&amp;quot; | sudo tee -a /etc/fstab &amp;gt; /dev/null&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
sudo mkdir -p /etc/docker&lt;br /&gt;
sudo tee /etc/docker/daemon.json &amp;gt; /dev/null &amp;lt;&amp;lt;EOF&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;storage-driver&amp;quot;: &amp;quot;zfs&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo systemctl start docker&lt;br /&gt;
sleep 5&lt;br /&gt;
sudo docker run hello-world&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Zfs_pool&amp;diff=5709</id>
		<title>Zfs pool</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Zfs_pool&amp;diff=5709"/>
		<updated>2026-06-15T21:46:57Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
```&lt;br /&gt;
sudo zpool create -o ashift=12 tank-nvme mirror /dev/disk/by-id/nvme-eui.0025385281b1b872 /dev/disk/by-id/nvme-eui.0025385281b1b878&lt;br /&gt;
&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/nvme-Samsung_SSD_960_EVO_1TB_S3X3NF0K204029J&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/nvme-Samsung_SSD_960_EVO_1TB_S3X3NF0K204035E&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RMS&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RPX&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN0339T&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RFB&lt;br /&gt;
&lt;br /&gt;
sudo zpool create -o ashift=12 tank-hdd mirror /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RMS /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RPX mirror /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN0339T /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RFB&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
sudo zfs create -o atime=off -o compression=lz4 -o xattr=sa -o acltype=posixacl tank-nvme/lxd&lt;br /&gt;
&lt;br /&gt;
## ashift&lt;br /&gt;
&lt;br /&gt;
`ashift` stands for **alignment shift**. It dictates the minimum block size ZFS will use when formatting and writing data to the physical storage devices in your pool.&lt;br /&gt;
&lt;br /&gt;
The number you provide is an exponent of 2:&lt;br /&gt;
&lt;br /&gt;
* `ashift=9` means $2^9=512$ bytes.&lt;br /&gt;
* `ashift=12` means $2^{12}=4096$ bytes (4K).&lt;br /&gt;
* `ashift=13` means $2^{13}=8192$ bytes (8K).&lt;br /&gt;
&lt;br /&gt;
Here is why forcing `ashift=12` is critical for modern storage.&lt;br /&gt;
&lt;br /&gt;
### **The 512-byte Lie (Emulation)**&lt;br /&gt;
&lt;br /&gt;
Historically, hard drives used physical sectors that were exactly 512 bytes in size. However, almost all modern hard drives and SSDs use **Advanced Format**, meaning their physical layout is built on 4096-byte (4K) sectors. This larger size allows for higher storage density and better error correction.&lt;br /&gt;
&lt;br /&gt;
To avoid breaking older operating systems and legacy hardware controllers, many modern 4K drives &amp;quot;lie&amp;quot; to the host system. They use a firmware feature called **512e (512-byte emulation)** to report themselves as having old-school 512-byte sectors, even though their physical architecture is 4K.&lt;br /&gt;
&lt;br /&gt;
### **The Read-Modify-Write Penalty**&lt;br /&gt;
&lt;br /&gt;
If you create a ZFS pool without specifying the `ashift` value, ZFS will often interrogate the drive, hear the 512-byte lie, and set `ashift=9`. This creates a severe misalignment between ZFS's logical blocks and the drive's physical sectors.&lt;br /&gt;
&lt;br /&gt;
If ZFS attempts to write a 512-byte block to a physical 4K sector, the storage drive is forced to execute a **Read-Modify-Write** operation:&lt;br /&gt;
&lt;br /&gt;
1. **Read:** The drive reads the entire 4K physical sector into its internal memory.&lt;br /&gt;
2. **Modify:** The drive inserts the 512 bytes ZFS sent into the 4K block.&lt;br /&gt;
3. **Write:** The drive writes the whole 4K sector back to the disk.&lt;br /&gt;
&lt;br /&gt;
This massive overhead completely destroys write performance (especially random I/O) and causes severe &amp;quot;write amplification,&amp;quot; which prematurely burns through the endurance limits of NVMe and SSD drives.&lt;br /&gt;
&lt;br /&gt;
### **The Solution**&lt;br /&gt;
&lt;br /&gt;
By explicitly appending `-o ashift=12` to your `zpool create` command, you force ZFS to align all of its data payloads to exact 4K boundaries. This ensures ZFS writes map perfectly to the physical hardware beneath it, entirely bypassing the emulation penalty and ensuring optimal throughput and drive lifespan.&lt;br /&gt;
&lt;br /&gt;
&amp;gt; **Note:** The `ashift` value is permanently baked into a top-level virtual device (vdev) at the moment of creation. If you create a pool with the wrong `ashift`, it cannot be changed later; you have to destroy the pool, wipe the drives, and start over.&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Zfs_pool&amp;diff=5708</id>
		<title>Zfs pool</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Zfs_pool&amp;diff=5708"/>
		<updated>2026-06-15T20:56:16Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
```&lt;br /&gt;
sudo zpool create -o ashift=12 tank-nvme mirror /dev/disk/by-id/nvme-eui.0025385281b1b872 /dev/disk/by-id/nvme-eui.0025385281b1b878&lt;br /&gt;
&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/nvme-Samsung_SSD_960_EVO_1TB_S3X3NF0K204029J&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/nvme-Samsung_SSD_960_EVO_1TB_S3X3NF0K204035E&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RMS&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RPX&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN0339T&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RFB&lt;br /&gt;
&lt;br /&gt;
sudo zpool create -o ashift=12 tank-hdd mirror /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RMS /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RPX mirror /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN0339T /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RFB&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## ashift&lt;br /&gt;
&lt;br /&gt;
`ashift` stands for **alignment shift**. It dictates the minimum block size ZFS will use when formatting and writing data to the physical storage devices in your pool.&lt;br /&gt;
&lt;br /&gt;
The number you provide is an exponent of 2:&lt;br /&gt;
&lt;br /&gt;
* `ashift=9` means $2^9=512$ bytes.&lt;br /&gt;
* `ashift=12` means $2^{12}=4096$ bytes (4K).&lt;br /&gt;
* `ashift=13` means $2^{13}=8192$ bytes (8K).&lt;br /&gt;
&lt;br /&gt;
Here is why forcing `ashift=12` is critical for modern storage.&lt;br /&gt;
&lt;br /&gt;
### **The 512-byte Lie (Emulation)**&lt;br /&gt;
&lt;br /&gt;
Historically, hard drives used physical sectors that were exactly 512 bytes in size. However, almost all modern hard drives and SSDs use **Advanced Format**, meaning their physical layout is built on 4096-byte (4K) sectors. This larger size allows for higher storage density and better error correction.&lt;br /&gt;
&lt;br /&gt;
To avoid breaking older operating systems and legacy hardware controllers, many modern 4K drives &amp;quot;lie&amp;quot; to the host system. They use a firmware feature called **512e (512-byte emulation)** to report themselves as having old-school 512-byte sectors, even though their physical architecture is 4K.&lt;br /&gt;
&lt;br /&gt;
### **The Read-Modify-Write Penalty**&lt;br /&gt;
&lt;br /&gt;
If you create a ZFS pool without specifying the `ashift` value, ZFS will often interrogate the drive, hear the 512-byte lie, and set `ashift=9`. This creates a severe misalignment between ZFS's logical blocks and the drive's physical sectors.&lt;br /&gt;
&lt;br /&gt;
If ZFS attempts to write a 512-byte block to a physical 4K sector, the storage drive is forced to execute a **Read-Modify-Write** operation:&lt;br /&gt;
&lt;br /&gt;
1. **Read:** The drive reads the entire 4K physical sector into its internal memory.&lt;br /&gt;
2. **Modify:** The drive inserts the 512 bytes ZFS sent into the 4K block.&lt;br /&gt;
3. **Write:** The drive writes the whole 4K sector back to the disk.&lt;br /&gt;
&lt;br /&gt;
This massive overhead completely destroys write performance (especially random I/O) and causes severe &amp;quot;write amplification,&amp;quot; which prematurely burns through the endurance limits of NVMe and SSD drives.&lt;br /&gt;
&lt;br /&gt;
### **The Solution**&lt;br /&gt;
&lt;br /&gt;
By explicitly appending `-o ashift=12` to your `zpool create` command, you force ZFS to align all of its data payloads to exact 4K boundaries. This ensures ZFS writes map perfectly to the physical hardware beneath it, entirely bypassing the emulation penalty and ensuring optimal throughput and drive lifespan.&lt;br /&gt;
&lt;br /&gt;
&amp;gt; **Note:** The `ashift` value is permanently baked into a top-level virtual device (vdev) at the moment of creation. If you create a pool with the wrong `ashift`, it cannot be changed later; you have to destroy the pool, wipe the drives, and start over.&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Zfs_pool&amp;diff=5707</id>
		<title>Zfs pool</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Zfs_pool&amp;diff=5707"/>
		<updated>2026-06-15T20:52:51Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
```&lt;br /&gt;
sudo zpool create -o ashift=12 tank-nvme mirror /dev/disk/by-id/nvme-eui.0025385281b1b872 /dev/disk/by-id/nvme-eui.0025385281b1b878&lt;br /&gt;
&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/nvme-Samsung_SSD_960_EVO_1TB_S3X3NF0K204029J&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/nvme-Samsung_SSD_960_EVO_1TB_S3X3NF0K204035E&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RMS&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RPX&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN0339T&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RFB&lt;br /&gt;
&lt;br /&gt;
sudo zpool create -o ashift=12 tank-hdd mirror /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RMS /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RPX mirror /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN0339T /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RFB&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## ashift&lt;br /&gt;
&lt;br /&gt;
ashift stands for alignment shift. It dictates the minimum block size ZFS will use when formatting and writing data to the physical storage devices in your pool.The number you provide is an exponent of 2:ashift=9 means $2^9=512$ bytes.ashift=12 means $2^{12}=4096$ bytes (4K).ashift=13 means $2^{13}=8192$ bytes (8K).Here is why forcing ashift=12 is critical for modern storage.The 512-byte Lie (Emulation)Historically, hard drives used physical sectors that were exactly 512 bytes in size. However, almost all modern hard drives and SSDs use Advanced Format, meaning their physical layout is built on 4096-byte (4K) sectors. This larger size allows for higher storage density and better error correction.To avoid breaking older operating systems and legacy hardware controllers, many modern 4K drives &amp;quot;lie&amp;quot; to the host system. They use a firmware feature called 512e (512-byte emulation) to report themselves as having old-school 512-byte sectors, even though their physical architecture is 4K.The Read-Modify-Write PenaltyIf you create a ZFS pool without specifying the ashift value, ZFS will often interrogate the drive, hear the 512-byte lie, and set ashift=9. This creates a severe misalignment between ZFS's logical blocks and the drive's physical sectors.If ZFS attempts to write a 512-byte block to a physical 4K sector, the storage drive is forced to execute a Read-Modify-Write operation:Read: The drive reads the entire 4K physical sector into its internal memory.Modify: The drive inserts the 512 bytes ZFS sent into the 4K block.Write: The drive writes the whole 4K sector back to the disk.This massive overhead completely destroys write performance (especially random I/O) and causes severe &amp;quot;write amplification,&amp;quot; which prematurely burns through the endurance limits of NVMe and SSD drives.The SolutionBy explicitly appending -o ashift=12 to your zpool create command, you force ZFS to align all of its data payloads to exact 4K boundaries. This ensures ZFS writes map perfectly to the physical hardware beneath it, entirely bypassing the emulation penalty and ensuring optimal throughput and drive lifespan.Note: The ashift value is permanently baked into a top-level virtual device (vdev) at the moment of creation. If you create a pool with the wrong ashift, it cannot be changed later; you have to destroy the pool, wipe the drives, and start over.&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Zfs_pool&amp;diff=5706</id>
		<title>Zfs pool</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Zfs_pool&amp;diff=5706"/>
		<updated>2026-06-15T20:47:33Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
```&lt;br /&gt;
sudo zpool create -o ashift=12 tank-nvme mirror /dev/disk/by-id/nvme-eui.0025385281b1b872 /dev/disk/by-id/nvme-eui.0025385281b1b878&lt;br /&gt;
&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/nvme-Samsung_SSD_960_EVO_1TB_S3X3NF0K204029J&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/nvme-Samsung_SSD_960_EVO_1TB_S3X3NF0K204035E&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RMS&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RPX&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN0339T&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RFB&lt;br /&gt;
&lt;br /&gt;
sudo zpool create -o ashift=12 tank-hdd mirror /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RMS /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RPX mirror /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN0339T /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RFB&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Zfs_pool&amp;diff=5705</id>
		<title>Zfs pool</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Zfs_pool&amp;diff=5705"/>
		<updated>2026-06-15T20:47:12Z</updated>

		<summary type="html">&lt;p&gt;Busk: Created page with &amp;quot; ``` sudo zpool create -o ashift=12 tank1 mirror /dev/disk/by-id/nvme-eui.0025385281b1b872 /dev/disk/by-id/nvme-eui.0025385281b1b878  sudo wipefs -a /dev/disk/by-id/nvme-Samsu...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
```&lt;br /&gt;
sudo zpool create -o ashift=12 tank1 mirror /dev/disk/by-id/nvme-eui.0025385281b1b872 /dev/disk/by-id/nvme-eui.0025385281b1b878&lt;br /&gt;
&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/nvme-Samsung_SSD_960_EVO_1TB_S3X3NF0K204029J&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/nvme-Samsung_SSD_960_EVO_1TB_S3X3NF0K204035E&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RMS&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RPX&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN0339T&lt;br /&gt;
sudo wipefs -a /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RFB&lt;br /&gt;
&lt;br /&gt;
sudo zpool create -o ashift=12 mypool mirror /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RMS /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RPX mirror /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN0339T /dev/disk/by-id/ata-ST4000DM004-2CV104_ZFN07RFB&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Sandbox3&amp;diff=5704</id>
		<title>Sandbox3</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Sandbox3&amp;diff=5704"/>
		<updated>2026-06-07T00:35:27Z</updated>

		<summary type="html">&lt;p&gt;Busk: Created page with &amp;quot;``` #!/bin/bash export REPO=&amp;quot;your-owner/your-repo&amp;quot; export BRANCH=&amp;quot;main&amp;quot; export RULESET_NAME=&amp;quot;Migrated Protection - $BRANCH&amp;quot;  # 1. Fetch Classic Branch Protection Rules echo &amp;quot;F...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;```&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
export REPO=&amp;quot;your-owner/your-repo&amp;quot;&lt;br /&gt;
export BRANCH=&amp;quot;main&amp;quot;&lt;br /&gt;
export RULESET_NAME=&amp;quot;Migrated Protection - $BRANCH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# 1. Fetch Classic Branch Protection Rules&lt;br /&gt;
echo &amp;quot;Fetching classic branch protection for $BRANCH...&amp;quot;&lt;br /&gt;
CLASSIC_RULES=$(gh api repos/$REPO/branches/$BRANCH/protection -X GET 2&amp;gt;/dev/null)&lt;br /&gt;
&lt;br /&gt;
if [ -z &amp;quot;$CLASSIC_RULES&amp;quot; ]; then&lt;br /&gt;
    echo &amp;quot;No classic rules found or error accessing repo.&amp;quot;&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# 2. Extract and Map Protections&lt;br /&gt;
REQ_PR=$(echo &amp;quot;$CLASSIC_RULES&amp;quot; | jq -e '.required_pull_request_reviews' &amp;gt;/dev/null &amp;amp;&amp;amp; echo &amp;quot;true&amp;quot; || echo &amp;quot;false&amp;quot;)&lt;br /&gt;
REQ_APPROVALS=$(echo &amp;quot;$CLASSIC_RULES&amp;quot; | jq '.required_pull_request_reviews.required_approving_review_count // 1')&lt;br /&gt;
DISMISS_STALE=$(echo &amp;quot;$CLASSIC_RULES&amp;quot; | jq '.required_pull_request_reviews.dismiss_stale_reviews // false')&lt;br /&gt;
REQ_CODE_OWNERS=$(echo &amp;quot;$CLASSIC_RULES&amp;quot; | jq '.required_pull_request_reviews.require_code_owner_reviews // false')&lt;br /&gt;
&lt;br /&gt;
REQ_CHECKS=$(echo &amp;quot;$CLASSIC_RULES&amp;quot; | jq -e '.required_status_checks' &amp;gt;/dev/null &amp;amp;&amp;amp; echo &amp;quot;true&amp;quot; || echo &amp;quot;false&amp;quot;)&lt;br /&gt;
REQ_STRICT=$(echo &amp;quot;$CLASSIC_RULES&amp;quot; | jq '.required_status_checks.strict // false')&lt;br /&gt;
CONTEXTS=$(echo &amp;quot;$CLASSIC_RULES&amp;quot; | jq '.required_status_checks.contexts // []')&lt;br /&gt;
&lt;br /&gt;
ENFORCE_ADMINS=$(echo &amp;quot;$CLASSIC_RULES&amp;quot; | jq '.enforce_admins.enabled // false')&lt;br /&gt;
REQ_LINEAR=$(echo &amp;quot;$CLASSIC_RULES&amp;quot; | jq '.required_linear_history.enabled // false')&lt;br /&gt;
REQ_SIGNATURES=$(echo &amp;quot;$CLASSIC_RULES&amp;quot; | jq '.required_signatures.enabled // false')&lt;br /&gt;
&lt;br /&gt;
# 3. Construct Ruleset Payload&lt;br /&gt;
PAYLOAD=$(jq -n \&lt;br /&gt;
  --arg name &amp;quot;$RULESET_NAME&amp;quot; \&lt;br /&gt;
  --arg target &amp;quot;$BRANCH&amp;quot; \&lt;br /&gt;
  --argjson req_pr &amp;quot;$REQ_PR&amp;quot; \&lt;br /&gt;
  --argjson approvals &amp;quot;$REQ_APPROVALS&amp;quot; \&lt;br /&gt;
  --argjson dismiss_stale &amp;quot;$DISMISS_STALE&amp;quot; \&lt;br /&gt;
  --argjson code_owners &amp;quot;$REQ_CODE_OWNERS&amp;quot; \&lt;br /&gt;
  --argjson req_checks &amp;quot;$REQ_CHECKS&amp;quot; \&lt;br /&gt;
  --argjson strict &amp;quot;$REQ_STRICT&amp;quot; \&lt;br /&gt;
  --argjson contexts &amp;quot;$CONTEXTS&amp;quot; \&lt;br /&gt;
  --argjson linear &amp;quot;$REQ_LINEAR&amp;quot; \&lt;br /&gt;
  --argjson signatures &amp;quot;$REQ_SIGNATURES&amp;quot; \&lt;br /&gt;
  '&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;name&amp;quot;: $name,&lt;br /&gt;
    &amp;quot;target&amp;quot;: &amp;quot;branch&amp;quot;,&lt;br /&gt;
    &amp;quot;enforcement&amp;quot;: &amp;quot;active&amp;quot;,&lt;br /&gt;
    &amp;quot;conditions&amp;quot;: {&lt;br /&gt;
      &amp;quot;ref_name&amp;quot;: {&lt;br /&gt;
        &amp;quot;include&amp;quot;: [&amp;quot;refs/heads/&amp;quot; + $target],&lt;br /&gt;
        &amp;quot;exclude&amp;quot;: []&lt;br /&gt;
      }&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;rules&amp;quot;: [&lt;br /&gt;
      { &amp;quot;type&amp;quot;: &amp;quot;deletion&amp;quot; },&lt;br /&gt;
      { &amp;quot;type&amp;quot;: &amp;quot;non_fast_forward&amp;quot; }&lt;br /&gt;
    ]&lt;br /&gt;
  }&lt;br /&gt;
  | if $req_pr then .rules += [{&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;pull_request&amp;quot;,&lt;br /&gt;
      &amp;quot;parameters&amp;quot;: {&lt;br /&gt;
        &amp;quot;required_approving_review_count&amp;quot;: $approvals,&lt;br /&gt;
        &amp;quot;dismiss_stale_reviews_on_push&amp;quot;: $dismiss_stale,&lt;br /&gt;
        &amp;quot;require_code_owner_review&amp;quot;: $code_owners,&lt;br /&gt;
        &amp;quot;require_last_push_approval&amp;quot;: false&lt;br /&gt;
      }&lt;br /&gt;
    }] else . end&lt;br /&gt;
  | if $req_checks then .rules += [{&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;required_status_checks&amp;quot;,&lt;br /&gt;
      &amp;quot;parameters&amp;quot;: {&lt;br /&gt;
        &amp;quot;strict_required_status_checks_policy&amp;quot;: $strict,&lt;br /&gt;
        &amp;quot;required_status_checks&amp;quot;: ($contexts | map({ context: ., integration_id: 0 }))&lt;br /&gt;
      }&lt;br /&gt;
    }] else . end&lt;br /&gt;
  | if $linear then .rules += [{ &amp;quot;type&amp;quot;: &amp;quot;required_linear_history&amp;quot; }] else . end&lt;br /&gt;
  | if $signatures then .rules += [{ &amp;quot;type&amp;quot;: &amp;quot;required_signatures&amp;quot; }] else . end&lt;br /&gt;
')&lt;br /&gt;
&lt;br /&gt;
# 4. Create the New Ruleset&lt;br /&gt;
echo &amp;quot;Creating new Branch Ruleset...&amp;quot;&lt;br /&gt;
CREATE_RES=$(gh api repos/$REPO/rulesets -X POST --input - &amp;lt;&amp;lt;&amp;lt; &amp;quot;$PAYLOAD&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
if [ $? -eq 0 ]; then&lt;br /&gt;
    echo &amp;quot;Ruleset successfully created!&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    # 5. Optional: Delete the classic rule if the ruleset succeeded&lt;br /&gt;
    echo &amp;quot;To complete the migration, manually delete the classic rule or uncomment the line below:&amp;quot;&lt;br /&gt;
    echo &amp;quot;# gh api repos/$REPO/branches/$BRANCH/protection -X DELETE&amp;quot;&lt;br /&gt;
else&lt;br /&gt;
    echo &amp;quot;Failed to create ruleset.&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Sed&amp;diff=5703</id>
		<title>Sed</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Sed&amp;diff=5703"/>
		<updated>2026-06-03T20:07:09Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;https://opensource.com/article/20/12/sed&lt;br /&gt;
&lt;br /&gt;
grep -rl oldtext . | xargs sed -i 's/oldtext/newtext/g'&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
find . -type f -name &amp;quot;*.txt&amp;quot; -exec sed -i 's/old_text/new_text/g' {} +&lt;br /&gt;
&lt;br /&gt;
find . -type f -name &amp;quot;*.txt&amp;quot; -exec sed -i '' 's/old_text/new_text/g' {} +&lt;br /&gt;
&lt;br /&gt;
find . -type f -name &amp;quot;*.txt&amp;quot; -print0 | xargs -0 sed -i 's/old_text/new_text/g'v&lt;br /&gt;
&lt;br /&gt;
## Linux&lt;br /&gt;
&lt;br /&gt;
grep -rlZ --exclude-dir='.git' 'oldtext' . | xargs -0 sed -i 's/oldtext/newtext/g'&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
## Macos/freebsd&lt;br /&gt;
grep -rl --null --exclude-dir='.git' 'oldtext' . | xargs -0 sed -i '' 's/oldtext/newtext/g'&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Sed&amp;diff=5702</id>
		<title>Sed</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Sed&amp;diff=5702"/>
		<updated>2026-06-03T20:05:29Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;https://opensource.com/article/20/12/sed&lt;br /&gt;
&lt;br /&gt;
grep -rl oldtext . | xargs sed -i 's/oldtext/newtext/g'&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
find . -type f -name &amp;quot;*.txt&amp;quot; -exec sed -i 's/old_text/new_text/g' {} +&lt;br /&gt;
&lt;br /&gt;
find . -type f -name &amp;quot;*.txt&amp;quot; -exec sed -i '' 's/old_text/new_text/g' {} +&lt;br /&gt;
&lt;br /&gt;
find . -type f -name &amp;quot;*.txt&amp;quot; -print0 | xargs -0 sed -i 's/old_text/new_text/g'&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Hugo&amp;diff=5701</id>
		<title>Hugo</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Hugo&amp;diff=5701"/>
		<updated>2026-06-01T15:07:51Z</updated>

		<summary type="html">&lt;p&gt;Busk: Created page with &amp;quot;``` nohup hugo server --source website_hugo --disableFastRender &amp;gt; hugo-server.log 2&amp;gt;&amp;amp;1 &amp;amp; ```&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;```&lt;br /&gt;
nohup hugo server --source website_hugo --disableFastRender &amp;gt; hugo-server.log 2&amp;gt;&amp;amp;1 &amp;amp;&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Rsync&amp;diff=5700</id>
		<title>Rsync</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Rsync&amp;diff=5700"/>
		<updated>2026-05-31T22:35:42Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;# Backup Command&lt;br /&gt;
&lt;br /&gt;
rsync -axSH --exclude='.locks/' --dry-run --progress ~/.cache/huggingface/hub/ /ai/hf_cache/hub/&lt;br /&gt;
&lt;br /&gt;
rate limit 10000 Kbytes per second on zfs&lt;br /&gt;
```&lt;br /&gt;
sudo  zfs create -o mountpoint=/bkp zfspv-pool/bkp&lt;br /&gt;
sudo adduser bkp&lt;br /&gt;
sudo chown bkp:bkp /bkp&lt;br /&gt;
rsync -avz --recursive --bwlimit=10000 --exclude &amp;quot;hourly.&amp;quot; --relative -e &amp;quot;ssh -p 22 -l bkp&amp;quot; --progress /var/lib/influxdb 10.x.x.x:/bkp/myinfluxbkp&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Backup example&lt;br /&gt;
```&lt;br /&gt;
rsync -avzSuc --recursive --relative --delete -e &amp;quot;ssh -p 22 -i /home/user/.ssh/id_ed25519&amp;quot; --progress --files-from=files.dat / user@10.x.x.x:/home/busk/rsync --include-from=includes.dat --exclude-from=excludes.dat&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Use lxd container and lxc snapshots to manage state. You can use rdiff-backup command tool as well&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
sudo rsync --dry-run -rv -e &amp;quot;ssh -p 22 -i /home/myuser/.ssh/id_ed25519&amp;quot; --rsync-path=&amp;quot;sudo rsyn&lt;br /&gt;
c&amp;quot;  myuser@10.x.x.x:/bkp/foo /docker/&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Rsync&amp;diff=5699</id>
		<title>Rsync</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Rsync&amp;diff=5699"/>
		<updated>2026-05-31T22:33:41Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;# Backup Command&lt;br /&gt;
&lt;br /&gt;
rsync -axSH --dry-run --progress ~/.cache/huggingface/hub/ /ai/hf_cache/hub/&lt;br /&gt;
&lt;br /&gt;
rate limit 10000 Kbytes per second on zfs&lt;br /&gt;
```&lt;br /&gt;
sudo  zfs create -o mountpoint=/bkp zfspv-pool/bkp&lt;br /&gt;
sudo adduser bkp&lt;br /&gt;
sudo chown bkp:bkp /bkp&lt;br /&gt;
rsync -avz --recursive --bwlimit=10000 --exclude &amp;quot;hourly.&amp;quot; --relative -e &amp;quot;ssh -p 22 -l bkp&amp;quot; --progress /var/lib/influxdb 10.x.x.x:/bkp/myinfluxbkp&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Backup example&lt;br /&gt;
```&lt;br /&gt;
rsync -avzSuc --recursive --relative --delete -e &amp;quot;ssh -p 22 -i /home/user/.ssh/id_ed25519&amp;quot; --progress --files-from=files.dat / user@10.x.x.x:/home/busk/rsync --include-from=includes.dat --exclude-from=excludes.dat&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Use lxd container and lxc snapshots to manage state. You can use rdiff-backup command tool as well&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
sudo rsync --dry-run -rv -e &amp;quot;ssh -p 22 -i /home/myuser/.ssh/id_ed25519&amp;quot; --rsync-path=&amp;quot;sudo rsyn&lt;br /&gt;
c&amp;quot;  myuser@10.x.x.x:/bkp/foo /docker/&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Amdgpu_rocm&amp;diff=5698</id>
		<title>Amdgpu rocm</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Amdgpu_rocm&amp;diff=5698"/>
		<updated>2026-05-26T02:27:30Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;# Make sure keyring dir exists&lt;br /&gt;
sudo mkdir --parents --mode=0755 /etc/apt/keyrings&lt;br /&gt;
&lt;br /&gt;
# Refresh AMD key, same as you already did&lt;br /&gt;
wget https://repo.radeon.com/rocm/rocm.gpg.key -O - | \&lt;br /&gt;
  gpg --dearmor | sudo tee /etc/apt/keyrings/rocm.gpg &amp;gt; /dev/null&lt;br /&gt;
&lt;br /&gt;
# Add the missing AMDGPU kernel-driver repo for Ubuntu 24.04 / noble&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/amdgpu.list &amp;gt; /dev/null &amp;lt;&amp;lt;'EOF'&lt;br /&gt;
deb [arch=amd64 signed-by=/etc/apt/keyrings/rocm.gpg] https://repo.radeon.com/amdgpu/30.30.3/ubuntu noble main&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
# Confirm apt now sees it&lt;br /&gt;
apt-cache policy amdgpu-dkms&lt;br /&gt;
&lt;br /&gt;
# Install prerequisites + driver&lt;br /&gt;
sudo apt install &amp;quot;linux-headers-$(uname -r)&amp;quot; &amp;quot;linux-modules-extra-$(uname -r)&amp;quot;&lt;br /&gt;
sudo apt install amdgpu-dkms&lt;br /&gt;
&lt;br /&gt;
# Add yourself for ROCm access, then reboot&lt;br /&gt;
sudo usermod -a -G render,video &amp;quot;$LOGNAME&amp;quot;&lt;br /&gt;
sudo reboot&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Test&lt;br /&gt;
```&lt;br /&gt;
dkms status | grep -i amdgpu&lt;br /&gt;
lsmod | grep amdgpu&lt;br /&gt;
ls /dev/kfd /dev/dri/render*&lt;br /&gt;
rocminfo | head&lt;br /&gt;
amd-smi list&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Amdgpu_rocm&amp;diff=5697</id>
		<title>Amdgpu rocm</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Amdgpu_rocm&amp;diff=5697"/>
		<updated>2026-05-26T02:23:14Z</updated>

		<summary type="html">&lt;p&gt;Busk: Created page with &amp;quot;# Make sure keyring dir exists sudo mkdir --parents --mode=0755 /etc/apt/keyrings  # Refresh AMD key, same as you already did wget https://repo.radeon.com/rocm/rocm.gpg.key -O...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;# Make sure keyring dir exists&lt;br /&gt;
sudo mkdir --parents --mode=0755 /etc/apt/keyrings&lt;br /&gt;
&lt;br /&gt;
# Refresh AMD key, same as you already did&lt;br /&gt;
wget https://repo.radeon.com/rocm/rocm.gpg.key -O - | \&lt;br /&gt;
  gpg --dearmor | sudo tee /etc/apt/keyrings/rocm.gpg &amp;gt; /dev/null&lt;br /&gt;
&lt;br /&gt;
# Add the missing AMDGPU kernel-driver repo for Ubuntu 24.04 / noble&lt;br /&gt;
sudo tee /etc/apt/sources.list.d/amdgpu.list &amp;gt; /dev/null &amp;lt;&amp;lt;'EOF'&lt;br /&gt;
deb [arch=amd64 signed-by=/etc/apt/keyrings/rocm.gpg] https://repo.radeon.com/amdgpu/30.30.3/ubuntu noble main&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
sudo apt update&lt;br /&gt;
&lt;br /&gt;
# Confirm apt now sees it&lt;br /&gt;
apt-cache policy amdgpu-dkms&lt;br /&gt;
&lt;br /&gt;
# Install prerequisites + driver&lt;br /&gt;
sudo apt install &amp;quot;linux-headers-$(uname -r)&amp;quot; &amp;quot;linux-modules-extra-$(uname -r)&amp;quot;&lt;br /&gt;
sudo apt install amdgpu-dkms&lt;br /&gt;
&lt;br /&gt;
# Add yourself for ROCm access, then reboot&lt;br /&gt;
sudo usermod -a -G render,video &amp;quot;$LOGNAME&amp;quot;&lt;br /&gt;
sudo reboot&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Rocm&amp;diff=5696</id>
		<title>Rocm</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Rocm&amp;diff=5696"/>
		<updated>2026-05-26T02:04:13Z</updated>

		<summary type="html">&lt;p&gt;Busk: Created page with &amp;quot;https://rocm.docs.amd.com/projects/install-on-linux/en/latest/install/install-methods/package-manager/package-manager-ubuntu.html&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;https://rocm.docs.amd.com/projects/install-on-linux/en/latest/install/install-methods/package-manager/package-manager-ubuntu.html&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Zfs_optimization&amp;diff=5695</id>
		<title>Zfs optimization</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Zfs_optimization&amp;diff=5695"/>
		<updated>2026-05-25T15:56:52Z</updated>

		<summary type="html">&lt;p&gt;Busk: Created page with &amp;quot;# ZFS Optimization Get &amp;amp; Set  ## Get current settings for pool ``` #!/bin/bash  if [ -z &amp;quot;$1&amp;quot; ]; then     echo &amp;quot;Usage: $0 &amp;lt;pool_name&amp;gt;&amp;quot;     exit 1 fi  POOL=&amp;quot;$1&amp;quot;  if ! zpool list...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;# ZFS Optimization Get &amp;amp; Set&lt;br /&gt;
&lt;br /&gt;
## Get current settings for pool&lt;br /&gt;
```&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
if [ -z &amp;quot;$1&amp;quot; ]; then&lt;br /&gt;
    echo &amp;quot;Usage: $0 &amp;lt;pool_name&amp;gt;&amp;quot;&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
POOL=&amp;quot;$1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if ! zpool list &amp;quot;$POOL&amp;quot; &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br /&gt;
    echo &amp;quot;Error: Pool '$POOL' does not exist.&amp;quot;&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;=== ZFS Pool Alignment ===&amp;quot;&lt;br /&gt;
zpool get ashift &amp;quot;$POOL&amp;quot;&lt;br /&gt;
echo &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;=== Dataset Optimizations ===&amp;quot;&lt;br /&gt;
zfs get recordsize,atime,compression &amp;quot;$POOL&amp;quot;&lt;br /&gt;
echo &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;=== TRIM Status ===&amp;quot;&lt;br /&gt;
zpool get autotrim &amp;quot;$POOL&amp;quot;&lt;br /&gt;
echo &amp;quot;&amp;quot;&lt;br /&gt;
zpool status -t &amp;quot;$POOL&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
# Set optimization&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
if [ -z &amp;quot;$1&amp;quot; ]; then&lt;br /&gt;
    echo &amp;quot;Usage: $0 &amp;lt;pool_name&amp;gt;&amp;quot;&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
POOL=&amp;quot;$1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
if ! zpool list &amp;quot;$POOL&amp;quot; &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br /&gt;
    echo &amp;quot;Error: Pool '$POOL' does not exist.&amp;quot;&lt;br /&gt;
    exit 1&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
zfs set recordsize=1M &amp;quot;$POOL&amp;quot;&lt;br /&gt;
zfs set atime=off &amp;quot;$POOL&amp;quot;&lt;br /&gt;
zpool set autotrim=on &amp;quot;$POOL&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Optimization settings applied to pool '$POOL'.&amp;quot;&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Codex_use_local_openai_api&amp;diff=5694</id>
		<title>Codex use local openai api</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Codex_use_local_openai_api&amp;diff=5694"/>
		<updated>2026-05-22T15:57:28Z</updated>

		<summary type="html">&lt;p&gt;Busk: Created page with &amp;quot;To point the **Codex CLI** to your local `llama-server`, you primarily need to override the environment variables that the tool uses to locate the OpenAI API.  Since the Codex...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;To point the **Codex CLI** to your local `llama-server`, you primarily need to override the environment variables that the tool uses to locate the OpenAI API.&lt;br /&gt;
&lt;br /&gt;
Since the Codex CLI (and most OpenAI-compatible tools) follows standard OpenAI SDK conventions, you can redirect its traffic by pointing `OPENAI_BASE_URL` to your local endpoint.&lt;br /&gt;
&lt;br /&gt;
### 1. Set the Environment Variables&lt;br /&gt;
&lt;br /&gt;
You need to set these in your shell configuration (e.g., `~/.zshrc`, `~/.bashrc`) or for the specific session where you run the command.&lt;br /&gt;
&lt;br /&gt;
* **`OPENAI_BASE_URL`**: Set this to your `llama-server` address, ensuring you include the `/v1` path.&lt;br /&gt;
* **`OPENAI_API_KEY`**: Even if your `llama-server` doesn't require authentication, the CLI usually expects this variable to exist. You can set it to any dummy string (e.g., `sk-no-key`).&lt;br /&gt;
&lt;br /&gt;
**Example for your shell configuration:**&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
export OPENAI_BASE_URL=&amp;quot;http://localhost:8080/v1&amp;quot;&lt;br /&gt;
export OPENAI_API_KEY=&amp;quot;sk-not-needed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
*After saving this, run `source ~/.zshrc` (or your relevant shell config file) to apply the changes.*&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
### 2. Configure via `config.toml` (Optional/Permanent)&lt;br /&gt;
&lt;br /&gt;
If you prefer a more permanent configuration—or if you need to use a specific model name that `llama-server` might not report by default—you can define a provider profile in the Codex CLI configuration file, typically located at `~/.codex/config.toml`.&lt;br /&gt;
&lt;br /&gt;
Add a custom provider section like this:&lt;br /&gt;
&lt;br /&gt;
```toml&lt;br /&gt;
# In ~/.codex/config.toml&lt;br /&gt;
&lt;br /&gt;
[model_providers.local]&lt;br /&gt;
name = &amp;quot;Llama Server&amp;quot;&lt;br /&gt;
base_url = &amp;quot;http://localhost:8080/v1&amp;quot;&lt;br /&gt;
env_key = &amp;quot;OPENAI_API_KEY&amp;quot;&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
### 3. Verify the Connection&lt;br /&gt;
&lt;br /&gt;
Once the environment variables are set, test the connection by running a simple command:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
codex &amp;quot;What is the capital of Utah?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
### Important Tips for Local Models&lt;br /&gt;
&lt;br /&gt;
* **Model Name:** If the CLI complains that the &amp;quot;model is not found,&amp;quot; you may need to explicitly specify the model name that `llama-server` is reporting. You can check what models are available by hitting the `/v1/models` endpoint directly:&lt;br /&gt;
`curl http://localhost:8080/v1/models`&lt;br /&gt;
* **Compatibility:** Some &amp;quot;agentic&amp;quot; features of high-end CLI tools rely on OpenAI-specific function calling or vision capabilities. Depending on the model you are running in `llama.cpp` (e.g., a standard Llama 3 vs. a specialized coding model), some advanced agentic behaviors might have varying success compared to using a proprietary model like `gpt-4o`.&lt;br /&gt;
* **SSL/HTTPS:** Ensure your `llama-server` is running on `http` (or that you handle any certificate issues if you've enabled HTTPS), as CLI tools often fail with self-signed local certificates.&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Zfs_nvme_log_and_cache&amp;diff=5693</id>
		<title>Zfs nvme log and cache</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Zfs_nvme_log_and_cache&amp;diff=5693"/>
		<updated>2026-05-22T15:42:26Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;```&lt;br /&gt;
sudo nvme list&lt;br /&gt;
Node                  Generic               SN                   Model                                    Namespace  Usage                      Format           FW Rev&lt;br /&gt;
--------------------- --------------------- -------------------- ---------------------------------------- ---------- -------------------------- ---------------- --------&lt;br /&gt;
/dev/nvme0n1          /dev/ng0n1            CVFT439300062P0EGN   INTEL SSDPEDMD020T4                      0x1          2.00  TB /   2.00  TB    512   B +  0 B   8DV101H0&lt;br /&gt;
&lt;br /&gt;
# 1. Create a new GPT partition table&lt;br /&gt;
sudo parted /dev/nvme0n1 mklabel gpt&lt;br /&gt;
&lt;br /&gt;
# 2. Create the first 1TB partition (for SLOG)&lt;br /&gt;
sudo parted -a optimal /dev/nvme0n1 mkpart primary 0% 1TB&lt;br /&gt;
&lt;br /&gt;
# 3. Create the second 1TB partition (for L2ARC)&lt;br /&gt;
sudo parted -a optimal /dev/nvme0n1 mkpart primary 1TB 100%&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
lsblk /dev/nvme0n1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Add to log&lt;br /&gt;
sudo zpool add &amp;lt;pool_name&amp;gt; log /dev/nvme0n1p1&lt;br /&gt;
&lt;br /&gt;
# Add to cache&lt;br /&gt;
sudo zpool add &amp;lt;pool_name&amp;gt; cache /dev/nvme0n1p2&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Removal &amp;amp; Size Updates&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To change the size, you must remove the devices from the pool, repartition the drive, and add the new partitions back.&lt;br /&gt;
&lt;br /&gt;
### The Removal Process&lt;br /&gt;
&lt;br /&gt;
When you want to change the size, follow this sequence:&lt;br /&gt;
&lt;br /&gt;
1. **Remove the log (SLOG) device:**&lt;br /&gt;
```bash&lt;br /&gt;
zpool remove &amp;lt;pool_name&amp;gt; /dev/nvme0n1p1&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
    *Note: ZFS will gracefully flush any pending synchronous writes from the SLOG to the main pool before removing the device.*&lt;br /&gt;
&lt;br /&gt;
2.  **Remove the cache (L2ARC) device:**&lt;br /&gt;
    ```bash&lt;br /&gt;
    zpool remove &amp;lt;pool_name&amp;gt; /dev/nvme0n1p2&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
*Note: This is instantaneous as it simply drops the cache.*&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
3. **Repartition the drive:**&lt;br /&gt;
Use `parted` or `fdisk` to delete the old partitions and create the new ones to your desired sizes.&lt;br /&gt;
4. **Add them back to the pool:**&lt;br /&gt;
```bash&lt;br /&gt;
zpool add &amp;lt;pool_name&amp;gt; log /dev/nvme0n1p1&lt;br /&gt;
zpool add &amp;lt;pool_name&amp;gt; cache /dev/nvme0n1p2&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
### Architect's Tip: Use LVM for Flexibility&lt;br /&gt;
If you anticipate wanting to resize these partitions later without wiping and recreating them, consider using **LVM (Logical Volume Manager)** as an intermediary layer.&lt;br /&gt;
&lt;br /&gt;
1.  Initialize the physical drive as an LVM Physical Volume (PV).&lt;br /&gt;
2.  Create a Volume Group (VG).&lt;br /&gt;
3.  Create two Logical Volumes (LV) — one for SLOG, one for L2ARC.&lt;br /&gt;
4.  Point ZFS to the device-mapper paths (e.g., `/dev/mapper/vgname-lvname`).&lt;br /&gt;
&lt;br /&gt;
**Why do this?**&lt;br /&gt;
*   **Elasticity:** You can grow or shrink the logical volumes on the fly.&lt;br /&gt;
*   **Abstraction:** You can move your ZFS log/cache to a different physical disk later by using `pvmove` without ever having to `zpool remove` or re-add the devices to ZFS.&lt;br /&gt;
&lt;br /&gt;
**Important Warning:** If you go the LVM route, ensure you are not creating a circular dependency where your root filesystem (and thus LVM) depends on a ZFS pool that is trying to access an LVM volume. Given your expertise, this is likely a non-issue, but it is a common pitfall.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Zfs_nvme_log_and_cache&amp;diff=5692</id>
		<title>Zfs nvme log and cache</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Zfs_nvme_log_and_cache&amp;diff=5692"/>
		<updated>2026-05-22T15:42:11Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;```&lt;br /&gt;
sudo nvme list&lt;br /&gt;
Node                  Generic               SN                   Model                                    Namespace  Usage                      Format           FW Rev&lt;br /&gt;
--------------------- --------------------- -------------------- ---------------------------------------- ---------- -------------------------- ---------------- --------&lt;br /&gt;
/dev/nvme0n1          /dev/ng0n1            CVFT439300062P0EGN   INTEL SSDPEDMD020T4                      0x1          2.00  TB /   2.00  TB    512   B +  0 B   8DV101H0&lt;br /&gt;
&lt;br /&gt;
# 1. Create a new GPT partition table&lt;br /&gt;
sudo parted /dev/nvme0n1 mklabel gpt&lt;br /&gt;
&lt;br /&gt;
# 2. Create the first 1TB partition (for SLOG)&lt;br /&gt;
sudo parted -a optimal /dev/nvme0n1 mkpart primary 0% 1TB&lt;br /&gt;
&lt;br /&gt;
# 3. Create the second 1TB partition (for L2ARC)&lt;br /&gt;
sudo parted -a optimal /dev/nvme0n1 mkpart primary 1TB 100%&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
lsblk /dev/nvme0n1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Add to log&lt;br /&gt;
sudo zpool add &amp;lt;pool_name&amp;gt; log /dev/nvme0n1p1&lt;br /&gt;
&lt;br /&gt;
# Add to cache&lt;br /&gt;
sudo zpool add &amp;lt;pool_name&amp;gt; cache /dev/nvme0n1p2&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Removal &amp;amp; Size Updates&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To change the size, you must remove the devices from the pool, repartition the drive, and add the new partitions back.&lt;br /&gt;
&lt;br /&gt;
### The Removal Process&lt;br /&gt;
&lt;br /&gt;
When you want to change the size, follow this sequence:&lt;br /&gt;
&lt;br /&gt;
1. **Remove the log (SLOG) device:**&lt;br /&gt;
```bash&lt;br /&gt;
zpool remove &amp;lt;pool_name&amp;gt; /dev/nvme0n1p1&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
    *Note: ZFS will gracefully flush any pending synchronous writes from the SLOG to the main pool before removing the device.*&lt;br /&gt;
&lt;br /&gt;
2.  **Remove the cache (L2ARC) device:**&lt;br /&gt;
    ```bash&lt;br /&gt;
    zpool remove &amp;lt;pool_name&amp;gt; /dev/nvme0n1p2&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
*Note: This is instantaneous as it simply drops the cache.*&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
3. **Repartition the drive:**&lt;br /&gt;
Use `parted` or `fdisk` to delete the old partitions and create the new ones to your desired sizes.&lt;br /&gt;
4. **Add them back to the pool:**&lt;br /&gt;
```bash&lt;br /&gt;
zpool add &amp;lt;pool_name&amp;gt; log /dev/nvme0n1p1&lt;br /&gt;
zpool add &amp;lt;pool_name&amp;gt; cache /dev/nvme0n1p2&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
### Architect's Tip: Use LVM for Flexibility&lt;br /&gt;
If you anticipate wanting to resize these partitions later without wiping and recreating them, consider using **LVM (Logical Volume Manager)** as an intermediary layer.&lt;br /&gt;
&lt;br /&gt;
1.  Initialize the physical drive as an LVM Physical Volume (PV).&lt;br /&gt;
2.  Create a Volume Group (VG).&lt;br /&gt;
3.  Create two Logical Volumes (LV) — one for SLOG, one for L2ARC.&lt;br /&gt;
4.  Point ZFS to the device-mapper paths (e.g., `/dev/mapper/vgname-lvname`).&lt;br /&gt;
&lt;br /&gt;
**Why do this?**&lt;br /&gt;
*   **Elasticity:** You can grow or shrink the logical volumes on the fly.&lt;br /&gt;
*   **Abstraction:** You can move your ZFS log/cache to a different physical disk later by using `pvmove` without ever having to `zpool remove` or re-add the devices to ZFS.&lt;br /&gt;
&lt;br /&gt;
**Important Warning:** If you go the LVM route, ensure you are not creating a circular dependency where your root filesystem (and thus LVM) depends on a ZFS pool that is trying to access an LVM volume. Given your expertise, this is likely a non-issue, but it is a common pitfall.&lt;br /&gt;
&lt;br /&gt;
Are you planning to stick with static partitioning, or does the LVM approach fit your current infrastructure design better?&lt;br /&gt;
&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Zfs_nvme_log_and_cache&amp;diff=5691</id>
		<title>Zfs nvme log and cache</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Zfs_nvme_log_and_cache&amp;diff=5691"/>
		<updated>2026-05-22T15:36:45Z</updated>

		<summary type="html">&lt;p&gt;Busk: Created page with &amp;quot;``` sudo nvme list Node                  Generic               SN                   Model                                    Namespace  Usage                      Format...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;```&lt;br /&gt;
sudo nvme list&lt;br /&gt;
Node                  Generic               SN                   Model                                    Namespace  Usage                      Format           FW Rev&lt;br /&gt;
--------------------- --------------------- -------------------- ---------------------------------------- ---------- -------------------------- ---------------- --------&lt;br /&gt;
/dev/nvme0n1          /dev/ng0n1            CVFT439300062P0EGN   INTEL SSDPEDMD020T4                      0x1          2.00  TB /   2.00  TB    512   B +  0 B   8DV101H0&lt;br /&gt;
&lt;br /&gt;
# 1. Create a new GPT partition table&lt;br /&gt;
sudo parted /dev/nvme0n1 mklabel gpt&lt;br /&gt;
&lt;br /&gt;
# 2. Create the first 1TB partition (for SLOG)&lt;br /&gt;
sudo parted -a optimal /dev/nvme0n1 mkpart primary 0% 1TB&lt;br /&gt;
&lt;br /&gt;
# 3. Create the second 1TB partition (for L2ARC)&lt;br /&gt;
sudo parted -a optimal /dev/nvme0n1 mkpart primary 1TB 100%&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
lsblk /dev/nvme0n1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Add to log&lt;br /&gt;
sudo zpool add &amp;lt;pool_name&amp;gt; log /dev/nvme0n1p1&lt;br /&gt;
&lt;br /&gt;
# Add to cache&lt;br /&gt;
sudo zpool add &amp;lt;pool_name&amp;gt; cache /dev/nvme0n1p2&lt;br /&gt;
&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Llama_optimization&amp;diff=5690</id>
		<title>Llama optimization</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Llama_optimization&amp;diff=5690"/>
		<updated>2026-05-13T17:32:49Z</updated>

		<summary type="html">&lt;p&gt;Busk: Created page with &amp;quot;Yes, that is a good **stable baseline**:  ```bash ./build/bin/llama-server \   -hf ggml-org/gpt-oss-20b-GGUF \   -ngl 999 \   -c 2048 \   -np 1 \   -t 8 \   --no-warmup \   --...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Yes, that is a good **stable baseline**:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./build/bin/llama-server \&lt;br /&gt;
  -hf ggml-org/gpt-oss-20b-GGUF \&lt;br /&gt;
  -ngl 999 \&lt;br /&gt;
  -c 2048 \&lt;br /&gt;
  -np 1 \&lt;br /&gt;
  -t 8 \&lt;br /&gt;
  --no-warmup \&lt;br /&gt;
  --cache-ram 0 \&lt;br /&gt;
  --host 0.0.0.0 \&lt;br /&gt;
  --port 8080&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
For your **Threadripper + 128 GB RAM + Tesla P40**, I’d optimize for **stability first**, not max speed. Your previous log showed GPT-OSS 20B fully loaded, with the P40 detected as compute capability 6.1 and about 22.9 GiB VRAM available, so the hardware is basically working. &lt;br /&gt;
&lt;br /&gt;
## My recommended P40-stable launcher&lt;br /&gt;
&lt;br /&gt;
Use this instead:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd ~/llama.cpp&lt;br /&gt;
&lt;br /&gt;
GGML_CUDA_DISABLE_GRAPHS=1 ./build/bin/llama-server \&lt;br /&gt;
  -hf ggml-org/gpt-oss-20b-GGUF \&lt;br /&gt;
  -ngl 999 \&lt;br /&gt;
  -c 2048 \&lt;br /&gt;
  -np 1 \&lt;br /&gt;
  -t 12 \&lt;br /&gt;
  -b 512 \&lt;br /&gt;
  -ub 256 \&lt;br /&gt;
  --no-warmup \&lt;br /&gt;
  --cache-ram 0 \&lt;br /&gt;
  --host 0.0.0.0 \&lt;br /&gt;
  --port 8080&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Why:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
GGML_CUDA_DISABLE_GRAPHS=1  Avoids CUDA graph weirdness on older GPUs.&lt;br /&gt;
-c 2048                     Lower context = lower KV/cache pressure.&lt;br /&gt;
-np 1                       One request/slot at a time.&lt;br /&gt;
-t 12                       Enough CPU threads without pegging Threadripper.&lt;br /&gt;
-b 512 -ub 256              Smaller batches; slower maybe, but less crashy.&lt;br /&gt;
--cache-ram 0               Avoids prompt cache save/load path that appeared near your crash.&lt;br /&gt;
--no-warmup                 Avoids extra startup GPU work.&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
CUDA graphs can improve performance, but they are also an area where llama.cpp has had CUDA-specific edge cases and workarounds; disabling them is a reasonable stability choice on Pascal/P40. NVIDIA’s CUDA-graphs writeup explains why they are used for performance, while llama.cpp issue/discussion threads show cases where disabling CUDA graphs is used as a workaround. ([NVIDIA Developer][1])&lt;br /&gt;
&lt;br /&gt;
## Auto-detect launcher script&lt;br /&gt;
&lt;br /&gt;
Create this:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cat &amp;gt; ~/run-llama-gpt-oss.sh &amp;lt;&amp;lt;'EOF'&lt;br /&gt;
#!/usr/bin/env bash&lt;br /&gt;
set -euo pipefail&lt;br /&gt;
&lt;br /&gt;
MODEL_REPO=&amp;quot;${MODEL_REPO:-ggml-org/gpt-oss-20b-GGUF}&amp;quot;&lt;br /&gt;
HOST=&amp;quot;${HOST:-0.0.0.0}&amp;quot;&lt;br /&gt;
PORT=&amp;quot;${PORT:-8080}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Detect CPU threads.&lt;br /&gt;
CPU_THREADS=&amp;quot;$(nproc)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Use about half the CPU threads, capped. Good for responsiveness.&lt;br /&gt;
if (( CPU_THREADS &amp;gt;= 32 )); then&lt;br /&gt;
  THREADS=12&lt;br /&gt;
elif (( CPU_THREADS &amp;gt;= 16 )); then&lt;br /&gt;
  THREADS=8&lt;br /&gt;
else&lt;br /&gt;
  THREADS=$(( CPU_THREADS / 2 ))&lt;br /&gt;
  (( THREADS &amp;lt; 4 )) &amp;amp;&amp;amp; THREADS=4&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# Detect system RAM in GiB.&lt;br /&gt;
RAM_GB=&amp;quot;$(awk '/MemTotal/ { printf &amp;quot;%d&amp;quot;, $2/1024/1024 }' /proc/meminfo)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Detect NVIDIA VRAM in MiB.&lt;br /&gt;
if command -v nvidia-smi &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then&lt;br /&gt;
  VRAM_MIB=&amp;quot;$(nvidia-smi --query-gpu=memory.total --format=csv,noheader,nounits | head -n1 | tr -d ' ')&amp;quot;&lt;br /&gt;
  GPU_NAME=&amp;quot;$(nvidia-smi --query-gpu=name --format=csv,noheader | head -n1)&amp;quot;&lt;br /&gt;
else&lt;br /&gt;
  VRAM_MIB=0&lt;br /&gt;
  GPU_NAME=&amp;quot;none&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# Conservative defaults for older GPUs.&lt;br /&gt;
CTX=2048&lt;br /&gt;
NP=1&lt;br /&gt;
BATCH=512&lt;br /&gt;
UBATCH=256&lt;br /&gt;
NGL=999&lt;br /&gt;
CACHE_RAM=0&lt;br /&gt;
NO_WARMUP=&amp;quot;--no-warmup&amp;quot;&lt;br /&gt;
CUDA_ENV=&amp;quot;GGML_CUDA_DISABLE_GRAPHS=1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# If VRAM is very small, reduce context/batch.&lt;br /&gt;
if (( VRAM_MIB &amp;gt; 0 &amp;amp;&amp;amp; VRAM_MIB &amp;lt; 16000 )); then&lt;br /&gt;
  CTX=1024&lt;br /&gt;
  BATCH=256&lt;br /&gt;
  UBATCH=128&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# If VRAM is &amp;gt;= 32GB, allow larger context.&lt;br /&gt;
if (( VRAM_MIB &amp;gt;= 32000 )); then&lt;br /&gt;
  CTX=4096&lt;br /&gt;
  BATCH=1024&lt;br /&gt;
  UBATCH=512&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
# Detect Pascal/P40-ish GPU and keep safer settings.&lt;br /&gt;
if echo &amp;quot;$GPU_NAME&amp;quot; | grep -Eiq 'P40|P100|Pascal|GTX 10'; then&lt;br /&gt;
  CTX=2048&lt;br /&gt;
  NP=1&lt;br /&gt;
  BATCH=512&lt;br /&gt;
  UBATCH=256&lt;br /&gt;
  CACHE_RAM=0&lt;br /&gt;
  CUDA_ENV=&amp;quot;GGML_CUDA_DISABLE_GRAPHS=1&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Detected:&amp;quot;&lt;br /&gt;
echo &amp;quot;  CPU threads: $CPU_THREADS&amp;quot;&lt;br /&gt;
echo &amp;quot;  RAM:         ${RAM_GB} GiB&amp;quot;&lt;br /&gt;
echo &amp;quot;  GPU:         $GPU_NAME&amp;quot;&lt;br /&gt;
echo &amp;quot;  VRAM:        ${VRAM_MIB} MiB&amp;quot;&lt;br /&gt;
echo&lt;br /&gt;
echo &amp;quot;Launching llama-server:&amp;quot;&lt;br /&gt;
echo &amp;quot;  model repo:  $MODEL_REPO&amp;quot;&lt;br /&gt;
echo &amp;quot;  ctx:         $CTX&amp;quot;&lt;br /&gt;
echo &amp;quot;  parallel:    $NP&amp;quot;&lt;br /&gt;
echo &amp;quot;  threads:     $THREADS&amp;quot;&lt;br /&gt;
echo &amp;quot;  batch:       $BATCH&amp;quot;&lt;br /&gt;
echo &amp;quot;  ubatch:      $UBATCH&amp;quot;&lt;br /&gt;
echo &amp;quot;  cache-ram:   $CACHE_RAM&amp;quot;&lt;br /&gt;
echo&lt;br /&gt;
&lt;br /&gt;
cd &amp;quot;$HOME/llama.cpp&amp;quot;&lt;br /&gt;
&lt;br /&gt;
exec env $CUDA_ENV ./build/bin/llama-server \&lt;br /&gt;
  -hf &amp;quot;$MODEL_REPO&amp;quot; \&lt;br /&gt;
  -ngl &amp;quot;$NGL&amp;quot; \&lt;br /&gt;
  -c &amp;quot;$CTX&amp;quot; \&lt;br /&gt;
  -np &amp;quot;$NP&amp;quot; \&lt;br /&gt;
  -t &amp;quot;$THREADS&amp;quot; \&lt;br /&gt;
  -b &amp;quot;$BATCH&amp;quot; \&lt;br /&gt;
  -ub &amp;quot;$UBATCH&amp;quot; \&lt;br /&gt;
  $NO_WARMUP \&lt;br /&gt;
  --cache-ram &amp;quot;$CACHE_RAM&amp;quot; \&lt;br /&gt;
  --host &amp;quot;$HOST&amp;quot; \&lt;br /&gt;
  --port &amp;quot;$PORT&amp;quot;&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
chmod +x ~/run-llama-gpt-oss.sh&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Run it:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
~/run-llama-gpt-oss.sh&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## Test command&lt;br /&gt;
&lt;br /&gt;
In another terminal:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
curl -N http://127.0.0.1:8080/v1/chat/completions \&lt;br /&gt;
  -H 'Content-Type: application/json' \&lt;br /&gt;
  -d '{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;gpt-oss-20b&amp;quot;,&lt;br /&gt;
    &amp;quot;stream&amp;quot;: true,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;,&lt;br /&gt;
        &amp;quot;content&amp;quot;: &amp;quot;Output only valid Python code. No markdown. Create a small Dog class with name, breed, age, tricks, add_trick(), and __str__().&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;temperature&amp;quot;: 0.2,&lt;br /&gt;
    &amp;quot;max_tokens&amp;quot;: 250&lt;br /&gt;
  }'&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## About auto-detecting `max_tokens`&lt;br /&gt;
&lt;br /&gt;
`max_tokens` is **per request**, not really a server setting. The server can control context size with `-c`, but each API request should still set `max_tokens`.&lt;br /&gt;
&lt;br /&gt;
Simple rule:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Small answer:      max_tokens 50-150&lt;br /&gt;
Small code:        max_tokens 200-500&lt;br /&gt;
Medium code:       max_tokens 800-1500&lt;br /&gt;
Long file/design:  max_tokens 2000+&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
For the P40, I’d keep most tests at:&lt;br /&gt;
&lt;br /&gt;
```json&lt;br /&gt;
&amp;quot;max_tokens&amp;quot;: 250&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Then increase only when needed.&lt;br /&gt;
&lt;br /&gt;
## Add a simple curl wrapper&lt;br /&gt;
&lt;br /&gt;
Create this:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cat &amp;gt; ~/ask-llama.sh &amp;lt;&amp;lt;'EOF'&lt;br /&gt;
#!/usr/bin/env bash&lt;br /&gt;
set -euo pipefail&lt;br /&gt;
&lt;br /&gt;
PROMPT=&amp;quot;${*:-Say hello.}&amp;quot;&lt;br /&gt;
MAX_TOKENS=&amp;quot;${MAX_TOKENS:-300}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
curl -s http://127.0.0.1:8080/v1/chat/completions \&lt;br /&gt;
  -H 'Content-Type: application/json' \&lt;br /&gt;
  -d &amp;quot;$(jq -n \&lt;br /&gt;
    --arg prompt &amp;quot;$PROMPT&amp;quot; \&lt;br /&gt;
    --argjson max_tokens &amp;quot;$MAX_TOKENS&amp;quot; \&lt;br /&gt;
    '{&lt;br /&gt;
      model: &amp;quot;gpt-oss-20b&amp;quot;,&lt;br /&gt;
      messages: [&lt;br /&gt;
        {&lt;br /&gt;
          role: &amp;quot;user&amp;quot;,&lt;br /&gt;
          content: $prompt&lt;br /&gt;
        }&lt;br /&gt;
      ],&lt;br /&gt;
      temperature: 0.2,&lt;br /&gt;
      max_tokens: $max_tokens&lt;br /&gt;
    }')&amp;quot; | jq -r '.choices[0].message.content'&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
chmod +x ~/ask-llama.sh&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Use it:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
~/ask-llama.sh &amp;quot;Output only valid Python code. Create a hello world script.&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
With more output:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
MAX_TOKENS=800 ~/ask-llama.sh &amp;quot;Output only valid Python code. Create a Dog class with name, breed, age, tricks, add_trick(), and __str__().&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## My final recommendation&lt;br /&gt;
&lt;br /&gt;
For your P40, use:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
GGML_CUDA_DISABLE_GRAPHS=1&lt;br /&gt;
-c 2048&lt;br /&gt;
-np 1&lt;br /&gt;
-t 12&lt;br /&gt;
-b 512&lt;br /&gt;
-ub 256&lt;br /&gt;
--cache-ram 0&lt;br /&gt;
--no-warmup&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
After it is stable for a while, try performance increases one at a time:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
1. Increase -t from 12 to 16&lt;br /&gt;
2. Increase -c from 2048 to 4096&lt;br /&gt;
3. Increase -b 512 to 1024&lt;br /&gt;
4. Re-enable CUDA graphs only if everything else is stable&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Do not tune everything at once, because then you will not know what caused the next crash.&lt;br /&gt;
&lt;br /&gt;
[1]: https://developer.nvidia.com/blog/optimizing-llama-cpp-ai-inference-with-cuda-graphs/?utm_source=chatgpt.com &amp;quot;Optimizing llama.cpp AI Inference with CUDA Graphs&amp;quot;&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Llama_1&amp;diff=5689</id>
		<title>Llama 1</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Llama_1&amp;diff=5689"/>
		<updated>2026-05-13T16:32:10Z</updated>

		<summary type="html">&lt;p&gt;Busk: Created page with &amp;quot;`model.gguf` was just a placeholder. You need to download an actual `.gguf` file, such as:  ```text gpt-oss-20b-mxfp4.gguf ```  For GPT-OSS 20B, the Hugging Face repo is:  ```...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;`model.gguf` was just a placeholder. You need to download an actual `.gguf` file, such as:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
gpt-oss-20b-mxfp4.gguf&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
For GPT-OSS 20B, the Hugging Face repo is:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
ggml-org/gpt-oss-20b-GGUF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
The model page shows `gpt-oss-20b-mxfp4.gguf` as the file used by `llama.cpp` / `llama-cpp-python`, and it also supports direct `llama-server -hf ggml-org/gpt-oss-20b-GGUF`. ([Hugging Face][1])&lt;br /&gt;
&lt;br /&gt;
## Easiest: let `llama.cpp` download it&lt;br /&gt;
&lt;br /&gt;
From your `llama.cpp` directory:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd ~/llama.cpp&lt;br /&gt;
&lt;br /&gt;
./build/bin/llama-server \&lt;br /&gt;
  -hf ggml-org/gpt-oss-20b-GGUF \&lt;br /&gt;
  -ngl 999 \&lt;br /&gt;
  -c 4096 \&lt;br /&gt;
  --host 0.0.0.0 \&lt;br /&gt;
  --port 8080&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
The official quick start for this repo is basically:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
llama-server -hf ggml-org/gpt-oss-20b-GGUF -c 0 --jinja&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
([Hugging Face][2])&lt;br /&gt;
&lt;br /&gt;
For your P40, I would start with:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
-c 4096&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
rather than unlimited/context auto mode.&lt;br /&gt;
&lt;br /&gt;
## Manual download to a real file&lt;br /&gt;
&lt;br /&gt;
Install the Hugging Face CLI:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo apt install -y python3-pip&lt;br /&gt;
python3 -m pip install --user -U huggingface_hub&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Make sure your user-local Python bin path is active:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
export PATH=&amp;quot;$HOME/.local/bin:$PATH&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Create a model directory:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
mkdir -p ~/models/gpt-oss-20b&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Download the GGUF file:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
huggingface-cli download ggml-org/gpt-oss-20b-GGUF \&lt;br /&gt;
  gpt-oss-20b-mxfp4.gguf \&lt;br /&gt;
  --local-dir ~/models/gpt-oss-20b \&lt;br /&gt;
  --local-dir-use-symlinks False&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Then run it:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd ~/llama.cpp&lt;br /&gt;
&lt;br /&gt;
./build/bin/llama-server \&lt;br /&gt;
  -m ~/models/gpt-oss-20b/gpt-oss-20b-mxfp4.gguf \&lt;br /&gt;
  -ngl 999 \&lt;br /&gt;
  -c 4096 \&lt;br /&gt;
  --host 0.0.0.0 \&lt;br /&gt;
  --port 8080&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## Test it&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
curl http://127.0.0.1:8080/v1/chat/completions \&lt;br /&gt;
  -H 'Content-Type: application/json' \&lt;br /&gt;
  -d '{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;gpt-oss-20b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;,&lt;br /&gt;
        &amp;quot;content&amp;quot;: &amp;quot;Write a minimal Go HTTP health check server.&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;temperature&amp;quot;: 0.2&lt;br /&gt;
  }'&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## For Qwen later&lt;br /&gt;
&lt;br /&gt;
Same idea, but choose a Qwen GGUF repo instead. For example, Qwen’s docs show running Qwen models through `llama.cpp` using GGUF files. ([Hugging Face][3])&lt;br /&gt;
&lt;br /&gt;
For now, get GPT-OSS 20B working first with:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
-hf ggml-org/gpt-oss-20b-GGUF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
or with the downloaded file:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
-m ~/models/gpt-oss-20b/gpt-oss-20b-mxfp4.gguf&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
[1]: https://huggingface.co/ggml-org/gpt-oss-20b-GGUF?utm_source=chatgpt.com &amp;quot;ggml-org/gpt-oss-20b-GGUF&amp;quot;&lt;br /&gt;
[2]: https://huggingface.co/ggml-org/gpt-oss-20b-GGUF/resolve/main/README.md?download=true&amp;amp;utm_source=chatgpt.com &amp;quot;285 Bytes&amp;quot;&lt;br /&gt;
[3]: https://huggingface.co/docs/inference-endpoints/engines/llama_cpp?utm_source=chatgpt.com &amp;quot;llama.cpp&amp;quot;&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Tesla_P40_llama.cpp&amp;diff=5688</id>
		<title>Tesla P40 llama.cpp</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Tesla_P40_llama.cpp&amp;diff=5688"/>
		<updated>2026-05-13T16:25:46Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;```&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-cuda-toolkit&lt;br /&gt;
sudo apt install -y git cmake build-essential curl libcurl4-openssl-dev&lt;br /&gt;
&lt;br /&gt;
git clone https://github.com/ggml-org/llama.cpp&lt;br /&gt;
cd llama.cpp&lt;br /&gt;
&lt;br /&gt;
cmake -B build -DGGML_CUDA=ON&lt;br /&gt;
cmake --build build --config Release -j&amp;quot;$(nproc)&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
That error is simple: **your NVIDIA driver is installed, but the CUDA Toolkit compiler is not.**&lt;br /&gt;
&lt;br /&gt;
`nvidia-smi` working means the **driver/runtime** is working.&lt;br /&gt;
Building `llama.cpp` with CUDA requires **`nvcc`**, which comes from the **CUDA Toolkit**, not from `nvidia-utils`. NVIDIA’s CUDA Linux install guide separates the driver from CUDA development tools/toolkit. ([NVIDIA Docs][1])&lt;br /&gt;
&lt;br /&gt;
Check:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
which nvcc&lt;br /&gt;
nvcc --version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Right now those probably fail.&lt;br /&gt;
&lt;br /&gt;
## Best fix on Ubuntu 24.04&lt;br /&gt;
&lt;br /&gt;
Since you are using `580-server` for the Tesla P40, I would install the Ubuntu CUDA toolkit package first:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-cuda-toolkit&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Then verify:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
which nvcc&lt;br /&gt;
nvcc --version&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Then rebuild `llama.cpp` cleanly:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
cd ~/llama.cpp&lt;br /&gt;
&lt;br /&gt;
rm -rf build&lt;br /&gt;
&lt;br /&gt;
cmake -B build \&lt;br /&gt;
  -DGGML_CUDA=ON \&lt;br /&gt;
  -DCMAKE_BUILD_TYPE=Release \&lt;br /&gt;
  -DCMAKE_CUDA_ARCHITECTURES=61&lt;br /&gt;
&lt;br /&gt;
cmake --build build --config Release -j&amp;quot;$(nproc)&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
The important part for Tesla P40 is:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
-DCMAKE_CUDA_ARCHITECTURES=61&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
P40 is Pascal, compute capability **6.1**. Setting that explicitly avoids CMake trying to guess or building unnecessary architectures.&lt;br /&gt;
&lt;br /&gt;
## If `nvidia-cuda-toolkit` is too old or missing&lt;br /&gt;
&lt;br /&gt;
Use NVIDIA’s CUDA repo/toolkit packages instead. For a P40, I would avoid chasing CUDA 13 unless needed. CUDA 12.x is safer for Pascal-era cards and llama.cpp.&lt;br /&gt;
&lt;br /&gt;
Example pattern:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo apt install -y cuda-toolkit-12-8&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Some Ubuntu 24.04 CUDA install docs show installing `cuda-toolkit-12-8` from NVIDIA’s repo after adding the CUDA repo/keyring. ([docs.leaf.cloud][2])&lt;br /&gt;
&lt;br /&gt;
But try this first:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo apt install -y nvidia-cuda-toolkit&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## Do not reinstall the NVIDIA driver&lt;br /&gt;
&lt;br /&gt;
Do **not** run a broad CUDA installer that replaces your working `580-server` driver with 590/595.&lt;br /&gt;
&lt;br /&gt;
You want:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Driver:       nvidia-driver-580-server&lt;br /&gt;
CUDA toolkit: nvcc/compiler only&lt;br /&gt;
llama.cpp:    built with GGML_CUDA=ON&lt;br /&gt;
Arch:         61 for Tesla P40&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
After build, test:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./build/bin/llama-cli --help | grep -i cuda&lt;br /&gt;
./build/bin/llama-bench --help&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Then run a small model or server with:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./build/bin/llama-server \&lt;br /&gt;
  -m /path/to/model.gguf \&lt;br /&gt;
  -ngl 999 \&lt;br /&gt;
  -c 4096 \&lt;br /&gt;
  --host 0.0.0.0 \&lt;br /&gt;
  --port 8080&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Your driver is fine now; you just need `nvcc`.&lt;br /&gt;
&lt;br /&gt;
[1]: https://docs.nvidia.com/cuda/cuda-installation-guide-linux/?utm_source=chatgpt.com &amp;quot;CUDA Installation Guide for Linux&amp;quot;&lt;br /&gt;
[2]: https://docs.leaf.cloud/en/latest/data-science/installing-gpu-drivers/?utm_source=chatgpt.com &amp;quot;Installing NVIDIA Drivers and CUDA on Ubuntu 24.04&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Yes — for a **Tesla P40**, I would use **`llama.cpp` first** for GPT-OSS, Qwen, DeepSeek, Llama, Gemma, etc.&lt;br /&gt;
&lt;br /&gt;
Your P40 is a great cheap 24 GB VRAM card, but it is **Pascal**, so it lacks Tensor Cores and newer datatype acceleration. That makes `llama.cpp` a better fit than heavier stacks like vLLM/TGI for most local single-GPU use.&lt;br /&gt;
&lt;br /&gt;
## Recommendation for your P40&lt;br /&gt;
&lt;br /&gt;
Use this stack:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Best low-friction stack:&lt;br /&gt;
llama.cpp + GGUF models + CUDA build&lt;br /&gt;
&lt;br /&gt;
Optional convenience layer:&lt;br /&gt;
Ollama or LM Studio&lt;br /&gt;
&lt;br /&gt;
Avoid as first choice on P40:&lt;br /&gt;
vLLM, TensorRT-LLM, exllamav2 for GPT-OSS&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
`llama.cpp` has active support for GPT-OSS and GGUF models, and there are ready GGUF builds for `gpt-oss-20b`. Hugging Face’s GGUF page for `ggml-org/gpt-oss-20b-GGUF` shows direct `llama.cpp`, `llama-cpp-python`, Ollama, LM Studio, and Jan usage paths. ([Hugging Face][1])&lt;br /&gt;
&lt;br /&gt;
For Qwen, the official Qwen docs also document running Qwen3/Qwen3MoE with `llama.cpp` and GGUF, with support starting from specific llama.cpp builds. ([Qwen][2])&lt;br /&gt;
&lt;br /&gt;
## What models fit your P40?&lt;br /&gt;
&lt;br /&gt;
With 24 GB VRAM:&lt;br /&gt;
&lt;br /&gt;
| Model type                       | Recommendation                              |&lt;br /&gt;
| -------------------------------- | ------------------------------------------- |&lt;br /&gt;
| GPT-OSS 20B                      | Good target                                 |&lt;br /&gt;
| GPT-OSS 120B                     | Not realistic on one P40                    |&lt;br /&gt;
| Qwen 7B / 14B / 30B-A3B MoE      | Good targets depending quant                |&lt;br /&gt;
| DeepSeek Coder / Qwen Coder GGUF | Good for coding                             |&lt;br /&gt;
| Llama 3.x 8B / 70B quantized     | 8B easy, 70B partially/offload or CPU spill |&lt;br /&gt;
| Mixtral / MoE GGUF               | Can work, speed varies                      |&lt;br /&gt;
&lt;br /&gt;
For your use — Go, SQL, Python, React, infra code — I would start with:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
1. Qwen coder GGUF model&lt;br /&gt;
2. GPT-OSS 20B GGUF&lt;br /&gt;
3. DeepSeek coder/distill GGUF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
For the P40 specifically, **GGUF quantized models** are the practical path.&lt;br /&gt;
&lt;br /&gt;
## Build `llama.cpp` with CUDA&lt;br /&gt;
&lt;br /&gt;
On Ubuntu:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y git cmake build-essential curl libcurl4-openssl-dev&lt;br /&gt;
&lt;br /&gt;
git clone https://github.com/ggml-org/llama.cpp&lt;br /&gt;
cd llama.cpp&lt;br /&gt;
&lt;br /&gt;
cmake -B build -DGGML_CUDA=ON&lt;br /&gt;
cmake --build build --config Release -j&amp;quot;$(nproc)&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Check CUDA offload works:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./build/bin/llama-cli --help | grep -i gpu&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## Run GPT-OSS 20B&lt;br /&gt;
&lt;br /&gt;
Example using llama.cpp’s Hugging Face download support:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./build/bin/llama-server \&lt;br /&gt;
  -hf ggml-org/gpt-oss-20b-GGUF \&lt;br /&gt;
  -ngl 999 \&lt;br /&gt;
  -c 8192 \&lt;br /&gt;
  --host 0.0.0.0 \&lt;br /&gt;
  --port 8080&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Then test OpenAI-compatible API:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
curl http://127.0.0.1:8080/v1/chat/completions \&lt;br /&gt;
  -H 'Content-Type: application/json' \&lt;br /&gt;
  -d '{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;gpt-oss-20b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [&lt;br /&gt;
      {&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Write a small Go HTTP server with health check.&amp;quot;}&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;temperature&amp;quot;: 0.2&lt;br /&gt;
  }'&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
If VRAM gets tight, reduce context:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
-c 4096&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Or reduce GPU layers:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
-ngl 60&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
But on a 24 GB P40, for many 20B-ish quantized GGUFs, this should be okay.&lt;br /&gt;
&lt;br /&gt;
## Run a Qwen coder model&lt;br /&gt;
&lt;br /&gt;
For coding, Qwen is probably where I would spend most of my time. Example:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./build/bin/llama-server \&lt;br /&gt;
  -hf unsloth/Qwen3-Coder-Next-GGUF \&lt;br /&gt;
  -ngl 999 \&lt;br /&gt;
  -c 8192 \&lt;br /&gt;
  --host 0.0.0.0 \&lt;br /&gt;
  --port 8080&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
The Unsloth Qwen GGUF page notes recent llama.cpp fixes for Qwen output/tool-calling behavior, so use a fresh llama.cpp build rather than an old distro package. ([Hugging Face][3])&lt;br /&gt;
&lt;br /&gt;
## Should you use Ollama instead?&lt;br /&gt;
&lt;br /&gt;
Ollama is easier, but `llama.cpp` gives you more direct control.&lt;br /&gt;
&lt;br /&gt;
Use **Ollama** if you want simple:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ollama run hf.co/ggml-org/gpt-oss-20b-GGUF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Use **llama.cpp directly** if you care about:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
GPU layer tuning&lt;br /&gt;
context size tuning&lt;br /&gt;
exact GGUF file selection&lt;br /&gt;
server flags&lt;br /&gt;
benchmarking&lt;br /&gt;
performance debugging&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Given how you work, I’d use **llama.cpp directly** first.&lt;br /&gt;
&lt;br /&gt;
## Should you use vLLM?&lt;br /&gt;
&lt;br /&gt;
For your **P40**, probably no — not as your first runtime.&lt;br /&gt;
&lt;br /&gt;
vLLM is excellent for newer GPUs and serving many users, but it tends to assume newer CUDA paths and benefits heavily from Tensor Cores / modern attention kernels. On Pascal P40, `llama.cpp` is usually simpler and more forgiving.&lt;br /&gt;
&lt;br /&gt;
I would use vLLM when you have something like:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
RTX 3090&lt;br /&gt;
RTX 4090&lt;br /&gt;
RTX PRO 4500 Blackwell&lt;br /&gt;
A10/A40/A100/H100/L40S&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
For the P40:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
llama.cpp &amp;gt; Ollama &amp;gt; exllamav2/vLLM experiments&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## My practical recommendation&lt;br /&gt;
&lt;br /&gt;
Start with:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Runtime: llama.cpp&lt;br /&gt;
Driver: 580-server&lt;br /&gt;
Model format: GGUF&lt;br /&gt;
First model: gpt-oss-20b-GGUF&lt;br /&gt;
Coding model: Qwen coder GGUF&lt;br /&gt;
Context: 4096 or 8192 first&lt;br /&gt;
GPU layers: -ngl 999&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Then benchmark:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./build/bin/llama-bench -m /path/to/model.gguf -ngl 999&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
For a single Tesla P40, **don’t chase the newest serving framework**. Use stable `580-server`, fresh `llama.cpp`, and GGUF models. That will give you the fewest headaches and the best compatibility.&lt;br /&gt;
&lt;br /&gt;
[1]: https://huggingface.co/ggml-org/gpt-oss-20b-GGUF?utm_source=chatgpt.com &amp;quot;ggml-org/gpt-oss-20b-GGUF&amp;quot;&lt;br /&gt;
[2]: https://qwen.readthedocs.io/en/latest/run_locally/llama.cpp.html?utm_source=chatgpt.com &amp;quot;llama.cpp - Qwen - Read the Docs&amp;quot;&lt;br /&gt;
[3]: https://huggingface.co/unsloth/Qwen3-Coder-Next-GGUF?utm_source=chatgpt.com &amp;quot;unsloth/Qwen3-Coder-Next-GGUF&amp;quot;&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Tesla_P40_llama.cpp&amp;diff=5687</id>
		<title>Tesla P40 llama.cpp</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Tesla_P40_llama.cpp&amp;diff=5687"/>
		<updated>2026-05-13T16:21:34Z</updated>

		<summary type="html">&lt;p&gt;Busk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;```&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y nvidia-cuda-toolkit&lt;br /&gt;
sudo apt install -y git cmake build-essential curl libcurl4-openssl-dev&lt;br /&gt;
&lt;br /&gt;
git clone https://github.com/ggml-org/llama.cpp&lt;br /&gt;
cd llama.cpp&lt;br /&gt;
&lt;br /&gt;
cmake -B build -DGGML_CUDA=ON&lt;br /&gt;
cmake --build build --config Release -j&amp;quot;$(nproc)&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Yes — for a **Tesla P40**, I would use **`llama.cpp` first** for GPT-OSS, Qwen, DeepSeek, Llama, Gemma, etc.&lt;br /&gt;
&lt;br /&gt;
Your P40 is a great cheap 24 GB VRAM card, but it is **Pascal**, so it lacks Tensor Cores and newer datatype acceleration. That makes `llama.cpp` a better fit than heavier stacks like vLLM/TGI for most local single-GPU use.&lt;br /&gt;
&lt;br /&gt;
## Recommendation for your P40&lt;br /&gt;
&lt;br /&gt;
Use this stack:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Best low-friction stack:&lt;br /&gt;
llama.cpp + GGUF models + CUDA build&lt;br /&gt;
&lt;br /&gt;
Optional convenience layer:&lt;br /&gt;
Ollama or LM Studio&lt;br /&gt;
&lt;br /&gt;
Avoid as first choice on P40:&lt;br /&gt;
vLLM, TensorRT-LLM, exllamav2 for GPT-OSS&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
`llama.cpp` has active support for GPT-OSS and GGUF models, and there are ready GGUF builds for `gpt-oss-20b`. Hugging Face’s GGUF page for `ggml-org/gpt-oss-20b-GGUF` shows direct `llama.cpp`, `llama-cpp-python`, Ollama, LM Studio, and Jan usage paths. ([Hugging Face][1])&lt;br /&gt;
&lt;br /&gt;
For Qwen, the official Qwen docs also document running Qwen3/Qwen3MoE with `llama.cpp` and GGUF, with support starting from specific llama.cpp builds. ([Qwen][2])&lt;br /&gt;
&lt;br /&gt;
## What models fit your P40?&lt;br /&gt;
&lt;br /&gt;
With 24 GB VRAM:&lt;br /&gt;
&lt;br /&gt;
| Model type                       | Recommendation                              |&lt;br /&gt;
| -------------------------------- | ------------------------------------------- |&lt;br /&gt;
| GPT-OSS 20B                      | Good target                                 |&lt;br /&gt;
| GPT-OSS 120B                     | Not realistic on one P40                    |&lt;br /&gt;
| Qwen 7B / 14B / 30B-A3B MoE      | Good targets depending quant                |&lt;br /&gt;
| DeepSeek Coder / Qwen Coder GGUF | Good for coding                             |&lt;br /&gt;
| Llama 3.x 8B / 70B quantized     | 8B easy, 70B partially/offload or CPU spill |&lt;br /&gt;
| Mixtral / MoE GGUF               | Can work, speed varies                      |&lt;br /&gt;
&lt;br /&gt;
For your use — Go, SQL, Python, React, infra code — I would start with:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
1. Qwen coder GGUF model&lt;br /&gt;
2. GPT-OSS 20B GGUF&lt;br /&gt;
3. DeepSeek coder/distill GGUF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
For the P40 specifically, **GGUF quantized models** are the practical path.&lt;br /&gt;
&lt;br /&gt;
## Build `llama.cpp` with CUDA&lt;br /&gt;
&lt;br /&gt;
On Ubuntu:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y git cmake build-essential curl libcurl4-openssl-dev&lt;br /&gt;
&lt;br /&gt;
git clone https://github.com/ggml-org/llama.cpp&lt;br /&gt;
cd llama.cpp&lt;br /&gt;
&lt;br /&gt;
cmake -B build -DGGML_CUDA=ON&lt;br /&gt;
cmake --build build --config Release -j&amp;quot;$(nproc)&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Check CUDA offload works:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./build/bin/llama-cli --help | grep -i gpu&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## Run GPT-OSS 20B&lt;br /&gt;
&lt;br /&gt;
Example using llama.cpp’s Hugging Face download support:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./build/bin/llama-server \&lt;br /&gt;
  -hf ggml-org/gpt-oss-20b-GGUF \&lt;br /&gt;
  -ngl 999 \&lt;br /&gt;
  -c 8192 \&lt;br /&gt;
  --host 0.0.0.0 \&lt;br /&gt;
  --port 8080&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Then test OpenAI-compatible API:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
curl http://127.0.0.1:8080/v1/chat/completions \&lt;br /&gt;
  -H 'Content-Type: application/json' \&lt;br /&gt;
  -d '{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;gpt-oss-20b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [&lt;br /&gt;
      {&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Write a small Go HTTP server with health check.&amp;quot;}&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;temperature&amp;quot;: 0.2&lt;br /&gt;
  }'&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
If VRAM gets tight, reduce context:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
-c 4096&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Or reduce GPU layers:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
-ngl 60&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
But on a 24 GB P40, for many 20B-ish quantized GGUFs, this should be okay.&lt;br /&gt;
&lt;br /&gt;
## Run a Qwen coder model&lt;br /&gt;
&lt;br /&gt;
For coding, Qwen is probably where I would spend most of my time. Example:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./build/bin/llama-server \&lt;br /&gt;
  -hf unsloth/Qwen3-Coder-Next-GGUF \&lt;br /&gt;
  -ngl 999 \&lt;br /&gt;
  -c 8192 \&lt;br /&gt;
  --host 0.0.0.0 \&lt;br /&gt;
  --port 8080&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
The Unsloth Qwen GGUF page notes recent llama.cpp fixes for Qwen output/tool-calling behavior, so use a fresh llama.cpp build rather than an old distro package. ([Hugging Face][3])&lt;br /&gt;
&lt;br /&gt;
## Should you use Ollama instead?&lt;br /&gt;
&lt;br /&gt;
Ollama is easier, but `llama.cpp` gives you more direct control.&lt;br /&gt;
&lt;br /&gt;
Use **Ollama** if you want simple:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ollama run hf.co/ggml-org/gpt-oss-20b-GGUF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Use **llama.cpp directly** if you care about:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
GPU layer tuning&lt;br /&gt;
context size tuning&lt;br /&gt;
exact GGUF file selection&lt;br /&gt;
server flags&lt;br /&gt;
benchmarking&lt;br /&gt;
performance debugging&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Given how you work, I’d use **llama.cpp directly** first.&lt;br /&gt;
&lt;br /&gt;
## Should you use vLLM?&lt;br /&gt;
&lt;br /&gt;
For your **P40**, probably no — not as your first runtime.&lt;br /&gt;
&lt;br /&gt;
vLLM is excellent for newer GPUs and serving many users, but it tends to assume newer CUDA paths and benefits heavily from Tensor Cores / modern attention kernels. On Pascal P40, `llama.cpp` is usually simpler and more forgiving.&lt;br /&gt;
&lt;br /&gt;
I would use vLLM when you have something like:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
RTX 3090&lt;br /&gt;
RTX 4090&lt;br /&gt;
RTX PRO 4500 Blackwell&lt;br /&gt;
A10/A40/A100/H100/L40S&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
For the P40:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
llama.cpp &amp;gt; Ollama &amp;gt; exllamav2/vLLM experiments&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## My practical recommendation&lt;br /&gt;
&lt;br /&gt;
Start with:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Runtime: llama.cpp&lt;br /&gt;
Driver: 580-server&lt;br /&gt;
Model format: GGUF&lt;br /&gt;
First model: gpt-oss-20b-GGUF&lt;br /&gt;
Coding model: Qwen coder GGUF&lt;br /&gt;
Context: 4096 or 8192 first&lt;br /&gt;
GPU layers: -ngl 999&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Then benchmark:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./build/bin/llama-bench -m /path/to/model.gguf -ngl 999&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
For a single Tesla P40, **don’t chase the newest serving framework**. Use stable `580-server`, fresh `llama.cpp`, and GGUF models. That will give you the fewest headaches and the best compatibility.&lt;br /&gt;
&lt;br /&gt;
[1]: https://huggingface.co/ggml-org/gpt-oss-20b-GGUF?utm_source=chatgpt.com &amp;quot;ggml-org/gpt-oss-20b-GGUF&amp;quot;&lt;br /&gt;
[2]: https://qwen.readthedocs.io/en/latest/run_locally/llama.cpp.html?utm_source=chatgpt.com &amp;quot;llama.cpp - Qwen - Read the Docs&amp;quot;&lt;br /&gt;
[3]: https://huggingface.co/unsloth/Qwen3-Coder-Next-GGUF?utm_source=chatgpt.com &amp;quot;unsloth/Qwen3-Coder-Next-GGUF&amp;quot;&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=Tesla_P40_llama.cpp&amp;diff=5686</id>
		<title>Tesla P40 llama.cpp</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=Tesla_P40_llama.cpp&amp;diff=5686"/>
		<updated>2026-05-13T16:19:32Z</updated>

		<summary type="html">&lt;p&gt;Busk: Created page with &amp;quot;``` sudo apt update sudo apt install -y git cmake build-essential curl libcurl4-openssl-dev  git clone https://github.com/ggml-org/llama.cpp cd llama.cpp  cmake -B build -DGGM...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;```&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y git cmake build-essential curl libcurl4-openssl-dev&lt;br /&gt;
&lt;br /&gt;
git clone https://github.com/ggml-org/llama.cpp&lt;br /&gt;
cd llama.cpp&lt;br /&gt;
&lt;br /&gt;
cmake -B build -DGGML_CUDA=ON&lt;br /&gt;
cmake --build build --config Release -j&amp;quot;$(nproc)&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Yes — for a **Tesla P40**, I would use **`llama.cpp` first** for GPT-OSS, Qwen, DeepSeek, Llama, Gemma, etc.&lt;br /&gt;
&lt;br /&gt;
Your P40 is a great cheap 24 GB VRAM card, but it is **Pascal**, so it lacks Tensor Cores and newer datatype acceleration. That makes `llama.cpp` a better fit than heavier stacks like vLLM/TGI for most local single-GPU use.&lt;br /&gt;
&lt;br /&gt;
## Recommendation for your P40&lt;br /&gt;
&lt;br /&gt;
Use this stack:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Best low-friction stack:&lt;br /&gt;
llama.cpp + GGUF models + CUDA build&lt;br /&gt;
&lt;br /&gt;
Optional convenience layer:&lt;br /&gt;
Ollama or LM Studio&lt;br /&gt;
&lt;br /&gt;
Avoid as first choice on P40:&lt;br /&gt;
vLLM, TensorRT-LLM, exllamav2 for GPT-OSS&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
`llama.cpp` has active support for GPT-OSS and GGUF models, and there are ready GGUF builds for `gpt-oss-20b`. Hugging Face’s GGUF page for `ggml-org/gpt-oss-20b-GGUF` shows direct `llama.cpp`, `llama-cpp-python`, Ollama, LM Studio, and Jan usage paths. ([Hugging Face][1])&lt;br /&gt;
&lt;br /&gt;
For Qwen, the official Qwen docs also document running Qwen3/Qwen3MoE with `llama.cpp` and GGUF, with support starting from specific llama.cpp builds. ([Qwen][2])&lt;br /&gt;
&lt;br /&gt;
## What models fit your P40?&lt;br /&gt;
&lt;br /&gt;
With 24 GB VRAM:&lt;br /&gt;
&lt;br /&gt;
| Model type                       | Recommendation                              |&lt;br /&gt;
| -------------------------------- | ------------------------------------------- |&lt;br /&gt;
| GPT-OSS 20B                      | Good target                                 |&lt;br /&gt;
| GPT-OSS 120B                     | Not realistic on one P40                    |&lt;br /&gt;
| Qwen 7B / 14B / 30B-A3B MoE      | Good targets depending quant                |&lt;br /&gt;
| DeepSeek Coder / Qwen Coder GGUF | Good for coding                             |&lt;br /&gt;
| Llama 3.x 8B / 70B quantized     | 8B easy, 70B partially/offload or CPU spill |&lt;br /&gt;
| Mixtral / MoE GGUF               | Can work, speed varies                      |&lt;br /&gt;
&lt;br /&gt;
For your use — Go, SQL, Python, React, infra code — I would start with:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
1. Qwen coder GGUF model&lt;br /&gt;
2. GPT-OSS 20B GGUF&lt;br /&gt;
3. DeepSeek coder/distill GGUF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
For the P40 specifically, **GGUF quantized models** are the practical path.&lt;br /&gt;
&lt;br /&gt;
## Build `llama.cpp` with CUDA&lt;br /&gt;
&lt;br /&gt;
On Ubuntu:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
sudo apt update&lt;br /&gt;
sudo apt install -y git cmake build-essential curl libcurl4-openssl-dev&lt;br /&gt;
&lt;br /&gt;
git clone https://github.com/ggml-org/llama.cpp&lt;br /&gt;
cd llama.cpp&lt;br /&gt;
&lt;br /&gt;
cmake -B build -DGGML_CUDA=ON&lt;br /&gt;
cmake --build build --config Release -j&amp;quot;$(nproc)&amp;quot;&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Check CUDA offload works:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./build/bin/llama-cli --help | grep -i gpu&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## Run GPT-OSS 20B&lt;br /&gt;
&lt;br /&gt;
Example using llama.cpp’s Hugging Face download support:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./build/bin/llama-server \&lt;br /&gt;
  -hf ggml-org/gpt-oss-20b-GGUF \&lt;br /&gt;
  -ngl 999 \&lt;br /&gt;
  -c 8192 \&lt;br /&gt;
  --host 0.0.0.0 \&lt;br /&gt;
  --port 8080&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Then test OpenAI-compatible API:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
curl http://127.0.0.1:8080/v1/chat/completions \&lt;br /&gt;
  -H 'Content-Type: application/json' \&lt;br /&gt;
  -d '{&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;gpt-oss-20b&amp;quot;,&lt;br /&gt;
    &amp;quot;messages&amp;quot;: [&lt;br /&gt;
      {&amp;quot;role&amp;quot;: &amp;quot;user&amp;quot;, &amp;quot;content&amp;quot;: &amp;quot;Write a small Go HTTP server with health check.&amp;quot;}&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;temperature&amp;quot;: 0.2&lt;br /&gt;
  }'&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
If VRAM gets tight, reduce context:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
-c 4096&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Or reduce GPU layers:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
-ngl 60&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
But on a 24 GB P40, for many 20B-ish quantized GGUFs, this should be okay.&lt;br /&gt;
&lt;br /&gt;
## Run a Qwen coder model&lt;br /&gt;
&lt;br /&gt;
For coding, Qwen is probably where I would spend most of my time. Example:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./build/bin/llama-server \&lt;br /&gt;
  -hf unsloth/Qwen3-Coder-Next-GGUF \&lt;br /&gt;
  -ngl 999 \&lt;br /&gt;
  -c 8192 \&lt;br /&gt;
  --host 0.0.0.0 \&lt;br /&gt;
  --port 8080&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
The Unsloth Qwen GGUF page notes recent llama.cpp fixes for Qwen output/tool-calling behavior, so use a fresh llama.cpp build rather than an old distro package. ([Hugging Face][3])&lt;br /&gt;
&lt;br /&gt;
## Should you use Ollama instead?&lt;br /&gt;
&lt;br /&gt;
Ollama is easier, but `llama.cpp` gives you more direct control.&lt;br /&gt;
&lt;br /&gt;
Use **Ollama** if you want simple:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
ollama run hf.co/ggml-org/gpt-oss-20b-GGUF&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Use **llama.cpp directly** if you care about:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
GPU layer tuning&lt;br /&gt;
context size tuning&lt;br /&gt;
exact GGUF file selection&lt;br /&gt;
server flags&lt;br /&gt;
benchmarking&lt;br /&gt;
performance debugging&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Given how you work, I’d use **llama.cpp directly** first.&lt;br /&gt;
&lt;br /&gt;
## Should you use vLLM?&lt;br /&gt;
&lt;br /&gt;
For your **P40**, probably no — not as your first runtime.&lt;br /&gt;
&lt;br /&gt;
vLLM is excellent for newer GPUs and serving many users, but it tends to assume newer CUDA paths and benefits heavily from Tensor Cores / modern attention kernels. On Pascal P40, `llama.cpp` is usually simpler and more forgiving.&lt;br /&gt;
&lt;br /&gt;
I would use vLLM when you have something like:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
RTX 3090&lt;br /&gt;
RTX 4090&lt;br /&gt;
RTX PRO 4500 Blackwell&lt;br /&gt;
A10/A40/A100/H100/L40S&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
For the P40:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
llama.cpp &amp;gt; Ollama &amp;gt; exllamav2/vLLM experiments&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
## My practical recommendation&lt;br /&gt;
&lt;br /&gt;
Start with:&lt;br /&gt;
&lt;br /&gt;
```text&lt;br /&gt;
Runtime: llama.cpp&lt;br /&gt;
Driver: 580-server&lt;br /&gt;
Model format: GGUF&lt;br /&gt;
First model: gpt-oss-20b-GGUF&lt;br /&gt;
Coding model: Qwen coder GGUF&lt;br /&gt;
Context: 4096 or 8192 first&lt;br /&gt;
GPU layers: -ngl 999&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Then benchmark:&lt;br /&gt;
&lt;br /&gt;
```bash&lt;br /&gt;
./build/bin/llama-bench -m /path/to/model.gguf -ngl 999&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
For a single Tesla P40, **don’t chase the newest serving framework**. Use stable `580-server`, fresh `llama.cpp`, and GGUF models. That will give you the fewest headaches and the best compatibility.&lt;br /&gt;
&lt;br /&gt;
[1]: https://huggingface.co/ggml-org/gpt-oss-20b-GGUF?utm_source=chatgpt.com &amp;quot;ggml-org/gpt-oss-20b-GGUF&amp;quot;&lt;br /&gt;
[2]: https://qwen.readthedocs.io/en/latest/run_locally/llama.cpp.html?utm_source=chatgpt.com &amp;quot;llama.cpp - Qwen - Read the Docs&amp;quot;&lt;br /&gt;
[3]: https://huggingface.co/unsloth/Qwen3-Coder-Next-GGUF?utm_source=chatgpt.com &amp;quot;unsloth/Qwen3-Coder-Next-GGUF&amp;quot;&lt;/div&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
</feed>