Proxmox setup with claude code

This is a session from Claude Code exported to markdown1 of part of the process of setting up my new MiniPC at home GMKtec Mini PC Setup


[!NOTE] Blue blocks are user messages

[!TIP] Green blocks are agent (teammate) reports

Plain quoted lines are Claude responses

Field Value
Date 05/26/2026, 21:38
Model claude-sonnet-4-6
Working Directory /Users/bmann/Developer/bmannskills
Session fcb96e0d-9feb-4e71-b006-c5199540f7c9
Claude Code v2.1.149

[!NOTE] User 05/26 21:38:16

I am configuring a proxmox server on my local home network. There is a UniFi Dream Machine as the router which has a single public IP Address. I currently have port forwarding setup where inbound traffic for ports 80, 443, and 8006 all point at the IP address of the proxmox host. How should I configure this so that I can route traffic to additional VMs on proxmox, which currently get their own private IP addresses?

Claude 05/26 21:38:28

The standard approach here is to add a reverse proxy as the single entry point for ports 80/443, which then routes traffic to individual VMs based on the hostname. Port 8006 (Proxmox web UI) can stay as a direct forward.

Internet β†’ UDM (public IP) β†’ port forward 80/443 β†’ Reverse Proxy VM
                                                         β”œβ”€β”€ vm1.yourdomain.com β†’ 192.168.x.10
                                                         β”œβ”€β”€ vm2.yourdomain.com β†’ 192.168.x.11
                                                         └── app.yourdomain.com β†’ 192.168.x.12

                           β†’ port forward 8006 β†’ Proxmox host (keep as-is)

Implementation Options

Easiest: Nginx Proxy Manager (LXC container or VM)

  • Web UI for managing proxy rules, automatic Let's Encrypt certs
  • Point all subdomains at one IP, NPM routes by Host: header
  • LXC container keeps overhead minimal

More control: Traefik or Caddy

  • Traefik auto-discovers Docker containers and has great config-as-code
  • Caddy has automatic HTTPS with very simple config syntax
  • Better if you want GitOps-style management

Already have nginx skills: nginx

  • server_name blocks route by hostname, proxy_pass to VM IPs

Steps

  1. Create a dedicated LXC or VM on Proxmox for the reverse proxy (give it a static private IP, e.g. 192.168.1.50)
  2. Change your UDM port forwarding: 80 and 443 β†’ proxy VM IP (instead of Proxmox host)
  3. Point DNS subdomains at your public IP (e.g. vm1.yourdomain.com, app.yourdomain.com)
  4. Configure the proxy to route each hostname to the correct VM's internal IP

For Non-HTTP Services

If VMs need to expose non-HTTP ports (SSH, databases, game servers, etc.), you have two options:

  • Different external ports: forward 2222 β†’ VM1:22, 2223 β†’ VM2:22 on UDM
  • Wireguard/VPN: set up a VPN (UDM supports Wireguard natively) and access services directly on internal IPs when connected β€” better security posture for admin access

For a home lab, Nginx Proxy Manager is the fastest path to working. For something you want to maintain long-term with code, Caddy has the cleanest config syntax.

[!NOTE] User 05/26 21:40:25

I am using Tailscale already, can I connect the UDM to my Tailnet directly?

Claude 05/26 21:40:43

Yes, but the better path for your use case is probably a subnet router on Proxmox rather than Tailscale on the UDM itself.

Run Tailscale on the Proxmox host (or a dedicated LXC) and advertise your local subnet:

# On Proxmox host
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up --advertise-routes=192.168.1.0/24 --accept-routes

Then approve the subnet route in the Tailscale admin console. From any Tailscale device, you can now reach all your VMs at their private IPs directly β€” no reverse proxy needed for admin/personal access.

This also means you can remove port 8006 from your UDM port forwarding entirely, since you'd access Proxmox over Tailscale instead.

Option B: Tailscale on the UDM Directly

This is possible via the community unifios-utilities project, which provides a package manager for UnifiOS. It works, but:

  • Not officially supported by Ubiquiti
  • UnifiOS firmware updates can break the installation
  • Requires SSH access to the UDM and manual reinstall after some upgrades

Worth it if you want the UDM itself as a Tailscale node (e.g., for exit node use), but it's more maintenance than the Proxmox subnet router approach.

How This Changes Your Setup

With a subnet router running, your architecture simplifies:

Tailscale clients β†’ subnet router (Proxmox) β†’ any VM by private IP

Internet β†’ UDM port forward 80/443 β†’ reverse proxy VM   (public-facing services only)

Port 8006 and any other admin ports can come out of UDM port forwarding entirely β€” access them exclusively over Tailscale. This significantly reduces your attack surface.

For your stated goal (routing to additional VMs), the subnet router gets you there immediately with no per-VM configuration β€” you just access each VM's private IP directly from any Tailscale device.

[!NOTE] User 05/26 21:45:10

Great. I already have tailscale installed on the proxmox host, I'll do that. The LXC container for nginx proxy manager seems like a good approach. What are the steps for spinning up that LXC on the proxmox host?

Claude 05/26 21:45:28

The fastest path is the Proxmox community helper scripts, which automate the LXC creation and NPM installation in one step.

Step 1: Create the LXC

SSH into your Proxmox host (or open the Shell in the web UI) and run:

bash -c "$(wget -qLO - https://github.com/community-scripts/ProxmoxVE/raw/main/ct/nginx-proxy-manager.sh)"

It will prompt for basic options (or accept defaults). It creates a Debian LXC, installs NPM, and prints the container's IP when done.

Note: This runs a script from the internet as root. It's widely used in the home lab community and the repo is at community-scripts/ProxmoxVE on GitHub if you want to review it first.

Step 2: Assign a Static IP

Before pointing your UDM at it, give the LXC a static IP so it doesn't change. In Proxmox UI:

  • Select the container β†’ Network β†’ edit the eth0 interface
  • Change from DHCP to a static IP (e.g. 192.168.1.50/24), set gateway to your UDM IP
  • Restart the container

Step 3: Update UDM Port Forwarding

Change your existing port forward rules:

  • 80 β†’ LXC static IP
  • 443 β†’ LXC static IP
  • Leave 8006 as-is for now (remove it once Tailscale subnet routing is confirmed working)

Step 4: Access NPM Admin UI

Navigate to http://<lxc-ip>:81 from your browser.

Default credentials:

  • Email: admin@example.com
  • Password: changeme

You'll be forced to change these on first login.

Step 5: Add a Proxy Host

For each VM you want to expose publicly:

  1. Proxy Hosts β†’ Add Proxy Host
  2. Domain Names: your subdomain (e.g. app.yourdomain.com)
  3. Forward Hostname/IP: the VM's private IP
  4. Forward Port: whatever port the service runs on
  5. SSL tab: Request a Let's Encrypt cert (requires your domain's DNS to be pointing at your public IP)

Repeat for each service. NPM handles cert renewal automatically.

[!NOTE] User 05/26 21:48:24

Great, thank you. I realize that port forwarding on the proxmox host isn't quite setup correctly. Here's the error message: "Warning: IPv6 forwarding is disabled. Traffic received on nic0 won't be forwarded (net.ipv4.conf.nic0.forwarding disabled) Traffic received on wlp1s0 won't be forwarded (net.ipv4.conf.wlp1s0.forwarding disabled) Traffic received on tailscale0 won't be forwarded (net.ipv4.conf.tailscale0.forwarding disabled) Subnet routes and exit nodes may not work correctly. See https://tailscale.com/s/ip-forwarding Warning: UDP GRO forwarding is suboptimally configured on vmbr0, UDP forwarding throughput capability will increase with a configuration change. See https://tailscale.com/s/ethtool-config-udp-gro" -> how do I turn on forwarding?

Claude 05/26 21:48:39

Two separate fixes needed. Run these on the Proxmox host.

Fix 1: Enable IP Forwarding (permanent)

Create a sysctl config file so it persists across reboots:

echo 'net.ipv4.ip_forward = 1' | tee -a /etc/sysctl.d/99-tailscale.conf
echo 'net.ipv6.conf.all.forwarding = 1' | tee -a /etc/sysctl.d/99-tailscale.conf
sysctl -p /etc/sysctl.d/99-tailscale.conf

Fix 2: UDP GRO Forwarding on vmbr0 (permanent)

This is a performance issue specific to the Proxmox bridge. Add a post-up hook to /etc/network/interfaces so it applies on every boot.

Open the file:

nano /etc/network/interfaces

Find the vmbr0 block and add the post-up line:

iface vmbr0 inet static
    address 192.168.1.x/24
    gateway 192.168.1.1
    bridge-ports eno1
    bridge-stp off
    bridge-fd 0
    post-up ethtool -K vmbr0 rx-udp-gro-forwarding on gro-hw off

Apply it immediately without rebooting:

ethtool -K vmbr0 rx-udp-gro-forwarding on gro-hw off

Verify Tailscale is Happy

tailscale status

The forwarding warnings should be gone. If you haven't already advertised your subnet:

tailscale up --advertise-routes=192.168.1.0/24 --accept-routes

Then go to the Tailscale admin console and approve the advertised route for this machine.

[!NOTE] User 05/26 21:53:06

I got an error on running ethtool "netlink error: bit name not found (offset 92)"

Claude 05/26 21:53:19

This is a kernel version issue β€” rx-udp-gro-forwarding requires a newer kernel than what's running. Check your kernel:

uname -r

First try without the gro-hw off part, since that flag is the one that often fails on bridge interfaces:

ethtool -K vmbr0 rx-udp-gro-forwarding on

If that also fails, your kernel simply doesn't support it. This is fine β€” the UDP GRO warning from Tailscale is a performance advisory, not a functional error. Subnet routing will work correctly without it; you'd just see slightly reduced UDP throughput at high load, which is unlikely to matter on a home network.

In that case, remove the post-up line you added to /etc/network/interfaces to keep the config clean, and move on. The IP forwarding fix from Fix 1 is the important one.

[!NOTE] User 05/26 22:02:05

Great, Fix 1 did it, thank you.

Claude 05/26 22:02:09

Glad that sorted it. To recap where you are:

  • Tailscale subnet routing is active on the Proxmox host β€” you can reach all VMs by private IP from any Tailscale device
  • Next step when ready: spin up the Nginx Proxy Manager LXC and point UDM ports 80/443 at it for public-facing services
  • Once Tailscale access is confirmed working, you can remove port 8006 from UDM port forwarding to close that off from the public internet
  1. See cc2md ↩

Notes mentioning this note