Skip to content

Instantly share code, notes, and snippets.

@ericlewis
Last active November 28, 2025 20:15
Show Gist options
  • Select an option

  • Save ericlewis/e1e2c12040c1fb07cd205c63ca8a2fc6 to your computer and use it in GitHub Desktop.

Select an option

Save ericlewis/e1e2c12040c1fb07cd205c63ca8a2fc6 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
set -euo pipefail
echo "=== Caddy + Tailscale TLS Installer ==="
# ---------------------------------------
# 0. Prechecks
# ---------------------------------------
if ! command -v tailscale >/dev/null 2>&1; then
echo "ERROR: Tailscale is not installed or not authenticated."
exit 1
fi
sudo apt update
sudo apt install -y jq
# ---------------------------------------
# 1. Detect fully qualified MagicDNS domain
# ---------------------------------------
TS_HOSTNAME=$(hostname)
TS_TAILNET=$(tailscale status --json | jq -r '.MagicDNSSuffix')
FQDN="${TS_HOSTNAME}.${TS_TAILNET}"
echo "Detected hostname: ${TS_HOSTNAME}"
echo "Detected tailnet: ${TS_TAILNET}"
echo "Detected FQDN: ${FQDN}"
echo
CERT_DIR="/var/lib/tailscale/certs"
CERT_CRT="${CERT_DIR}/${FQDN}.crt"
CERT_KEY="${CERT_DIR}/${FQDN}.key"
# ---------------------------------------
# 2. Install official Go (ARM64)
# ---------------------------------------
echo "[1] Installing official Go (ARM64)"
GO_VERSION="1.25.4"
# Remove any existing Go installs
sudo rm -rf /usr/local/go
sudo apt purge -y golang-go golang 2>/dev/null || true
wget -q "https://go.dev/dl/go${GO_VERSION}.linux-arm64.tar.gz"
sudo tar -C /usr/local -xzf "go${GO_VERSION}.linux-arm64.tar.gz"
# Add Go to PATH system-wide
sudo tee /etc/profile.d/go-path.sh >/dev/null <<EOF
export PATH=\$PATH:/usr/local/go/bin
EOF
# Apply PATH for current shell
source /etc/profile.d/go-path.sh
echo "Installed Go version: $(go version)"
echo
# ---------------------------------------
# 3. Install xcaddy
# ---------------------------------------
echo "[2] Installing xcaddy builder"
XCADDY_VERSION="0.4.5"
if ! command -v xcaddy >/dev/null 2>&1; then
wget -q "https://github.com/caddyserver/xcaddy/releases/download/v${XCADDY_VERSION}/xcaddy_${XCADDY_VERSION}_linux_arm64.tar.gz"
tar -xzf "xcaddy_${XCADDY_VERSION}_linux_arm64.tar.gz"
sudo mv xcaddy /usr/local/bin/
sudo chmod +x /usr/local/bin/xcaddy
fi
echo "xcaddy version: $(xcaddy version)"
echo
# ---------------------------------------
# 4. Build latest Caddy
# ---------------------------------------
echo "[3] Building latest Caddy with xcaddy"
xcaddy build
sudo mv caddy /usr/bin/caddy
sudo setcap cap_net_bind_service=+ep /usr/bin/caddy
echo "Installed Caddy version: $(caddy version)"
echo
# ---------------------------------------
# 5. Create caddy system user
# ---------------------------------------
echo "[4] Creating caddy user"
sudo useradd --system --home /var/lib/caddy --shell /usr/sbin/nologin caddy 2>/dev/null || true
sudo mkdir -p /etc/caddy
sudo chown -R caddy:caddy /etc/caddy
# ---------------------------------------
# 6. Install systemd service
# ---------------------------------------
echo "[5] Installing systemd service at /etc/systemd/system/caddy.service"
sudo tee /etc/systemd/system/caddy.service >/dev/null <<EOF
[Unit]
Description=Caddy Web Server (Custom Build)
After=network.target
[Service]
Type=notify
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile --force
User=caddy
Group=caddy
AmbientCapabilities=CAP_NET_BIND_SERVICE
LimitNOFILE=1048576
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
# ---------------------------------------
# 7. Ensure TLS certificate exists and is readable
# ---------------------------------------
echo "[6] Ensuring Tailscale certificate for ${FQDN}"
sudo mkdir -p "${CERT_DIR}"
# Directory traversal permissions (keys still protected by file mode)
sudo chmod 755 /var/lib/tailscale
sudo chmod 755 /var/lib/tailscale/certs
if [[ ! -f "${CERT_CRT}" || ! -f "${CERT_KEY}" ]]; then
echo "No certificate found. Requesting new Tailscale certificate..."
sudo tailscale cert "${FQDN}"
else
echo "Certificate files already exist."
fi
# Ensure Caddy can read the private key
sudo chgrp caddy "${CERT_KEY}"
sudo chmod 640 "${CERT_KEY}"
# ---------------------------------------
# 8. Write Caddyfile
# ---------------------------------------
echo "[7] Writing /etc/caddy/Caddyfile"
sudo tee /etc/caddy/Caddyfile >/dev/null <<EOF
{
# Global options can go here
}
${FQDN} {
tls ${CERT_CRT} ${CERT_KEY}
reverse_proxy localhost:8000
}
:80 {
root * /usr/share/caddy
file_server
}
EOF
sudo chown caddy:caddy /etc/caddy/Caddyfile
sudo caddy fmt --overwrite /etc/caddy/Caddyfile
# ---------------------------------------
# 9. Start & enable Caddy
# ---------------------------------------
echo "[8] Starting Caddy"
sudo systemctl daemon-reload
sudo systemctl enable --now caddy
sudo systemctl status caddy --no-pager
echo
echo "==================================================================="
echo "Caddy installation complete for:"
echo " ${FQDN}"
echo
echo "Tailscale certificate files:"
echo " ${CERT_CRT}"
echo " ${CERT_KEY}"
echo
echo "Certificates auto-renew via tailscaled."
echo "Backend currently set to: localhost:8000"
echo "Edit /etc/caddy/Caddyfile to change upstream."
echo "==================================================================="
#!/usr/bin/env bash
set -euo pipefail
INNER_HOME="/root/.cache/huggingface"
docker run -it --rm \
--gpus all \
--net=host \
--name=ray-head \
--shm-size=16g \
--ulimit memlock=-1 --ulimit stack=67108864 \
--device=/dev/infiniband \
-v "${HF_HOME}:${INNER_HOME}" \
-e HF_HOME="${INNER_HOME}" \
storage.local:5000/ericlewisplease/vllm:latest bash
@ericlewis
Copy link
Author

set -euo pipefail
ray start --head --dashboard-host=0.0.0.0 --node-ip-address="'${HEAD_IP}'"
mkdir -p /tmp/ray
export RAY_ADDRESS="127.0.0.1:6379"
vllm serve openai/gpt-oss-120b \
  --download-dir /root/.cache/huggingface \
  --gpu-memory-utilization 0.92 \
  --max-model-len 8192 \
  --safetensors-load-strategy eager \
  --max-num-batched-tokens 1K \
  --max-num-seqs 128 \
  --async-scheduling

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment