Skip to content

Instantly share code, notes, and snippets.

@sjelfull
Last active January 27, 2026 22:29
Show Gist options
  • Select an option

  • Save sjelfull/a34a7eaa14690acd18a01cbbd622698d to your computer and use it in GitHub Desktop.

Select an option

Save sjelfull/a34a7eaa14690acd18a01cbbd622698d to your computer and use it in GitHub Desktop.
Proxmox Tailscale LXC - Create minimal LXC for Tailscale exit node / subnet router

Proxmox Tailscale LXC

Creates a minimal Debian 12 LXC container on Proxmox with Tailscale pre-installed and configured for use as an exit node or subnet router.

Requirements

  • Proxmox VE host - Run this script directly on your Proxmox server via SSH or the web console shell
  • Root access (the script will verify)
  • Internet connectivity (to download Debian template and Tailscale)

Note: This script must be run on the Proxmox host itself, not inside a VM or container.

Quick Start

One-liner (from gist)

bash -c "$(curl -fsSL https://gist.githubusercontent.com/sjelfull/a34a7eaa14690acd18a01cbbd622698d/raw/create-tailscale-lxc.sh)"

With auth key (fully automated)

bash -c "$(curl -fsSL https://gist.githubusercontent.com/sjelfull/a34a7eaa14690acd18a01cbbd622698d/raw/create-tailscale-lxc.sh)" -- --auth-key tskey-auth-xxxxx

Local usage

chmod +x create-tailscale-lxc.sh
./create-tailscale-lxc.sh

Options

Option Description Default
--ctid <id> Container ID Next available
--hostname <name> Container hostname tailscale
--storage <name> Storage pool Auto-detect
--auth-key <key> Tailscale auth key None (interactive)
--memory <mb> Memory in MB 512
--disk <gb> Disk size in GB 2

Examples

# Interactive mode - prompts for all values
./create-tailscale-lxc.sh

# Automated with auth key
./create-tailscale-lxc.sh --auth-key tskey-auth-xxxxx

# Custom configuration
./create-tailscale-lxc.sh --ctid 200 --hostname ts-exit --storage local-zfs

# Full automation
./create-tailscale-lxc.sh --ctid 200 --hostname tailscale-exit --auth-key tskey-auth-xxxxx

After Installation

Authenticate (if no auth-key provided)

pct exec <CTID> -- tailscale up

Follow the URL printed to authenticate in your browser.

Check Status

pct exec <CTID> -- tailscale status

Exit Node Setup

An exit node routes all internet traffic from other Tailscale devices through this container. Useful for:

  • Securing traffic on untrusted networks (coffee shops, hotels)
  • Accessing geo-restricted content from your home network
  • Providing a consistent IP address for external services

Step 1: Advertise as Exit Node

pct exec <CTID> -- tailscale up --advertise-exit-node

If already authenticated, use tailscale set instead:

pct exec <CTID> -- tailscale set --advertise-exit-node

Step 2: Approve in Admin Console

  1. Go to Tailscale Admin Console
  2. Find your machine in the list
  3. Click the ... menu → Edit route settings
  4. Enable Use as exit node
  5. Save

Step 3: Use from Client Devices

macOS/Windows/Linux GUI:

  • Click Tailscale icon → Exit Node → Select your node

Linux CLI:

tailscale up --exit-node=<hostname-or-ip>

iOS/Android:

  • Open Tailscale app → Exit Node → Select your node

Verify Exit Node is Working

From a client using the exit node:

# Should show the exit node's public IP, not your local IP
curl ifconfig.me

Subnet Router Setup

A subnet router allows Tailscale devices to access your local network (e.g., printers, NAS, IoT devices) without installing Tailscale on each device.

Step 1: Advertise Routes

# Single subnet
pct exec <CTID> -- tailscale up --advertise-routes=192.168.1.0/24

# Multiple subnets
pct exec <CTID> -- tailscale up --advertise-routes=192.168.1.0/24,10.0.0.0/24

Step 2: Approve in Admin Console

  1. Go to Tailscale Admin Console
  2. Find your machine
  3. Click ... menu → Edit route settings
  4. Enable the subnets you want to advertise
  5. Save

Step 3: Access from Clients

Clients can now reach devices on the advertised subnets:

# Access a device at 192.168.1.100
ping 192.168.1.100
ssh user@192.168.1.100

Combined: Exit Node + Subnet Router

You can run both simultaneously:

pct exec <CTID> -- tailscale up \
    --advertise-exit-node \
    --advertise-routes=192.168.1.0/24

Useful Commands

Container Management

# Enter container shell
pct enter <CTID>

# Execute command in container
pct exec <CTID> -- <command>

# Stop/start container
pct stop <CTID>
pct start <CTID>

# View container config
pct config <CTID>

Tailscale Commands (inside container)

# Status
tailscale status

# Detailed status
tailscale status --peers

# Check IP addresses
tailscale ip

# View current settings
tailscale debug prefs

# Disconnect
tailscale down

# Reconnect
tailscale up

# Logout completely
tailscale logout

Logs

# Tailscale daemon logs
pct exec <CTID> -- journalctl -u tailscaled -f

# Container logs from host
journalctl -u pve-container@<CTID>

Troubleshooting

TUN device not available

Verify TUN is configured in container:

pct exec <CTID> -- ls -la /dev/net/tun

If missing, check /etc/pve/lxc/<CTID>.conf contains:

lxc.cgroup2.devices.allow: c 10:200 rwm
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file

Restart container after changes.

Tailscale won't connect

# Check tailscaled is running
pct exec <CTID> -- systemctl status tailscaled

# Restart tailscaled
pct exec <CTID> -- systemctl restart tailscaled

# Check for errors
pct exec <CTID> -- journalctl -u tailscaled --no-pager -n 50

Exit node not working

  1. Verify IP forwarding is enabled:
pct exec <CTID> -- sysctl net.ipv4.ip_forward
# Should show: net.ipv4.ip_forward = 1
  1. Verify exit node is approved in admin console

  2. Check client is actually using exit node:

tailscale status
# Should show "exit node: <hostname>"

Subnet routes not accessible

  1. Verify routes are approved in admin console
  2. Check IP forwarding is enabled (see above)
  3. Ensure no firewall blocking traffic in container

Security Considerations

Example ACL to restrict exit node usage:

{
  "acls": [
    {
      "action": "accept",
      "src": ["group:admins"],
      "dst": ["autogroup:internet"]
    }
  ]
}

References

#!/usr/bin/env bash
# Proxmox Tailscale LXC Creator
# Creates a minimal Debian LXC container with Tailscale pre-installed
# Configured for exit node / subnet router use
#
# Usage: ./create-tailscale-lxc.sh [OPTIONS]
# or: bash -c "$(curl -fsSL URL)" -- [OPTIONS]
#
# Options:
# --ctid <id> Container ID (default: auto-detect next available)
# --hostname <name> Hostname (default: tailscale)
# --storage <name> Storage pool (default: auto-detect)
# --auth-key <key> Tailscale auth key for automatic authentication
# --memory <mb> Memory in MB (default: 512)
# --disk <gb> Disk size in GB (default: 2)
# -h, --help Show this help message
set -Eeuo pipefail
# Colors and formatting
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
BOLD='\033[1m'
# Default values
DEFAULT_HOSTNAME="tailscale"
DEFAULT_MEMORY=512
DEFAULT_DISK=2
TEMPLATE_NAME="debian-12-standard"
# Script variables
CTID=""
HOSTNAME=""
STORAGE=""
AUTH_KEY=""
MEMORY=""
DISK=""
HEADLESS=false
banner() {
echo -e "${CYAN}"
cat << 'EOF'
╔╦╗┌─┐┬┬ ┌─┐┌─┐┌─┐┬ ┌─┐ ╦ ═╗ ╦╔═╗
║ ├─┤││ └─┐│ ├─┤│ ├┤ ║ ╔╩╦╝║
╩ ┴ ┴┴┴─┘└─┘└─┘┴ ┴┴─┘└─┘ ╩═╝╩ ╚═╚═╝
EOF
echo -e "${NC}${BOLD} Proxmox LXC Creator${NC}"
echo ""
}
msg_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
msg_ok() { echo -e "${GREEN}[OK]${NC} $1"; }
msg_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
msg_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# Confirmation prompt with default value
confirm() {
local prompt="$1"
local default="${2:-y}"
local yn
if [[ "$default" == "y" ]]; then
read -rp "${prompt} [Y/n]: " yn
yn=${yn:-y}
else
read -rp "${prompt} [y/N]: " yn
yn=${yn:-n}
fi
[[ "${yn,,}" =~ ^y ]]
}
# Display settings in a styled box
show_settings() {
local width=50
echo ""
echo -e "${CYAN}┌$(printf '─%.0s' $(seq 1 $width))┐${NC}"
echo -e "${CYAN}│${NC} ${BOLD}Container Settings${NC}$(printf ' %.0s' $(seq 1 $((width - 19))))${CYAN}│${NC}"
echo -e "${CYAN}├$(printf '─%.0s' $(seq 1 $width))┤${NC}"
printf "${CYAN}│${NC} %-18s : %-27s ${CYAN}│${NC}\n" "Container ID" "$CTID"
printf "${CYAN}│${NC} %-18s : %-27s ${CYAN}│${NC}\n" "Hostname" "$HOSTNAME"
printf "${CYAN}│${NC} %-18s : %-27s ${CYAN}│${NC}\n" "Storage" "$STORAGE"
printf "${CYAN}│${NC} %-18s : %-27s ${CYAN}│${NC}\n" "Memory" "${MEMORY} MB"
printf "${CYAN}│${NC} %-18s : %-27s ${CYAN}│${NC}\n" "Disk" "${DISK} GB"
if [[ -n "$AUTH_KEY" ]]; then
printf "${CYAN}│${NC} %-18s : %-27s ${CYAN}│${NC}\n" "Auth Key" "Provided"
else
printf "${CYAN}│${NC} %-18s : %-27s ${CYAN}│${NC}\n" "Auth Key" "None (manual auth)"
fi
echo -e "${CYAN}└$(printf '─%.0s' $(seq 1 $width))┘${NC}"
echo ""
}
# Show intro warning and get confirmation
wizard_intro() {
echo ""
echo -e "${YELLOW}${BOLD}This script will create a new LXC container with:${NC}"
echo -e " - Debian 12 (minimal)"
echo -e " - Tailscale pre-installed"
echo -e " - Configured for exit node / subnet router use"
echo -e " - TUN device access enabled"
echo -e " - IP forwarding enabled"
echo ""
if ! confirm "Proceed with container creation?"; then
echo ""
msg_info "Cancelled by user"
exit 0
fi
echo ""
}
usage() {
cat << EOF
Usage: $0 [OPTIONS]
Creates a minimal Debian LXC container with Tailscale pre-installed,
configured for use as an exit node or subnet router.
Options:
--ctid <id> Container ID (default: next available)
--hostname <name> Hostname (default: $DEFAULT_HOSTNAME)
--storage <name> Storage pool (default: auto-detect)
--auth-key <key> Tailscale auth key for automatic authentication
--memory <mb> Memory in MB (default: $DEFAULT_MEMORY)
--disk <gb> Disk size in GB (default: $DEFAULT_DISK)
-h, --help Show this help message
Examples:
$0 # Interactive mode
$0 --auth-key tskey-auth-xxxxx # Automated with auth key
$0 --ctid 200 --hostname ts-exit # Custom CTID and hostname
EOF
exit 0
}
check_root() {
if [[ $EUID -ne 0 ]]; then
msg_error "This script must be run as root on the Proxmox host"
exit 1
fi
}
check_proxmox() {
if ! command -v pveversion &>/dev/null; then
msg_error "This script must be run on a Proxmox VE host"
exit 1
fi
msg_ok "Running on Proxmox VE $(pveversion | awk -F'/' '{print $2}')"
}
parse_args() {
while [[ $# -gt 0 ]]; do
case $1 in
--ctid)
CTID="$2"
shift 2
;;
--hostname)
HOSTNAME="$2"
shift 2
;;
--storage)
STORAGE="$2"
shift 2
;;
--auth-key)
AUTH_KEY="$2"
HEADLESS=true
shift 2
;;
--memory)
MEMORY="$2"
shift 2
;;
--disk)
DISK="$2"
shift 2
;;
-h|--help)
usage
;;
--)
shift
;;
*)
msg_error "Unknown option: $1"
usage
;;
esac
done
}
get_next_ctid() {
pvesh get /cluster/nextid 2>/dev/null || echo "100"
}
detect_storage() {
local storages
storages=$(pvesm status -content rootdir 2>/dev/null | awk 'NR>1 && $3=="active" {print $1}')
if [[ -z "$storages" ]]; then
msg_error "No storage pools available for containers"
exit 1
fi
local count
count=$(echo "$storages" | wc -l)
if [[ $count -eq 1 ]]; then
echo "$storages"
else
echo "$storages" | head -1
fi
}
detect_template_storage() {
local storage
storage=$(pvesm status -content vztmpl 2>/dev/null | awk 'NR>1 && $3=="active" {print $1; exit}')
if [[ -z "$storage" ]]; then
msg_error "No storage with template (vztmpl) support found"
msg_info "Enable on 'local': pvesm set local -content vztmpl,iso,backup"
exit 1
fi
echo "$storage"
}
select_storage() {
local storages
storages=$(pvesm status -content rootdir 2>/dev/null | awk 'NR>1 && $3=="active" {print $1}')
if [[ -z "$storages" ]]; then
msg_error "No storage pools available for containers"
exit 1
fi
local count
count=$(echo "$storages" | wc -l)
if [[ $count -eq 1 ]]; then
STORAGE="$storages"
msg_info "Using storage: $STORAGE"
else
msg_info "Available storage pools:"
local i=1
declare -A storage_map
while IFS= read -r s; do
echo " $i) $s"
storage_map[$i]="$s"
((i++))
done <<< "$storages"
while true; do
read -rp "Select storage [1]: " choice
choice=${choice:-1}
if [[ -n "${storage_map[$choice]:-}" ]]; then
STORAGE="${storage_map[$choice]}"
break
fi
echo "Invalid selection"
done
fi
}
set_defaults() {
# Set defaults for any values not provided via CLI
[[ -z "$CTID" ]] && CTID=$(get_next_ctid)
[[ -z "$HOSTNAME" ]] && HOSTNAME=$DEFAULT_HOSTNAME
[[ -z "$STORAGE" ]] && STORAGE=$(detect_storage)
[[ -z "$MEMORY" ]] && MEMORY=$DEFAULT_MEMORY
[[ -z "$DISK" ]] && DISK=$DEFAULT_DISK
}
validate_ctid() {
if pct status "$CTID" &>/dev/null; then
msg_error "Container $CTID already exists"
exit 1
fi
}
prompt_settings() {
local next_id
next_id=$(get_next_ctid)
echo -e "${BOLD}Basic Settings:${NC}"
echo ""
# CTID
read -rp " Container ID [$CTID]: " input
CTID=${input:-$CTID}
# Hostname
read -rp " Hostname [$HOSTNAME]: " input
HOSTNAME=${input:-$HOSTNAME}
# Storage selection
select_storage
echo ""
echo -e "${BOLD}Resources:${NC}"
echo ""
# Memory
read -rp " Memory in MB [$MEMORY]: " input
MEMORY=${input:-$MEMORY}
# Disk
read -rp " Disk size in GB [$DISK]: " input
DISK=${input:-$DISK}
}
prompt_auth_key() {
echo ""
echo -e "${BOLD}Tailscale Authentication:${NC}"
echo ""
echo -e " ${CYAN}Get an auth key from: https://login.tailscale.com/admin/settings/keys${NC}"
echo -e " Leave empty to authenticate manually after creation."
echo ""
read -rp " Auth key (optional): " AUTH_KEY
}
prompt_values() {
# Set defaults first
set_defaults
if [[ "$HEADLESS" == true ]]; then
# Headless mode: just validate and proceed
validate_ctid
return
fi
# Interactive wizard mode
wizard_intro
# Show default settings
echo -e "${BOLD}Default Settings:${NC}"
show_settings
# Ask if user wants to modify
if confirm "Would you like to modify these settings?" "n"; then
echo ""
prompt_settings
fi
# Always prompt for auth key in interactive mode (if not already set)
if [[ -z "$AUTH_KEY" ]]; then
prompt_auth_key
fi
# Validate CTID
validate_ctid
# Show final summary and confirm
echo ""
echo -e "${BOLD}Final Configuration:${NC}"
show_settings
if ! confirm "Create container with these settings?"; then
echo ""
msg_info "Cancelled by user"
exit 0
fi
echo ""
}
get_template() {
local template_storage="$1"
local template_file
# Find the latest debian-12-standard template
template_file=$(pveam list "$template_storage" 2>/dev/null | grep -E "debian-12-standard.*tar\.(gz|zst)" | tail -1 | awk '{print $1}')
if [[ -z "$template_file" ]]; then
msg_info "Downloading Debian 12 template..."
pveam update >/dev/null 2>&1 || true
# Get available template name
local available_template
available_template=$(pveam available -section system 2>/dev/null | grep -E "debian-12-standard" | tail -1 | awk '{print $2}')
if [[ -z "$available_template" ]]; then
msg_error "Could not find Debian 12 template"
exit 1
fi
pveam download "$template_storage" "$available_template"
template_file=$(pveam list "$template_storage" 2>/dev/null | grep -E "debian-12-standard.*tar\.(gz|zst)" | tail -1 | awk '{print $1}')
fi
echo "$template_file"
}
create_container() {
local template="$1"
msg_info "Creating container $CTID..."
pct create "$CTID" "$template" \
--hostname "$HOSTNAME" \
--memory "$MEMORY" \
--cores 1 \
--rootfs "${STORAGE}:${DISK}" \
--net0 name=eth0,bridge=vmbr0,ip=dhcp \
--unprivileged 1 \
--features nesting=1,keyctl=1 \
--onboot 1 \
--start 0
msg_ok "Container created"
}
configure_tun() {
local conf="/etc/pve/lxc/${CTID}.conf"
msg_info "Configuring TUN device access..."
# Add TUN device access if not already present
if ! grep -q "lxc.cgroup2.devices.allow: c 10:200 rwm" "$conf" 2>/dev/null; then
echo "lxc.cgroup2.devices.allow: c 10:200 rwm" >> "$conf"
fi
if ! grep -q "lxc.mount.entry: /dev/net/tun" "$conf" 2>/dev/null; then
echo "lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file" >> "$conf"
fi
msg_ok "TUN device configured"
}
start_container() {
msg_info "Starting container..."
pct start "$CTID"
# Wait for container to be fully up
local max_wait=30
local waited=0
while [[ $waited -lt $max_wait ]]; do
if pct exec "$CTID" -- test -f /etc/os-release 2>/dev/null; then
break
fi
sleep 1
((waited++))
done
if [[ $waited -ge $max_wait ]]; then
msg_error "Container failed to start properly"
exit 1
fi
# Wait for network
waited=0
while [[ $waited -lt $max_wait ]]; do
if pct exec "$CTID" -- ping -c1 1.1.1.1 &>/dev/null; then
break
fi
sleep 1
((waited++))
done
msg_ok "Container started"
}
install_tailscale() {
msg_info "Installing Tailscale..."
pct exec "$CTID" -- bash -c '
set -e
export DEBIAN_FRONTEND=noninteractive
# Get OS info
ID=$(grep "^ID=" /etc/os-release | cut -d"=" -f2)
VER=$(grep "^VERSION_CODENAME=" /etc/os-release | cut -d"=" -f2)
# Install prerequisites
apt-get update -qq
apt-get install -y -qq curl gnupg ethtool >/dev/null
# Add Tailscale repo
curl -fsSL "https://pkgs.tailscale.com/stable/${ID}/${VER}.noarmor.gpg" \
| tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.tailscale.com/stable/${ID} ${VER} main" \
> /etc/apt/sources.list.d/tailscale.list
# Install Tailscale
apt-get update -qq
apt-get install -y -qq tailscale >/dev/null
# Enable and start tailscaled
systemctl enable tailscaled >/dev/null 2>&1
systemctl start tailscaled
'
msg_ok "Tailscale installed"
}
configure_ip_forwarding() {
msg_info "Configuring IP forwarding for exit node support..."
pct exec "$CTID" -- bash -c '
# Enable IP forwarding
cat > /etc/sysctl.d/99-tailscale.conf << EOF
# Enable IP forwarding for Tailscale exit node / subnet router
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
EOF
sysctl -p /etc/sysctl.d/99-tailscale.conf >/dev/null
'
msg_ok "IP forwarding enabled"
}
configure_udp_gro() {
msg_info "Configuring UDP GRO forwarding..."
pct exec "$CTID" -- bash -c '
# Apply immediately
ethtool -K eth0 rx-udp-gro-forwarding on 2>/dev/null || true
ethtool -K eth0 rx-gro-list off 2>/dev/null || true
# Make persistent via networkd-dispatcher or interfaces
if [[ -d /etc/networkd-dispatcher/routable.d ]]; then
cat > /etc/networkd-dispatcher/routable.d/50-tailscale-gro << "EOF"
#!/bin/bash
ethtool -K eth0 rx-udp-gro-forwarding on
ethtool -K eth0 rx-gro-list off
EOF
chmod +x /etc/networkd-dispatcher/routable.d/50-tailscale-gro
fi
'
msg_ok "UDP GRO forwarding configured"
}
authenticate_tailscale() {
if [[ -n "$AUTH_KEY" ]]; then
msg_info "Authenticating with Tailscale..."
pct exec "$CTID" -- tailscale up --auth-key="$AUTH_KEY"
msg_ok "Tailscale authenticated"
fi
}
add_proxmox_tag() {
local current_tags
current_tags=$(pct config "$CTID" | awk -F': ' '/^tags:/ {print $2}')
if [[ -n "$current_tags" ]]; then
pct set "$CTID" -tags "${current_tags};tailscale"
else
pct set "$CTID" -tags "tailscale"
fi
}
print_summary() {
echo ""
echo -e "${GREEN}${BOLD}═══════════════════════════════════════════════════════════${NC}"
echo -e "${GREEN}${BOLD} Container created successfully!${NC}"
echo -e "${GREEN}${BOLD}═══════════════════════════════════════════════════════════${NC}"
echo ""
echo -e " ${BOLD}Container ID:${NC} $CTID"
echo -e " ${BOLD}Hostname:${NC} $HOSTNAME"
echo -e " ${BOLD}Storage:${NC} $STORAGE"
echo -e " ${BOLD}Memory:${NC} ${MEMORY}MB"
echo -e " ${BOLD}Disk:${NC} ${DISK}GB"
echo ""
if [[ -z "$AUTH_KEY" ]]; then
echo -e "${YELLOW}${BOLD}Next Steps:${NC}"
echo ""
echo " 1. Authenticate with Tailscale:"
echo -e " ${CYAN}pct exec $CTID -- tailscale up${NC}"
echo ""
else
echo -e "${YELLOW}${BOLD}Tailscale Status:${NC}"
echo ""
pct exec "$CTID" -- tailscale status 2>/dev/null || true
echo ""
fi
echo -e "${YELLOW}${BOLD}Enable as Exit Node:${NC}"
echo ""
echo " 1. Advertise as exit node:"
echo -e " ${CYAN}pct exec $CTID -- tailscale up --advertise-exit-node${NC}"
echo ""
echo " 2. Approve in Tailscale admin console:"
echo -e " ${CYAN}https://login.tailscale.com/admin/machines${NC}"
echo " Find the machine → Edit route settings → Enable 'Use as exit node'"
echo ""
echo -e "${YELLOW}${BOLD}Enable as Subnet Router:${NC}"
echo ""
echo " Advertise routes (replace with your subnet):"
echo -e " ${CYAN}pct exec $CTID -- tailscale up --advertise-routes=192.168.1.0/24${NC}"
echo ""
echo -e "${YELLOW}${BOLD}Combined (Exit Node + Subnet Router):${NC}"
echo ""
echo -e " ${CYAN}pct exec $CTID -- tailscale up --advertise-exit-node --advertise-routes=192.168.1.0/24${NC}"
echo ""
}
main() {
banner
check_root
check_proxmox
parse_args "$@"
prompt_values
local template_storage template
template_storage=$(detect_template_storage)
template=$(get_template "$template_storage")
create_container "$template"
configure_tun
start_container
install_tailscale
configure_ip_forwarding
configure_udp_gro
authenticate_tailscale
add_proxmox_tag
print_summary
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment