Posts in category “Tips”

WSL2 Won't Run on EC2 Windows Server? Use WSL1

Most EC2 Windows Server instances don't expose nested virtualization to the guest OS. WSL2 requires Hyper-V extensions, so it simply won't start. WSL1 works fine — it's a translation layer, not a VM.

Enable the WSL feature and reboot in an Admin powershell window:

Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
Restart-Computer

After reboot, pin the default version to 1:

wsl --set-default-version 1

On Windows Server, Add-AppxPackage is often broken or unavailable, so the standard wsl --install route fails. Use wsl --import with a rootfs tarball instead:

Now use a non-admin powershell:

mkdir $HOME\WSL
mkdir $HOME\WSL\Ubuntu

Then:

wsl --import Ubuntu $HOME\WSL\Ubuntu .\ubuntu.tar.gz --version 1

What you lose with WSL1: no Docker, no real Linux kernel, no systemd, weaker filesystem compatibility. Fine for CLI tooling, scripting, and build environments. If you need a real kernel, spin up a native Linux EC2 instance instead.

WezTerm stealing Alt+Enter? Here's the fix

WezTerm binds Alt+Enter to toggle fullscreen by default. That hijacks Alt+Enter newline in Claude Code, GitHub Copilot, and other terminal-based tools.

Drop this in ~/.wezterm.lua to disable the default and remap fullscreen to Ctrl+Shift+F11:

local wezterm = require 'wezterm'
local config = wezterm.config_builder()

config.keys = {
  {
    key = 'Enter',
    mods = 'ALT',
    action = wezterm.action.DisableDefaultAssignment,
  },
  {
    key = 'F11',
    mods = 'CTRL|SHIFT',
    action = wezterm.action.ToggleFullScreen,
  },
}

return config

Config takes effect immediately on save — no restart needed.

Stop opening admin cmd just to mklink — git-bash can do real symlinks

If you've been alt-tabbing to an admin cmd window to run mklink every time you wanted a symlink on Windows, there's a much cleaner way nobody seems to mention. Two settings, set them once, forget about it.

The reason ln -s in git-bash silently turns into cp by default is two unrelated barriers stacked together:

  1. Windows non-admins can't create symlinks unless Developer Mode is on.
  2. MSYS (git-bash's runtime) doesn't even try to create native symlinks without the MSYS env var set.

Fix the first once with admin, fix the second in your shell profile.

# Run once in admin PowerShell, or use Settings → Update & Security → For developers → Developer Mode
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" `
  -Name "AllowDevelopmentWithoutDevLicense" -Value 1 -Type DWord
# In ~/.bashrc
export MSYS=winsymlinks:nativestrict

nativestrict makes failures loud — ln -s errors out instead of silently copying when symlinks aren't supported. Avoid winsymlinks:native (the lenient sibling) — its silent fallback is exactly the trap you're trying to escape. Avoid winsymlinks:lnk entirely; .lnk shortcuts aren't symlinks anything else recognizes.

Open a new git-bash window and verify:

ln -s ~/.bashrc /tmp/test-link
ls -la /tmp/test-link

If the line starts with l, it's a real symlink that git, Linux tools, GNU stow, and your dotfiles install.sh all treat consistently across platforms. If it starts with -, either the env var didn't reach the new shell or Developer Mode didn't actually toggle.

Bonus: Developer Mode also unlocks Windows 11's native sudo command, so you can stop alt-tabbing to admin terminals for quick one-offs entirely.

WT keeps opening as Administrator? Check settings.json before the registry

Your Windows Terminal default tab is opening with admin privileges and you don't remember asking for it. The intuitive guess is the AppCompat Layers registry — that's where ticking "Run as administrator" on a shortcut's compatibility tab gets stored, and it persists across reinstalls. Worth checking, but it's the second place to look for WT.

The first place is settings.json:

{
    "commandline": "C:\\Program Files\\Git\\bin\\bash.exe",
    "elevate": true,
    "guid": "{17c3a2bf-...}",
    "name": "Git Bash"
}

WT 1.18+ added elevate as a per-profile flag. When it's true and that profile is also pointed to by defaultProfile, every new window silently opens elevated — no UAC prompt at the tab level because the elevation happened at WT launch. Delete the line, restart WT, done.

If you still want an admin tab on demand, add a second profile with a fresh GUID and a different name (e.g. "Git Bash (Admin)") that keeps elevate: true. You get a dropdown choice and a real UAC prompt when you actually need it, instead of unconditional elevation on every launch.

To rule out the registry side as well:

Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers"
Get-ItemProperty -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers"

Each property name is an exe path; a value containing RUNASADMIN means that program is forced to elevate every launch. To clear one, prefer the GUI — right-click the exe → Properties → Compatibility → uncheck "Run this program as administrator" — over editing the registry by hand.

Two mechanisms, same symptom, different layers. For Windows Terminal specifically, the per-profile setting wins; check it first.

Cloning an EC2 Instance: Three Ways

AWS console offers three ways to duplicate an EC2 instance, differing in whether disk data is carried over.

Create AMI (recommended, full clone) — preserves the system disk, installed software, and all configuration.

In the EC2 console, select the target instance → Actions → Image and templates → Create image. Wait for the AMI status to become available (a few minutes to tens of minutes), then go to AMIs → select it → Launch instance from AMI. Adjust instance type, subnet, Security Group as needed.

Launch More Like This (fastest, no data) — copies only instance configuration (type, SG, subnet, tags). The system disk is brand new.

Actions → Image and templates → Launch more like this. The Launch page opens with config pre-filled; confirm and launch. Good for stateless instances, e.g. web servers initialized via userdata.

Launch Template — if the original instance had a Launch Template saved, launch directly from it. EC2 → Launch Templates → select template → Actions → Launch instance from template.

Use AMI for most cases. Use Launch More Like This when you only need the same specs with a clean disk.