
[{"content":"","date":"5 May 2026","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","date":"5 May 2026","externalUrl":null,"permalink":"/tags/hetzner/","section":"Tags","summary":"","title":"Hetzner","type":"tags"},{"content":"","date":"5 May 2026","externalUrl":null,"permalink":"/categories/infrastructure/","section":"Categories","summary":"","title":"Infrastructure","type":"categories"},{"content":"","date":"5 May 2026","externalUrl":null,"permalink":"/","section":"Melih Savdert's Tech Blog","summary":"","title":"Melih Savdert's Tech Blog","type":"page"},{"content":"","date":"5 May 2026","externalUrl":null,"permalink":"/posts/","section":"Posts","summary":"","title":"Posts","type":"posts"},{"content":"","date":"5 May 2026","externalUrl":null,"permalink":"/tags/proxmox/","section":"Tags","summary":"","title":"Proxmox","type":"tags"},{"content":"Deploying Proxmox VE on a Hetzner dedicated bare metal server with a single public IP can be challenging because Hetzner does not provide standard IPMI/KVM access out of the box unless requested.\nIn this guide, we will walk through the step-by-step process of downloading Proxmox VE 9.x, installing it via QEMU inside the Hetzner Rescue System using a ZFS RAID0 layout for maximum performance across two disks, configuring native SDN-based NAT, and setting up Tailscale for secure remote management.\n1. Booting into Hetzner Rescue System and Downloading the ISO # First, navigate to your Hetzner Robot Panel, activate the Rescue System (Linux, 64-bit), and reboot your server. Once logged into the rescue environment via SSH, fetch and download the latest Proxmox VE 9.x ISO:\n# Fetch the latest ISO version name ISO_VERSION=$(curl -s \u0026#39;http://download.proxmox.com/iso/\u0026#39; | grep -oP \u0026#39;proxmox-ve_(\\d+.\\d+-\\d).iso\u0026#39; | sort -V | tail -n1) ISO_URL=\u0026#34;http://download.proxmox.com/iso/$ISO_VERSION\u0026#34; # Download the ISO to the temp folder curl $ISO_URL -o /tmp/proxmox-ve.iso echo \u0026#34;Downloaded ISO version: $ISO_VERSION\u0026#34; # Example output: proxmox-ve_9.1-1.iso 2. Acquiring Network Details from the Host # Before booting the virtual machine to start the installation, gather your main server network configuration details. We will need these parameters during the graphical setup:\n# Determine interface name, IP, gateway and subnet INTERFACE_NAME=$(udevadm info -q property /sys/class/net/eth0 | grep \u0026#34;ID_NET_NAME_PATH=\u0026#34; | cut -d\u0026#39;=\u0026#39; -f2) IP_CIDR=$(ip addr show eth0 | grep \u0026#34;inet\\b\u0026#34; | awk \u0026#39;{print $2}\u0026#39;) GATEWAY=$(ip route | grep default | awk \u0026#39;{print $3}\u0026#39;) IP_ADDRESS=$(echo \u0026#34;$IP_CIDR\u0026#34; | cut -d\u0026#39;/\u0026#39; -f1) CIDR=$(echo \u0026#34;$IP_CIDR\u0026#34; | cut -d\u0026#39;/\u0026#39; -f2) # Print values to write them down echo \u0026#34;Interface: $INTERFACE_NAME\u0026#34; # e.g. enp0s31f6 echo \u0026#34;IP/CIDR: $IP_CIDR\u0026#34; # e.g. 192.0.2.113/26 echo \u0026#34;Gateway: $GATEWAY\u0026#34; # e.g. 192.0.2.65 echo \u0026#34;IP: $IP_ADDRESS\u0026#34; # e.g. 192.0.2.113 echo \u0026#34;CIDR: $CIDR\u0026#34; # e.g. 26 3. Initiating QEMU for Proxmox GUI Installation # Since we cannot boot the bare metal server directly into the Proxmox installer ISO, we will start a temporary virtual machine using QEMU. This VM will map the host\u0026rsquo;s actual physical drives (/dev/sda, /dev/sdb etc.) to the VM\u0026rsquo;s disk slots.\nPreparing UEFI Packages \u0026amp; Launching QEMU # Install OVMF for UEFI support, identify your primary and secondary disks, and spin up QEMU:\napt-get install -y ovmf # Identify primary and secondary disks (filtering out loop/ram devices) PRIMARY_DISK=$(lsblk -dn -o NAME,SIZE,TYPE -e 1,7,11,14,15 | sed -n 1p | awk \u0026#39;{print $1}\u0026#39;) SECONDARY_DISK=$(lsblk -dn -o NAME,SIZE,TYPE -e 1,7,11,14,15 | sed -n 2p | awk \u0026#39;{print $1}\u0026#39;) # Launch QEMU mapping both drives and the ISO qemu-system-x86_64 -daemonize -enable-kvm -m 10240 -k en-us \\ -drive file=/dev/$PRIMARY_DISK,format=raw,media=disk,if=virtio,id=$PRIMARY_DISK \\ -drive file=/dev/$SECONDARY_DISK,format=raw,media=disk,if=virtio,id=$SECONDARY_DISK \\ -drive file=/usr/share/OVMF/OVMF_CODE.fd,if=pflash,format=raw,readonly=on \\ -drive file=/usr/share/OVMF/OVMF_VARS.fd,if=pflash,format=raw \\ -cdrom /tmp/proxmox-ve.iso -boot d \\ -vnc :0,password=on -monitor telnet:127.0.0.1:4444,server,nowait # Set a secure VNC password to protect your installer session echo \u0026#34;change vnc password YOUR_SECURE_VNC_PASSWORD\u0026#34; | nc -q 1 127.0.0.1 4444 Accessing the Installer GUI # Open your VNC client (on macOS, press CMD+K in Finder) and connect using your server\u0026rsquo;s public IP:\nvnc://192.0.2.113:5900 Enter the VNC password you set above (YOUR_SECURE_VNC_PASSWORD) to access the graphical installation wizard.\n4. Walking Through the GUI Installer # Select Install Proxmox VE (Graphical). Note: A warning regarding missing hardware virtualization support is safe to ignore; it occurs because we are inside QEMU. Click Agree to the license agreement. Under Target Harddisk, open Options: Change filesystem to zfs (RAID0) to stripe across both disks for maximum performance. Click OK. Configure system parameters: Country: United States (or your choice) Time zone: UTC Password: Enter a secure password (e.g. YOUR_SECURE_ROOT_PASSWORD) Email: your-email@example.com Configure management network settings. Enter the values you extracted from the host in Section 2: Management Interface: Select the virtio interface. Hostname: pve.lan IP Address: 192.0.2.113/26 (Use your actual IP and CIDR) Gateway: 192.0.2.65 DNS Server: 1.1.1.1 (or 8.8.8.8) Important: Untick the \u0026ldquo;Automatically reboot after successful installation\u0026rdquo; box. Click Install. 5. Post-Install Network Configuration (Within Rescue) # Once the installer finishes, do not reboot the server yet. Go back to your SSH session and stop QEMU:\n# Gracefully stop the installer VM printf \u0026#34;quit\\n\u0026#34; | nc 127.0.0.1 4444 Now, launch QEMU again, but this time boot from the newly installed Proxmox OS on the virtual disk rather than the ISO, mapping port 22 in the VM to port 2222 on the host:\n# Spin up QEMU booting from the virtual disk with port forwarding qemu-system-x86_64 -daemonize -enable-kvm -m 10240 -k en-us \\ -drive file=/dev/$PRIMARY_DISK,format=raw,media=disk,if=virtio,id=$PRIMARY_DISK \\ -drive file=/dev/$SECONDARY_DISK,format=raw,media=disk,if=virtio,id=$SECONDARY_DISK \\ -drive file=/usr/share/OVMF/OVMF_CODE.fd,if=pflash,format=raw,readonly=on \\ -drive file=/usr/share/OVMF/OVMF_VARS.fd,if=pflash,format=raw \\ -vnc :0,password=on -monitor telnet:127.0.0.1:4444,server,nowait \\ -net user,hostfwd=tcp::2222-:22 -net nic # Set the VNC password echo \u0026#34;change vnc password YOUR_SECURE_VNC_PASSWORD\u0026#34; | nc -q 1 127.0.0.1 4444 Wait about a minute for Proxmox to boot inside the VM. On your host SSH terminal, install sshpass to easily copy configuration files into the virtual Proxmox host:\napt-get -y install sshpass Write a proper bare metal network configuration file. Since Proxmox was installed inside QEMU, its network interface settings point to virtual devices. We need to restore the physical interface configuration so it can communicate on bare metal:\ncat \u0026gt; /tmp/proxmox_network_config \u0026lt;\u0026lt; EOF auto lo iface lo inet loopback iface $INTERFACE_NAME inet manual auto vmbr0 iface vmbr0 inet static address $IP_ADDRESS/$CIDR gateway $GATEWAY bridge_ports $INTERFACE_NAME bridge_stp off bridge_fd 0 EOF # Copy the bare metal config file to the virtual Proxmox system sshpass -p \u0026#34;YOUR_SECURE_ROOT_PASSWORD\u0026#34; scp -o StrictHostKeyChecking=no -P 2222 /tmp/proxmox_network_config root@localhost:/etc/network/interfaces # Update nameserver inside Proxmox sshpass -p \u0026#34;YOUR_SECURE_ROOT_PASSWORD\u0026#34; ssh -o StrictHostKeyChecking=no -p 2222 root@localhost \u0026#34;sed -i \u0026#39;s/nameserver.*/nameserver 1.1.1.1/\u0026#39; /etc/resolv.conf\u0026#34; Once the network config is successfully updated, shutdown the QEMU VM:\nprintf \u0026#34;system_powerdown\\n\u0026#34; | nc 127.0.0.1 4444 After the VM process exits, restart your Hetzner server to exit the Rescue System and boot into your fresh Proxmox bare metal hypervisor:\n# Reboot host shutdown -r now 6. Configuring Proxmox on Bare Metal # Once the host reboots, access the Proxmox Web GUI in your browser at https://192.0.2.113:8006/ using root credentials.\nRunning Helper Optimization Scripts # Open the Host Shell from the GUI and run the community post-installation script to clean up repositories, disable subscription warnings, and update package sources:\nbash -c \u0026#34;$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/pve/post-pve-install.sh)\u0026#34; Disabling the pve-enterprise repository: Yes (unless you have a subscription license). Correcting ceph package sources: Yes. Enabling the pve-no-subscription repository: Yes. Disabling the subscription nag popup: Yes. Updating packages and upgrading: Yes. 7. Creating an SDN NAT Zone and DHCP Range # Hetzner bonds public IPs to MAC addresses. To avoid paying for extra public IPs, we will configure Software-Defined Networking (SDN) to run VMs behind a NAT bridge.\nEnabling IP Forwarding (Kernel-level) # Execute the following commands in the host shell to allow the system to route traffic:\ncat \u0026lt;\u0026lt; EOF \u0026gt; /etc/sysctl.d/99-ip-forwarding.conf net.ipv4.ip_forward = 1 net.ipv6.conf.all.forwarding = 1 EOF # Apply the kernel configurations sysctl -p /etc/sysctl.d/99-ip-forwarding.conf Install the SDN controller dependencies:\napt update \u0026amp;\u0026amp; apt install -y dnsmasq systemctl disable --now dnsmasq # Proxmox will control it Ensure your /etc/network/interfaces references the SDN configuration:\ngrep \u0026#39;interfaces.d\u0026#39; /etc/network/interfaces || echo \u0026#34;source /etc/network/interfaces.d/*\u0026#34; \u0026gt;\u0026gt; /etc/network/interfaces Configuring SDN via Web UI # Create the SDN Zone: Go to Datacenter \u0026gt; SDN \u0026gt; Zones \u0026gt; Add \u0026gt; Simple. ID: localnat IPAM: pve Advanced: Check automatic DHCP. Create the VNet: Go to Datacenter \u0026gt; SDN \u0026gt; VNets \u0026gt; Add. Name: vnet0 Zone: localnat Configure Subnet and SNAT: Click on your newly created vnet0 and click Create under the Subnets panel. Subnet: 10.0.0.0/24 Gateway: 10.0.0.1 SNAT: Check this box (crucial for internet access). Under the DHCP Ranges tab, define the pool: Start Address: 10.0.0.100 End Address: 10.0.0.200 Apply Settings: Go back to the Datacenter \u0026gt; SDN page and click Apply at the top. Now when you launch a VM or Container, choose vnet0 as the bridge interface and set its network configuration to DHCP. It will automatically receive an IP in the 10.0.0.x range and route to the internet.\n8. Automating Proxmox with API Tokens # Instead of using the root credentials in Terraform, OpenTofu, or scripts, create a scoped API User:\n# Add a new admin user pveum user add admin@pve --comment \u0026#34;Automation Admin User\u0026#34; # Grant administrative role on the entire cluster path (/) pveum acl modify / --user admin@pve --role Administrator # Generate an API Token pveum user token add admin@pve mytoken --privsep 0 You can test authenticating with the token using curl:\ncurl -k -H \u0026#39;Authorization: PVEAPIToken=admin@pve!mytoken=YOUR_API_TOKEN_VALUE\u0026#39; \\ https://100.64.0.10:8006/api2/json/nodes 9. Setting Up Tailscale VPN for Out-of-Band Access # To access your Proxmox dashboard without exposing public ports, configure Tailscale as a secure gateway:\n# Download and install Tailscale curl -fsSL https://tailscale.com/install.sh | sh # Spin up Tailscale and advertise the private SDN NAT subnet tailscale up --advertise-routes=10.0.0.0/24 Optimizing Network Performance (UDP GRO forwarding) # Tailscale might warning you about suboptimal UDP configurations. Add persistent performance tuning to your interfaces:\n# Apply dynamically ethtool -K vmbr0 rx-udp-gro-forwarding on rx-gro-list off To make it permanent, modify /etc/network/interfaces and add the post-up hook:\nauto vmbr0 iface vmbr0 inet static # ... your existing ip address configs ... post-up /usr/sbin/ethtool -K vmbr0 rx-udp-gro-forwarding on rx-gro-list off Finally, go to your Tailscale Admin Console, click Machines, select your Proxmox host, click Edit route settings, and enable the 10.0.0.0/24 subnet route.\nHealth check warning: If you see the warning: \u0026ldquo;Some peers are advertising routes but \u0026ndash;accept-routes is false\u0026rdquo;, you can resolve it by running:\nsudo tailscale up --accept-routes References # Install Proxmox on a Hetzner Dedicated Server using SDN - CyanLabs Proxmox VE Software-Defined Network Documentation ","date":"5 May 2026","externalUrl":null,"permalink":"/posts/proxmox-9-hetzner-zfs-guide/","section":"Posts","summary":"Deploying Proxmox VE on a Hetzner dedicated bare metal server with a single public IP can be challenging because Hetzner does not provide standard IPMI/KVM access out of the box unless requested.\nIn this guide, we will walk through the step-by-step process of downloading Proxmox VE 9.x, installing it via QEMU inside the Hetzner Rescue System using a ZFS RAID0 layout for maximum performance across two disks, configuring native SDN-based NAT, and setting up Tailscale for secure remote management.\n","title":"Proxmox VE 9.x Installation on Hetzner: A Complete ZFS Setup Guide","type":"posts"},{"content":"","date":"5 May 2026","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"","date":"5 May 2026","externalUrl":null,"permalink":"/tags/zfs/","section":"Tags","summary":"","title":"Zfs","type":"tags"},{"content":"","date":"27 April 2026","externalUrl":null,"permalink":"/tags/cloudflare/","section":"Tags","summary":"","title":"Cloudflare","type":"tags"},{"content":"In my previous post, we set up Proxmox VE on a Hetzner dedicated server. While the installation is complete, accessing the Proxmox dashboard usually involves opening port 8006 to the public internet or using a VPN. A more modern and secure approach is to use Cloudflare Tunnels (Cloudflared). This allows you to access your dashboard via a nice hostname (e.g., proxmox.yourdomain.com) without opening any inbound ports on your server.\nWhy Cloudflare Tunnels? # No Inbound Ports: You can keep your firewall completely closed to the public internet. Identity-Based Access: You can add Cloudflare Access rules (SSO, 2FA) in front of your Proxmox login. Automated SSL: Cloudflare handles the SSL/TLS certificates automatically. 1. Prerequisites # A Proxmox VE server (see the installation guide). A domain managed by Cloudflare. A Cloudflare Zero Trust account (Free tier is fine). 2. Setting Up the Tunnel in Cloudflare Dashboard # Log in to the Cloudflare Dashboard. Navigate to Zero Trust \u0026gt; Networks \u0026gt; Tunnels. Click Create a tunnel and name it (e.g., proxmox-hetzner). Select Cloudflared as the connector. Choose your environment (e.g., Debian 64-bit). 3. Installing Cloudflared on Proxmox # Back in your Proxmox terminal, follow these steps to install the agent:\nAdd Cloudflare Repository # sudo mkdir -p --mode=0755 /usr/share/keyrings curl -fsSL https://pkg.cloudflare.com/cloudflare-public-v2.gpg | sudo tee /usr/share/keyrings/cloudflare-public-v2.gpg \u0026gt;/dev/null echo \u0026#39;deb [signed-by=/usr/share/keyrings/cloudflare-public-v2.gpg] https://pkg.cloudflare.com/cloudflared any main\u0026#39; | sudo tee /etc/apt/sources.list.d/cloudflared.list sudo apt-get update \u0026amp;\u0026amp; sudo apt-get install cloudflared Install the Service # Cloudflare will provide you with a command containing a unique token. Run it on your server:\nsudo cloudflared service install \u0026lt;YOUR_TUNNEL_TOKEN\u0026gt; Enable and start the service:\nsystemctl enable cloudflared systemctl start cloudflared 4. Configuring Public Hostnames # In the Cloudflare Dashboard, under your tunnel configuration:\nGo to the Public Hostname tab. Click Add a public hostname. Fill in the details: Subdomain: proxmox Domain: yourdomain.com Service Type: HTTPS URL: localhost:8006 Important: Since Proxmox uses a self-signed certificate by default, go to Additional application settings \u0026gt; HTTP Settings and enable No TLS Verify. 5. Fixing QUIC Handshake Timeouts # If you are using the Hetzner Firewall, you might encounter QUIC handshake timeout errors because Cloudflare Tunnel uses UDP for its high-performance transport.\nTo fix this, go to your Hetzner Robot Panel and add a firewall rule:\nName: Cloudflare QUIC Protocol: UDP Source Port: 0-65535 Destination Port: 32768-65535 Action: Accept Apply and save the rules.\n6. Verification # Restart the service and check the status:\nsystemctl restart cloudflared systemctl status cloudflared You should now be able to access your Proxmox GUI at https://proxmox.yourdomain.com.\nNext Steps # Now that your dashboard is secure, I highly recommend setting up Cloudflare Access policies to restrict access only to your email address or specific IP ranges. This adds a powerful layer of security before someone even sees the Proxmox login screen.\nIf you missed the initial server setup, check out the Hetzner Proxmox Deployment Guide.\nReferences # Resolved: Connection Issues with Cloudflared due to Ingress UDP Traffic - SSE and Zero trust / Cloudflare Tunnel - Cloudflare Community Troubleshooting · Cloudflare Docs ","date":"27 April 2026","externalUrl":null,"permalink":"/posts/securing-proxmox-with-cloudflare-tunnel/","section":"Posts","summary":"In my previous post, we set up Proxmox VE on a Hetzner dedicated server. While the installation is complete, accessing the Proxmox dashboard usually involves opening port 8006 to the public internet or using a VPN. A more modern and secure approach is to use Cloudflare Tunnels (Cloudflared). This allows you to access your dashboard via a nice hostname (e.g., proxmox.yourdomain.com) without opening any inbound ports on your server.\nWhy Cloudflare Tunnels? # No Inbound Ports: You can keep your firewall completely closed to the public internet. Identity-Based Access: You can add Cloudflare Access rules (SSO, 2FA) in front of your Proxmox login. Automated SSL: Cloudflare handles the SSL/TLS certificates automatically. 1. Prerequisites # A Proxmox VE server (see the installation guide). A domain managed by Cloudflare. A Cloudflare Zero Trust account (Free tier is fine). 2. Setting Up the Tunnel in Cloudflare Dashboard # Log in to the Cloudflare Dashboard. Navigate to Zero Trust \u003e Networks \u003e Tunnels. Click Create a tunnel and name it (e.g., proxmox-hetzner). Select Cloudflared as the connector. Choose your environment (e.g., Debian 64-bit). 3. Installing Cloudflared on Proxmox # Back in your Proxmox terminal, follow these steps to install the agent:\n","title":"Securing Proxmox VE with Cloudflare Tunnel: A Zero Trust Approach","type":"posts"},{"content":"Deploying Proxmox VE on a Hetzner Dedicated Server can be a bit tricky due to Hetzner\u0026rsquo;s specific network security policies. In this guide, we will walk through the process of installing Proxmox VE on a fresh Debian 13 (Trixie) installation and configuring a modern, scalable networking stack using Software-Defined Networking (SDN).\nIf you are looking to expose your Proxmox dashboard securely without opening ports, check out my follow-up guide: Securing Proxmox VE with Cloudflare Tunnel.\n1. Initial Installation via Hetzner Rescue System # First, we need to boot into the Hetzner Rescue System to install a clean Debian base.\nGo to the Hetzner Robot panel. Select your server -\u0026gt; Rescue tab. Select Linux as the operating system and activate the rescue system. Note down the temporary root password and reboot the server. Connect via SSH:\nssh root@\u0026lt;SERVER_IP\u0026gt; Run the installimage script:\ninstallimage Choose Debian 13 (Trixie). You can leave most settings as default, but ensure your disk layout (RAID/LVM) matches your needs. After the installation completes, reboot the server.\n2. Installing Proxmox VE # Once logged back into the fresh Debian system, we need to add the Proxmox repositories.\nRepository Configuration # Create the source list for Proxmox VE:\ncat \u0026gt; /etc/apt/sources.list.d/pve-install-repo.sources \u0026lt;\u0026lt; EOL Types: deb URIs: http://download.proxmox.com/debian/pve Suites: trixie Components: pve-no-subscription Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpg EOL wget https://enterprise.proxmox.com/debian/proxmox-archive-keyring-trixie.gpg -O /usr/share/keyrings/proxmox-archive-keyring.gpg System Upgrade \u0026amp; Kernel Installation # Update the system and install the Proxmox kernel:\napt update \u0026amp;\u0026amp; apt full-upgrade apt install proxmox-default-kernel systemctl reboot Core Packages # After rebooting into the Proxmox kernel, install the VE environment:\napt install proxmox-ve postfix open-iscsi chrony apt remove linux-image-amd64 \u0026#39;linux-image-6.12*\u0026#39; update-grub apt update \u0026amp;\u0026amp; apt full-upgrade passwd root You can now access the Proxmox Web GUI at https://\u0026lt;SERVER_IP\u0026gt;:8006/.\n3. Network Configuration: The Modern Way # Hetnzer enforces strict IP/MAC binding. If you have only one Public IP, you cannot use a standard Bridged setup for your VMs without purchasing additional IPs and MAC addresses. Instead, we will use Masquerading (NAT) with the new Software-Defined Network (SDN) feature in Proxmox. This allows your VMs to sit behind the host\u0026rsquo;s IP, which is both cost-effective and secure.\nEnable IP Forwarding # The host must act as a router for the VMs:\ncat \u0026lt;\u0026lt; EOF \u0026gt; /etc/sysctl.d/ip-forwarding.conf net.ipv4.ip_forward = 1 net.ipv6.conf.all.forwarding = 1 EOF systemctl restart systemd-sysctl Install SDN Dependencies # The Software-Defined Network (SDN) feature in Proxmox VE enables the creation of virtual zones and networks (VNets). This functionality simplifies advanced networking configurations and multitenancy setup.\napt update \u0026amp;\u0026amp; apt install -y libpve-network-perl dnsmasq systemctl disable --now dnsmasq # Proxmox manages this Ensure your /etc/network/interfaces includes the interfaces.d directory:\ngrep \u0026#39;interfaces.d\u0026#39; /etc/network/interfaces || echo \u0026#34;source /etc/network/interfaces.d/*\u0026#34; \u0026gt;\u0026gt; /etc/network/interfaces Configure SDN in Proxmox GUI # Create a Zone: Datacenter \u0026gt; SDN \u0026gt; Zones \u0026gt; Add \u0026gt; Simple. ID: hnat IPAM: pve Advanced: Check automatic DHCP. Create a VNet: Datacenter \u0026gt; SDN \u0026gt; VNets \u0026gt; Add. Name: vnet1 Zone: hnat Add a Subnet: Click on vnet1 and create a new Subnet. Subnet: 10.0.0.0/24 Gateway: 10.0.0.1 DHCP Ranges: 10.0.0.100 - 10.0.0.200 SNAT: Check this (CRITICAL for internet access). Apply: Go back to the SDN section and click Apply. Now, when you create a VM or Container, select vnet1 as the bridge and set IPv4 to DHCP.\n4. Post-Installation Hardening # Fail2Ban # Protect your SSH service from brute-force attacks:\napt update \u0026amp;\u0026amp; apt install fail2ban -y cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local Edit /etc/fail2ban/jail.local and ensure [sshd] is enabled:\n[sshd] enabled = true Restart the service:\nsystemctl restart fail2ban Hetzner Firewall # In the Hetzner Robot Panel, go to Firewall and apply the SSH template. This ensures that only essential ports are open at the edge.\nProxmox Helper Scripts # For quick optimizations, use the excellent community scripts:\nbash -c \u0026#34;$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/pve/post-pve-install.sh)\u0026#34; Conclusion # You now have a fully functional Proxmox VE node running on Hetzner with a modern SDN-based NAT network. This setup is flexible, secure, and doesn\u0026rsquo;t require additional IP costs.\nIn the next post, we\u0026rsquo;ll look at how to securely access this dashboard using Cloudflare Tunnels.\nReferences # Install Proxmox VE on Debian 13 Trixie - Proxmox VE Install and Configure Proxmox VE|Hetzner Community Install Proxmox on a Hetzner Dedicated Server with 1 IP using SDN and without KVM using QEMU - CyanLabs ","date":"26 April 2026","externalUrl":null,"permalink":"/posts/proxmox-hetzner-deployment-guide/","section":"Posts","summary":"Deploying Proxmox VE on a Hetzner Dedicated Server can be a bit tricky due to Hetzner’s specific network security policies. In this guide, we will walk through the process of installing Proxmox VE on a fresh Debian 13 (Trixie) installation and configuring a modern, scalable networking stack using Software-Defined Networking (SDN).\nIf you are looking to expose your Proxmox dashboard securely without opening ports, check out my follow-up guide: Securing Proxmox VE with Cloudflare Tunnel.\n","title":"Proxmox VE on Hetzner Bare Metal: The Complete Deployment Guide","type":"posts"},{"content":"","date":"16 April 2026","externalUrl":null,"permalink":"/tags/automation/","section":"Tags","summary":"","title":"Automation","type":"tags"},{"content":"Managing my developer environment across multiple machines (macOS, Ubuntu, Oracle Linux, and minimal Docker containers) has always been a challenge. Most dotfiles setups I\u0026rsquo;ve seen rely on brittle helper scripts, global sudo installations, or manual token handling.\nI decided to fix this by building a fully native, no-sudo, and secure dotfiles infrastructure from the ground up. Here’s how I modernized my workflow and why it’s a game-changer for my daily productivity.\n1. The \u0026ldquo;No-Sudo\u0026rdquo; Philosophy # One of the rigid constraints I set for this project was zero root requirements. Whether I am on a locked-down production server or a shared development container, I want my environment to move with me without asking for permission.\nEverything—from the editor to the terminal multiplexer—is installed as a standalone binary in ~/.local/bin. By leveraging user-space installations, I’ve achieved a level of portability where a single curl | bash command can hydrate my entire stack in seconds, regardless of the distribution.\n2. Secrets Management with 1Password (Native Integration) # The biggest security hole in most dotfiles is the way they handle API tokens and SSH keys. Storing them in plain-text .bash_local or pushing them to private repos is a risk I wasn\u0026rsquo;t willing to take.\nMy new setup uses the 1Password CLI (op) natively. Using 1Password Service Accounts, my secrets are fetched only when needed via secure references (op://dotfiles/github/token). This \u0026ldquo;Hybrid Secret Hydration\u0026rdquo; allows me to keep my environment variables local and git-ignored, while maintaining a single source of truth in a secure vault.\n3. The Modern Terminal Stack # I’ve moved away from standard, heavy frameworks. My new lean stack focuses on high-performance, modern CLI tools:\nZellij: A modern terminal multiplexer that feels interactive and alive. Neovim (NvChad inspired): A blazingly fast development experience without the bloat. uv: The \u0026ldquo;Swiss Army Knife\u0026rdquo; of the project. It handles standalone Python management and zip extractions in minimal environments where unzip or python are absent. GitHub CLI (gh): Fully integrated for a native Git experience. 4. Engineering Quality: The 8-Distro CI Matrix # A project is only as good as its reliability. To prove that these dotfiles are truly \u0026ldquo;Bulletproof,\u0026rdquo; I implemented a GitHub Actions matrix that tests the entire bootstrap process on:\nmacOS (14 \u0026amp; 15) Ubuntu (22.04 \u0026amp; 24.04 LTS) Oracle Linux (9 \u0026amp; 10) Debian (11 \u0026amp; 12) Every time I push a change, it is automatically verified across all these environments for idempotency and binary stability. If it passes CI, I know it will work on any machine I touch.\n5. Conclusion # Dotfiles are more than just configurations; they are our digital workspace. By transitioning to a native, no-sudo, and secure-first approach, I’ve gained a workspace that is not only fast but also incredibly resilient.\nCheck out the full repository here: msavdert/dotfiles\nHappy Hacking!\n","date":"16 April 2026","externalUrl":null,"permalink":"/posts/no-sudo-modern-dotfiles/","section":"Posts","summary":"Managing my developer environment across multiple machines (macOS, Ubuntu, Oracle Linux, and minimal Docker containers) has always been a challenge. Most dotfiles setups I’ve seen rely on brittle helper scripts, global sudo installations, or manual token handling.\nI decided to fix this by building a fully native, no-sudo, and secure dotfiles infrastructure from the ground up. Here’s how I modernized my workflow and why it’s a game-changer for my daily productivity.\n","title":"Building the Ultimate 'No-Sudo' Modern Dotfiles: A Native \u0026 Secure Approach","type":"posts"},{"content":"","date":"16 April 2026","externalUrl":null,"permalink":"/categories/devops/","section":"Categories","summary":"","title":"DevOps","type":"categories"},{"content":"","date":"16 April 2026","externalUrl":null,"permalink":"/tags/dotfiles/","section":"Tags","summary":"","title":"Dotfiles","type":"tags"},{"content":"","date":"9 April 2026","externalUrl":null,"permalink":"/categories/career/","section":"Categories","summary":"","title":"Career","type":"categories"},{"content":"I am in the middle of a career shift.\nFor years, I worked close to legacy database systems. That experience taught me how to think carefully, solve production problems, and respect reliability.\nNow I am moving toward platform engineering.\nTo make that shift visible and real, I started a public GitHub repository:\nlegacy-dba-to-platform-engineer\nThis repository is my working log. I will use it to document what I learn, what I build, and how my thinking changes over time.\nThe goal is simple:\nshare the transition openly create a clear record of progress connect my database background with modern platform work I want this repo to be useful not only for me, but also for anyone making a similar move.\nIf you are interested in databases, infrastructure, automation, or platform engineering, you can follow the journey there.\n","date":"9 April 2026","externalUrl":null,"permalink":"/posts/shift-to-platform-engineering/","section":"Posts","summary":"I am in the middle of a career shift.\nFor years, I worked close to legacy database systems. That experience taught me how to think carefully, solve production problems, and respect reliability.\nNow I am moving toward platform engineering.\nTo make that shift visible and real, I started a public GitHub repository:\nlegacy-dba-to-platform-engineer\nThis repository is my working log. I will use it to document what I learn, what I build, and how my thinking changes over time.\n","title":"Documenting My Shift to Platform Engineering","type":"posts"},{"content":"","date":"9 April 2026","externalUrl":null,"permalink":"/tags/platform-engineering/","section":"Tags","summary":"","title":"Platform-Engineering","type":"tags"},{"content":"","date":"27 February 2026","externalUrl":null,"permalink":"/tags/github-pages/","section":"Tags","summary":"","title":"Github-Pages","type":"tags"},{"content":"This guide provides the official, recommended steps to configure a custom subdomain (e.g., blog.savdert.com) for GitHub Pages using Cloudflare as your DNS provider, based on GitHub\u0026rsquo;s official documentation.\n1. Configure GitHub Pages # First, you need to tell your GitHub repository that you intend to use a custom domain.\nNavigate to your GitHub repository.\nGo to Settings \u0026gt; Pages (under the \u0026ldquo;Code and automation\u0026rdquo; section).\nUnder Custom domain, type your subdomain (e.g., blog.savdert.com).\nClick Save.\nNote: This will automatically create a commit adding a CNAME file to the root of your repository. 2. Configure Cloudflare DNS (CNAME Record) # For a subdomain (like blog.savdert.com), GitHub requires a CNAME record, not A records.\nGo to your Cloudflare Dashboard and navigate to DNS \u0026gt; Records.\nAdd a new record with the following details:\nType: CNAME Name: blog (the subdomain part) and www.blog Target: msavdert.github.io (your GitHub Pages default domain) Proxy status: ☁️ DNS Only (Grey cloud) Important: Leave it as \u0026ldquo;DNS Only\u0026rdquo; initially so GitHub can successfully provision an SSL certificate. You can turn on the orange cloud (Proxied) later if you want Cloudflare\u0026rsquo;s features. GitHub strongly recommends never using wildcard DNS records (e.g., *.savdert.com), as they put you at immediate risk of domain takeovers. 3. Verify Your Custom Domain (Highly Recommended) # Verifying your domain at the account level prevents other GitHub users from taking over your custom domain if you ever delete your repository or remove the custom domain from your repository settings.\nIn the upper-right corner of GitHub, click your profile picture and go to Settings.\nIn the sidebar under \u0026ldquo;Code, planning, and automation\u0026rdquo;, click Pages.\nClick Add a domain.\nEnter blog.savdert.com and click Add domain.\nGitHub will provide a DNS TXT record to add (e.g., _github-pages-challenge-msavdert).\nGo back to Cloudflare DNS and add the TXT record:\nType: TXT Name: _github-pages-challenge-msavdert (or exactly as GitHub instructs) Content: The challenge code provided by GitHub. Return to GitHub and click Verify. (DNS changes might take a few minutes).\n4. Enforce HTTPS and SSL Settings # GitHub Pages automatically provisions HTTPS certificates for custom domains.\nGo back to your repository\u0026rsquo;s Settings \u0026gt; Pages.\nCheck the Enforce HTTPS box. (This might take up to 24 hours to become available after DNS changes).\nCloudflare SSL/TLS Settings:\nIf you decide to enable Cloudflare\u0026rsquo;s Proxy (Orange cloud) later, ensure your SSL/TLS encryption mode in Cloudflare is set to Full or Full (Strict) to avoid redirect loops. Do not use \u0026ldquo;Flexible\u0026rdquo;. Official References:\nManaging a custom domain for your GitHub Pages site Verifying your custom domain for GitHub Pages ","date":"27 February 2026","externalUrl":null,"permalink":"/posts/github-pages-cloudflare-setup/","section":"Posts","summary":"This guide provides the official, recommended steps to configure a custom subdomain (e.g., blog.savdert.com) for GitHub Pages using Cloudflare as your DNS provider, based on GitHub’s official documentation.\n1. Configure GitHub Pages # First, you need to tell your GitHub repository that you intend to use a custom domain.\nNavigate to your GitHub repository.\nGo to Settings \u003e Pages (under the “Code and automation” section).\n","title":"Setting Up GitHub Pages with Custom Subdomain Using Cloudflare DNS","type":"posts"},{"content":"","date":"26 February 2026","externalUrl":null,"permalink":"/categories/database/","section":"Categories","summary":"","title":"Database","type":"categories"},{"content":"Pigsty is an open-source, battery-included PostgreSQL distribution that allows you to self-host PostgreSQL databases like a professional RDS (Relational Database Service). Developed by Vonng, Pigsty provides a comprehensive platform for deploying, managing, and monitoring PostgreSQL clusters with enterprise-grade features.\nWhat is Pigsty? # Pigsty stands for \u0026ldquo;PostgreSQL In Great STYle\u0026rdquo; and encompasses Postgres, Infrastructure, Graphics, Service, Toolbox, and more. It\u0026rsquo;s designed to make PostgreSQL deployment as easy as possible while offering advanced capabilities that rival commercial database services.\nKey features include:\nExtensible: Supports 451+ PostgreSQL extensions Reliable: Self-healing HA clusters with PITR and SSL security Observable: Built-in monitoring with Victoria Metrics and Grafana Scalable: Auto-routed database services with connection pooling Maintainable: One-command deployment and IaC support Composable: Modular design with bonus modules like Redis, MinIO, and more Why Choose Pigsty for PostgreSQL? # Traditional PostgreSQL setup requires extensive configuration for high availability, monitoring, and security. Pigsty simplifies this by providing:\nPre-configured HA clusters using Patroni and etcd Point-in-time recovery with pgBackRest Comprehensive monitoring dashboards Automatic service discovery and load balancing Security best practices out of the box Getting Started with Pigsty # Prerequisites # Pigsty runs on bare Linux systems. Supported distributions include:\nRocky Linux / AlmaLinux / RHEL 8/9/10 Ubuntu 22.04/24.04 Debian 12/13 You\u0026rsquo;ll need a fresh Linux node (physical or virtual) with:\nx86_64 or aarch64 architecture At least 2GB RAM (4GB recommended) SSH access with sudo privileges Installation # Download and run the installer:\ncurl -fsSL https://repo.pigsty.io/get | bash cd ~/pigsty Configure your deployment:\n./configure -g # Generate config with random passwords Deploy Pigsty:\n./deploy.yml # Deploy everything on the current node After deployment, you\u0026rsquo;ll have:\nPostgreSQL running on port 5432 Web UI available at http://your-ip on ports 80 and 443 Monitoring dashboards at http://your-ip:3000 Creating Your First Database # Connect to PostgreSQL:\npsql -h your-ip -U dbuser_dba -d postgres Create a database and user:\nCREATE DATABASE myapp; CREATE USER myuser WITH PASSWORD \u0026#39;secure_password\u0026#39;; GRANT ALL PRIVILEGES ON DATABASE myapp TO myuser; Advanced Setup: HA Cluster # For production environments, deploy multi-node clusters:\nPrepare multiple nodes with Pigsty installed Configure cluster topology in pigsty.yml Run the deployment playbook Example 3-node cluster configuration:\npg-test: hosts: 10.10.10.11: { pg_seq: 1, pg_role: primary } 10.10.10.12: { pg_seq: 2, pg_role: replica } 10.10.10.13: { pg_seq: 3, pg_role: offline } vars: { pg_cluster: pg-test } Deploy with:\nbin/pgsql-add pg-test PostgreSQL-Specific Features in Pigsty # Pigsty enhances PostgreSQL with:\nExtension Management: Easy installation of popular extensions like PostGIS, TimescaleDB, etc. Performance Tuning: Auto-tuning based on hardware and workload Backup \u0026amp; Recovery: Integrated PITR with optional S3/MinIO storage Security: Pre-configured SSL, HBA rules, and access controls Monitoring: Detailed metrics for PostgreSQL performance, queries, and system health Conclusion # Pigsty transforms PostgreSQL from a powerful database engine into a complete database platform. Whether you\u0026rsquo;re a developer looking for a local PostgreSQL setup or an organization needing production-grade database infrastructure, Pigsty provides the tools and automation to get started quickly and maintain reliably.\nFor more information, visit the Pigsty documentation or check out the GitHub repository.\n","date":"26 February 2026","externalUrl":null,"permalink":"/posts/getting-started-with-pigsty/","section":"Posts","summary":"Pigsty is an open-source, battery-included PostgreSQL distribution that allows you to self-host PostgreSQL databases like a professional RDS (Relational Database Service). Developed by Vonng, Pigsty provides a comprehensive platform for deploying, managing, and monitoring PostgreSQL clusters with enterprise-grade features.\nWhat is Pigsty? # Pigsty stands for “PostgreSQL In Great STYle” and encompasses Postgres, Infrastructure, Graphics, Service, Toolbox, and more. It’s designed to make PostgreSQL deployment as easy as possible while offering advanced capabilities that rival commercial database services.\n","title":"Getting Started with Pigsty: Self-Hosting PostgreSQL Like a Pro","type":"posts"},{"content":"","date":"26 February 2026","externalUrl":null,"permalink":"/tags/pigsty/","section":"Tags","summary":"","title":"Pigsty","type":"tags"},{"content":"","date":"26 February 2026","externalUrl":null,"permalink":"/tags/postgresql/","section":"Tags","summary":"","title":"Postgresql","type":"tags"},{"content":"","date":"15 February 2026","externalUrl":null,"permalink":"/tags/blowfish/","section":"Tags","summary":"","title":"Blowfish","type":"tags"},{"content":"Building a fast, lightweight, and modern developer blog doesn\u0026rsquo;t have to require heavy server infrastructure or database systems. In this article, I will walk you through the exact technical details of how this blog was initialized, customized, and automated using Hugo, the Blowfish theme, Git submodules, and GitHub Actions.\nThe Core Stack # Static Site Generator: Hugo (known for being incredibly fast to build). Theme: Blowfish (a highly configurable, responsive, and aesthetically premium Hugo theme built with Tailwind CSS). Hosting \u0026amp; CI/CD: GitHub Pages deployed automatically via a GitHub Actions workflow. Step 1: Repository Initialization \u0026amp; GitHub Setup # To build a personal site hosted on GitHub Pages, we start by duplicating a starter template.\nUse the Template: Go to the official nunocoracao/blowfish_template repository and click \u0026ldquo;Use this template\u0026rdquo; -\u0026gt; \u0026ldquo;Create a new repository\u0026rdquo;. Repository Naming: Name your repository exactly \u0026lt;username\u0026gt;.github.io (for example, ours is msavdert.github.io). Using this exact format tells GitHub to serve this repository as your root personal domain. Make the repository Public. Configure Settings on GitHub: GitHub Actions Workflow Permissions: Navigate to Settings -\u0026gt; Actions -\u0026gt; General, scroll down to Workflow permissions, and select \u0026ldquo;Read and write permissions\u0026rdquo;. This is critical because the compilation process needs write access to deploy. GitHub Pages Deployment Source: Navigate to Settings -\u0026gt; Pages. Under Build and deployment -\u0026gt; Source, change the dropdown selection from Deploy from a branch to \u0026ldquo;GitHub Actions\u0026rdquo;. This instructs GitHub to run your custom build workflow file (.github/workflows/pages.yml) rather than deploying raw files. Initializing the Theme Submodule Locally # When copying or cloning the template, the theme folder (themes/blowfish) is initialized as an empty directory reference. To download the actual theme source files, clone your newly created repository locally and run the following command in the root folder:\ngit submodule update --init --recursive This populates /themes/blowfish/ with all the files from the official nunocoracao/blowfish repository.\nStep 2: Configuration \u0026amp; Personalization # Hugo templates default to the creator\u0026rsquo;s metadata. To customize it, three key TOML config files are modified:\nA. Core Site URL (config/_default/hugo.toml) # We uncomment and set the baseURL to the user\u0026rsquo;s GitHub Pages domain:\nbaseURL = \u0026#34;https://msavdert.github.io/\u0026#34; B. Language \u0026amp; Author Info (config/_default/languages.en.toml) # Here we customize the title, meta descriptions, author headline, social links (GitHub, LinkedIn, Email), and biography:\n[en] title = \u0026#34;Melih Savdert\u0026#39;s Tech Blog\u0026#34; description = \u0026#34;Technical articles and guides on Platform Engineering, Kubernetes, DevOps, and Database Administration.\u0026#34; [en.author] name = \u0026#34;Melih Savdert\u0026#34; headline = \u0026#34;Platform Engineer | DevOps | DBA | Kubernetes\u0026#34; bio = \u0026#34;Hi! I am Melih, a Platform Engineer specializing in Kubernetes, cloud infrastructure, database management, and automating software delivery.\u0026#34; image = \u0026#34;img/avatar.png\u0026#34; C. Theme Visuals (config/_default/params.toml) # Blowfish supports a dark/light toggle and multiple pre-configured color schemes. For a clean developer aesthetic, the site is forced to dark mode and uses the premium slate color scheme. We also enable post listings on the homepage:\n[theme] defaultAppearance = \u0026#34;dark\u0026#34; colorScheme = \u0026#34;slate\u0026#34; [homepage] showRecent = true showRecentItems = 5 showMoreLink = true Step 3: Modernizing the CI/CD Pipeline to Node.js 24 # One of the common issues in standard workflows is Node.js version deprecation warnings (e.g., Node.js 20 deprecation). To ensure a warning-free and future-proof pipeline, the GitHub Actions workflow file (.github/workflows/pages.yml) was migrated to native Node.js 24 action versions:\nUpgraded checkout action to actions/checkout@v6 Upgraded pages configuration to actions/configure-pages@v6 Upgraded pages artifact upload to actions/upload-pages-artifact@v5 (using upload-artifact@v7 internally) Upgraded pages deployment to actions/deploy-pages@v5 Upgraded Hugo build runner to peaceiris/actions-hugo@v3 This ensures that the build runner compiles our Hugo site using native Node.js 24 actions, completely avoiding deprecation warnings.\nStep 4: Maintenance \u0026amp; Theme Upgrades # Since the Blowfish theme is a Git submodule, upgrading it is straightforward.\nChecking the Current Version # To find the exact commit or version of Blowfish checking out:\ngit -C themes/blowfish describe --tags Output: v2.103.0\nUpgrading to the Latest Theme Version # To pull down any upstream changes from the Blowfish repository and merge them into the tracking branch:\ngit submodule update --remote --merge Alternatively, to pin to a specific release (like v2.104.0):\ngit -C themes/blowfish fetch --tags git -C themes/blowfish checkout v2.104.0 Finally, pushing the updated submodule reference triggers the GitHub Actions rebuild:\ngit add themes/blowfish git commit -m \u0026#34;Upgrade Blowfish theme to latest version\u0026#34; git push origin main The Git-Backed Content Workflow # To add new content to this blog, I follow a set of simple, structured formatting rules:\nA. Folder Structure (Page Bundles) # Instead of putting a single flat .md file under content/posts/, I use Hugo Page Bundles (a folder per post). This encapsulates all resources (images, attachments) with the text itself.\nStructure: content/ └── posts/ └── my-new-post/ ├── index.md \u0026lt;-- The main markdown post ├── schema.png \u0026lt;-- Image referenced by index.md └── performance.csv \u0026lt;-- Supplemental attachment B. Front-Matter Metadata Setup # At the top of every index.md file, a YAML front-matter block contains the metadata that Blowfish reads to display card titles, summary descriptions, categories, and tags:\n--- title: \u0026#34;Your Post Title Here\u0026#34; date: 2026-05-22 draft: false description: \u0026#34;A short, 1-2 sentence description shown in SEO listings and search results.\u0026#34; tags: [\u0026#34;Kubernetes\u0026#34;, \u0026#34;DevOps\u0026#34;] # Case-sensitive taxonomies categories: [\u0026#34;Infrastructure\u0026#34;] # High-level groupings # Optional settings: # showAuthor: true # featureImage: \u0026#34;schema.png\u0026#34; # Relative path to directory image # showTableOfContents: true --- C. Formatting and Images # Headings: Use ## or ### for headings. Avoid using # as the post title in front-matter is already mapped to the HTML \u0026lt;h1\u0026gt; header automatically. Images: Keep images inside the post\u0026rsquo;s bundle folder and reference them using clean relative paths: ![Alt text describing image](schema.png) D. Drafting vs. Publishing # Set draft: true while writing. The local/CI build pipeline ignores drafts. Set draft: false when you are ready to publish. E. Commit \u0026amp; Publish # Once written and verified, the post is pushed to GitHub:\ngit add content/posts/my-new-post/ git commit -m \u0026#34;feat: publish post about [topic]\u0026#34; git push origin main Within 60 seconds, GitHub Actions finishes the Hugo compilation and deploys the new post live to the global CDN at https://msavdert.github.io/.\n","date":"15 February 2026","externalUrl":null,"permalink":"/posts/how-this-blog-was-built/","section":"Posts","summary":"Building a fast, lightweight, and modern developer blog doesn’t have to require heavy server infrastructure or database systems. In this article, I will walk you through the exact technical details of how this blog was initialized, customized, and automated using Hugo, the Blowfish theme, Git submodules, and GitHub Actions.\nThe Core Stack # Static Site Generator: Hugo (known for being incredibly fast to build). Theme: Blowfish (a highly configurable, responsive, and aesthetically premium Hugo theme built with Tailwind CSS). Hosting \u0026 CI/CD: GitHub Pages deployed automatically via a GitHub Actions workflow. Step 1: Repository Initialization \u0026 GitHub Setup # To build a personal site hosted on GitHub Pages, we start by duplicating a starter template.\n","title":"Building a Modern Tech Blog with Hugo, Blowfish, and GitHub Actions","type":"posts"},{"content":"","date":"15 February 2026","externalUrl":null,"permalink":"/tags/github-actions/","section":"Tags","summary":"","title":"Github-Actions","type":"tags"},{"content":"","date":"15 February 2026","externalUrl":null,"permalink":"/tags/hugo/","section":"Tags","summary":"","title":"Hugo","type":"tags"},{"content":"Welcome to my new technical blog! Here, I will be sharing guides, architectural insights, and hands-on tutorials about platform engineering, cloud-native deployments, database administration, and automating complex systems.\nWhat We Will Cover # In-depth technical articles on the following domains:\nPlatform Engineering: Building internal developer platforms (IDPs), Infrastructure as Code (IaC) patterns, and developer self-service tools. Kubernetes: Cloud-native architecture, container orchestration, scaling, ingress management, and operators. DevOps \u0026amp; CI/CD: Software delivery pipelines, automating GitOps workflows (e.g., ArgoCD, Flux), and security scanning. Database Administration (DBA): Designing high-availability database architectures, automated backups, performance tuning, and database reliability engineering. Stay tuned for upcoming deep dives!\n","date":"1 February 2026","externalUrl":null,"permalink":"/posts/hello-world/","section":"Posts","summary":"Welcome to my new technical blog! Here, I will be sharing guides, architectural insights, and hands-on tutorials about platform engineering, cloud-native deployments, database administration, and automating complex systems.\nWhat We Will Cover # In-depth technical articles on the following domains:\nPlatform Engineering: Building internal developer platforms (IDPs), Infrastructure as Code (IaC) patterns, and developer self-service tools. Kubernetes: Cloud-native architecture, container orchestration, scaling, ingress management, and operators. DevOps \u0026 CI/CD: Software delivery pipelines, automating GitOps workflows (e.g., ArgoCD, Flux), and security scanning. Database Administration (DBA): Designing high-availability database architectures, automated backups, performance tuning, and database reliability engineering. Stay tuned for upcoming deep dives!\n","title":"Welcome to my Platform \u0026 DevOps Blog","type":"posts"},{"content":"","externalUrl":null,"permalink":"/authors/","section":"Authors","summary":"","title":"Authors","type":"authors"},{"content":"","externalUrl":null,"permalink":"/series/","section":"Series","summary":"","title":"Series","type":"series"}]