🚀 Alpine Linux Setup Guide - node222 (Hyper-V)

Hypervisor: Microsoft Hyper-V
VM Specs: 2 GB RAM, 4 vCPUs, 15 GB disk
Static IP: 192.168.1.211
Goal: Get Alpine installed and SSH-ready for VS Code Remote
Note: This guide uses DHCP during installation due to Hyper-V compatibility

Part 0: Prerequisites

Download Alpine Linux ISO

Recommended ISO: alpine-standard (not alpine-virt)
Why? The standard ISO includes proper networking tools and setup-alpine integration.
The alpine-virt ISO is meant for containers/cloud and lacks some VM setup features.

Download Links:

Verify Download (Optional but Recommended):

# Download SHA256 checksum file
# From: https://dl-cdn.alpinelinux.org/alpine/v3.22/releases/x86_64/alpine-standard-3.22.2-x86_64.iso.sha256

# In PowerShell, verify the checksum:
Get-FileHash alpine-standard-3.22.2-x86_64.iso -Algorithm SHA256
# Compare the hash with the official SHA256 file

Hyper-V VM Configuration:

✅ Once VM is created, attach the alpine-standard ISO and boot!

Part 1: Initial Alpine Installation

Step 1: Boot and Login

Alpine Linux VM boots to login prompt:
localhost login: root
(no password - just press Enter)

Step 2: Run Setup Wizard

setup-alpine

Step 3: Answer Setup Questions

Keyboard Layout:

Select keyboard layout: us
Select variant: us

Hostname:

Enter system hostname: node222

Network Interface:

IMPORTANT: Alpine Linux with Hyper-V requires DHCP during installation.
Static IP configuration causes DNS resolution failures. We'll convert to static IP (192.168.1.211) after setup is complete.
Which one do you want to initialize? eth0
Ip address for eth0? (dhcp/none/manual): dhcp
# Use DHCP for Hyper-V compatibility - static IP conversion happens in Step 18

Root Password:

New password: (choose a strong password)
Retype password: (same password)

Timezone:

Which timezone are you in? America/Los_Angeles
(or your timezone - use Tab to autocomplete)

Proxy:

HTTP/FTP proxy URL? none

NTP Client:

Which NTP client to run? chrony

APK Mirror:

Enter mirror number or URL: 1
(picks fastest mirror automatically)

User Setup:

Setup a user? (press Enter to skip - we'll do this later)

SSH Server:

Which SSH server? openssh
Allow root ssh login? no
(we'll use your user account with sudo instead)

Disk Setup:

Which disk(s) would you like to use? sda
How would you like to use it? sys
WARNING: This will erase all data on sda. Continue? y
✅ Installation completes!

Part 2: First Boot Configuration (Still Using DHCP)

Strategy: We'll do all setup while using DHCP, then convert to static IP as the final step.
This ensures everything works before we lock in the network configuration.

Step 4: Reboot and Login

reboot

After reboot:
node222 login: root
Password: (enter the root password you set during install)

Step 5: Configure Network Interface

Critical: Make sure you ejected the installation ISO before rebooting!
If you see "localhost" instead of "node222", you're booting from the ISO - shut down, eject it, and restart.
# Check if eth0 is UP
ip addr show eth0

# If eth0 is DOWN, run the network setup tool
setup-interfaces

# When prompted:
# Which interface? eth0
# IP address? dhcp
# Do you want to do any manual configuration? no

# Restart networking
rc-service networking restart

# Verify eth0 is now UP with DHCP address
ip addr show eth0
# Should show: inet 192.168.1.xxx/24 and state UP

# Test connectivity
ping -c 2 google.com
# Should work!

Step 6: Update System

# Now that network is up, update packages
apk update
apk upgrade

Step 7: Install Essential Packages

# Install all essential packages
apk add bash curl wget nano doas openssh
# Note: Use 'doas' instead of 'sudo' - it's Alpine's preferred tool

Step 8: Create Your User Account

adduser yourusername
# Enter password when prompted
# Accept defaults for Full Name, etc. (just press Enter)

# Add user to wheel group (doas access)
adduser yourusername wheel

# Configure doas for wheel group
echo "permit persist :wheel" > /etc/doas.d/doas.conf

# Test doas works
su - yourusername
doas apk update
# Enter your user password - should work!
# Note: 'persist' means password is cached for 5 minutes
exit
# Back to root

Part 3: Configure SSH for VS Code (Still Using DHCP)

Step 9: Enable SSH with Password Authentication (Temporarily)

Strategy: Hyper-V console doesn't support paste, so we can't add SSH keys yet.
Solution: Enable password auth first, SSH in from Windows, THEN add your keys.
We'll disable password auth in Step 18 after keys are working.
# Make sure SSH is running (it should be from setup-alpine)
rc-service sshd status

# If not running, start it
rc-service sshd start
rc-update add sshd

# Verify SSH config allows password auth (should be default)
grep PasswordAuthentication /etc/ssh/sshd_config
# If it says "no", edit the file:
# nano /etc/ssh/sshd_config
# Change to: PasswordAuthentication yes
# Then: rc-service sshd restart

Step 10: Get Your DHCP IP Address

# Get your current DHCP IP
ip addr show eth0 | grep "inet "
# Look for: inet 192.168.1.xxx/24
# Write down this IP address!

Step 11: Test SSH Connection with Password

Note: Use the DHCP IP address for now. After we convert to static IP (192.168.1.211),
you'll use that address instead.
# From your Windows PowerShell:
ssh ryanc@192.168.1.xxx  # Use the DHCP IP from Step 10
# Enter your user password when prompted
# Should connect! Don't exit yet - we'll add SSH keys now

Step 12: Add Your SSH Public Key (From SSH Session)

✅ Now you're in a proper SSH session and can paste!
# In your SSH session on node222:

# Create .ssh directory
mkdir -p ~/.ssh
chmod 700 ~/.ssh

# Create authorized_keys file
nano ~/.ssh/authorized_keys

# On Windows (in another PowerShell window), copy your public key:
# Get-Content C:\Users\ryanc\.ssh\id_ed25519.pub | Set-Clipboard
# OR the shorter version:
# cat ~/.ssh/id_ed25519.pub | clip

# Back in nano on node222:
# Paste your public key (Right-click in terminal, or Ctrl+Shift+V)
# Should be one long line starting with: ssh-ed25519 AAAA... or ssh-rsa AAAA...
# Save: Ctrl+O, Enter, Ctrl+X

# Set correct permissions
chmod 600 ~/.ssh/authorized_keys

# Verify the key was added
cat ~/.ssh/authorized_keys
# Should show your public key

Step 13: Test SSH Key Authentication

# Exit your current SSH session
exit

# From Windows, SSH in again:
ssh ryanc@192.168.1.xxx  # Same DHCP IP
# Should connect WITHOUT asking for password!
# If it asks for password, something's wrong with the key setup
✅ SSH keys working! Now we need to enable port forwarding for VS Code.

Step 13b: Enable TCP Port Forwarding for VS Code Remote-SSH

Required for VS Code: VS Code Remote-SSH needs TCP port forwarding enabled.
Alpine's default sshd config has this set to no - you must change it to yes.
# In your SSH session, edit SSH config
doas nano /etc/ssh/sshd_config

# Find this line (use Ctrl+W to search):
# AllowTcpForwarding no

# Change it to:
AllowTcpForwarding yes

# Save: Ctrl+O, Enter, Ctrl+X

# Restart SSH to apply changes
doas rc-service sshd restart

# Verify SSH restarted successfully
doas rc-service sshd status

Step 14: Configure Firewall (Optional but Recommended)

# In your SSH session, install iptables
doas apk add iptables iptables-openrc

# Create basic firewall rules - paste this entire block:
doas sh -c 'cat > /etc/iptables/rules-save << "EOF"
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p tcp --dport 22 -j ACCEPT
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
-A INPUT -p tcp --dport 11235 -j ACCEPT
-A INPUT -p icmp --icmp-type echo-request -j ACCEPT
COMMIT
EOF
'

# Apply firewall rules
doas /etc/init.d/iptables save
doas rc-update add iptables
doas rc-service iptables start

Step 15: Verify System is Ready

# In your SSH session, check everything
uname -a
# Should show: Linux node222 ... Alpine Linux

# Check installed packages
apk info | grep -E 'bash|curl|wget|nano|doas'

# Verify doas works
doas apk update

# Check SSH is running
doas rc-service sshd status

Part 4: Setup VS Code Remote-SSH (Using DHCP IP)

Step 16: On Your Laptop in VS Code

Install Extension:

  1. Open VS Code
  2. Go to Extensions (Ctrl+Shift+X)
  3. Search: "Remote - SSH"
  4. Install "Remote - SSH" by Microsoft

Configure SSH Connection:

Temporary IP: Use your DHCP IP for now. We'll update the SSH config to 192.168.1.211 after converting to static.
  1. Press F1 or Ctrl+Shift+P
  2. Type: "Remote-SSH: Connect to Host"
  3. Select "Add New SSH Host"
  4. Enter: ssh ryanc@192.168.1.xxx (use your current DHCP IP)
  5. Select SSH config file (usually C:\Users\ryanc\.ssh\config)

Connect:

  1. Press F1 again
  2. Type: "Remote-SSH: Connect to Host"
  3. Select your DHCP IP address (or ryanc@192.168.1.xxx)
  4. New VS Code window opens
  5. Trust the host (click "Continue")
  6. VS Code connects and installs server components (no password needed - using your SSH key!)
  7. You're in! Open folder: /home/ryanc
⚠️ Before connecting with VS Code:
Exit any active SSH sessions to node222 in your terminals first!
Type exit in any open SSH sessions before using VS Code Remote-SSH.

If connection still hangs at "Waiting for port forwarding to be ready":
VS Code Remote-SSH has compatibility issues with Alpine's musl libc. See troubleshooting below.

Step 16b: Install Extensions on Remote Host (Optional but Recommended)

Key Concept: VS Code extensions must be installed separately on remote hosts.
Extensions installed locally don't automatically work when connected via Remote-SSH.

Install GitHub Copilot (if you have it):

  1. While connected to node222 in VS Code
  2. Click Extensions icon (Ctrl+Shift+X)
  3. You'll see two sections: "LOCAL - INSTALLED" and "SSH: NODE222 - INSTALLED"
  4. Find "GitHub Copilot" in your local extensions
  5. Click the "Install in SSH: node222" button
  6. Wait for installation to complete

Install GitHub Copilot Chat (separate extension):

  1. Still in Extensions (Ctrl+Shift+X)
  2. Search for: "GitHub Copilot Chat"
  3. Find the extension by GitHub
  4. Click "Install in SSH: node222"
  5. After installation, you should see the chat icon in the sidebar
  6. Or press Ctrl+Alt+I for inline chat
✅ Extensions working! The gcompat package (from troubleshooting) enables Copilot's language server to run on Alpine's musl libc.

Other useful extensions to install remotely:

Tip: You can see which extensions are local-only vs remote-capable in the Extensions panel. Look for the "Install in SSH" button.

Part 5: Verify Everything Works

Step 17: In VS Code Connected to Alpine

Open terminal in VS Code (Ctrl+`):

# Check system
uname -a
# Should show: Linux node222 ... Alpine Linux

# Check memory
free -h
# Should show ~2 GB total

# Check disk
df -h
# Should show ~15 GB for /dev/sda*

# Test doas
doas apk update
# Should work without errors

# Test internet and DNS
ping -c 2 google.com
# Should work
✅ Everything working on DHCP! Now we can safely convert to static IP.

Part 6: Convert to Static IP (Final Step)

Step 18: Switch from DHCP to Static IP

Why now? Everything is installed and working. Converting to static IP is now safe,
and if anything goes wrong, you can easily troubleshoot from VS Code.
# In VS Code terminal connected to Alpine

# Edit network interfaces file
doas nano /etc/network/interfaces

# Change from DHCP to static - replace the eth0 section with:
auto eth0
iface eth0 inet static
    address 192.168.1.211
    netmask 255.255.255.0
    gateway 192.168.1.1

# Save (Ctrl+O, Enter, Ctrl+X)

# Update DNS configuration (make it persistent)
doas sh -c 'echo "nameserver 192.168.1.1" > /etc/resolv.conf'

# Restart networking service
doas rc-service networking restart

# Verify static IP is set
ip addr show eth0
# Should show: inet 192.168.1.211/24

# Test connectivity
ping -c 2 192.168.1.1      # Gateway
ping -c 2 8.8.8.8          # Internet
ping -c 2 google.com       # DNS resolution

Step 19: Update VS Code SSH Config

Note: Your current VS Code connection will disconnect when networking restarts.
This is normal! Just reconnect using the new static IP.

On your Windows laptop, edit SSH config:

# Open: C:\Users\ryanc\.ssh\config
# Change the old DHCP IP to the static IP:

Host node222
    HostName 192.168.1.211
    User ryanc
    IdentityFile ~/.ssh/id_ed25519  # (or your key file)

Reconnect VS Code:

  1. Press F1
  2. Type: "Remote-SSH: Connect to Host"
  3. Select node222 (or 192.168.1.211)
  4. VS Code connects to the static IP using your SSH key
  5. Test terminal commands to verify everything works

Step 20: Disable Password Authentication (Security Hardening)

Only do this after confirming SSH key authentication works on static IP!
Test that you can SSH in and use VS Code Remote-SSH before disabling passwords.
# In VS Code terminal connected to node222 via static IP

# Edit SSH config
doas nano /etc/ssh/sshd_config

# Find and change this line:
PasswordAuthentication no

# Save (Ctrl+O, Enter, Ctrl+X) and restart SSH
doas rc-service sshd restart

# Test one more time from Windows to confirm keys still work:
# Exit VS Code, close connection
# ssh ryanc@192.168.1.211
# Should connect WITHOUT password!

✅ COMPLETE SETUP DONE!

You now have:

Troubleshooting

Issue: VS Code Remote-SSH Hangs at "Waiting for port forwarding"

Symptom: VS Code window opens but hangs with "Waiting for port forwarding to be ready"
Cause: Alpine uses musl libc, but VS Code Remote server expects glibc
Solution: Install glibc compatibility layer
# SSH into node222 from PowerShell
ssh ryanc@192.168.1.xxx

# Install gcompat (glibc compatibility for Alpine)
doas apk add gcompat libstdc++

# Exit SSH session
exit

# Back in VS Code:
# 1. Close the hung VS Code window
# 2. Press F1 → "Remote-SSH: Kill VS Code Server on Host"
# 3. Select your host (ryanc@192.168.1.xxx)
# 4. Try connecting again - should work now!

Alternative: Use SSH terminal instead of VS Code Remote-SSH

If VS Code Remote-SSH continues to have issues, you can still use VS Code to edit files locally and just SSH in for testing. Or use the integrated terminal in VS Code with a regular SSH connection.

Issue: Network Not Working After Reboot (alpine-virt ISO)

Symptom: eth0 is DOWN, /etc/network/interfaces doesn't exist
Cause: You're using alpine-virt ISO instead of alpine-standard
Solution: Create the network configuration manually
# Create the network interfaces file from scratch
cat > /etc/network/interfaces << 'EOF'
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp
EOF

# Verify the file was created correctly
cat /etc/network/interfaces

# Start networking service
rc-service networking start

# Enable networking to start on boot
rc-update add networking boot

# Verify eth0 is now UP
ip addr show eth0

Recommendation: Use alpine-standard ISO to avoid this issue entirely.

Hyper-V Specific Notes

Why DHCP during installation?

Hyper-V has a known compatibility issue with Alpine Linux when using static IP configuration during the setup-alpine wizard. The network interface initialization timing causes DNS resolution to fail, preventing APK mirror access. Using DHCP allows Hyper-V to properly initialize the network stack, then we safely convert to static IP after installation completes.

Network Configuration Order:

  1. During Installation: Use DHCP (Step 3)
  2. After First Boot: Start networking service and do all setup on DHCP (Steps 4-15)
  3. Final Step: Convert to static IP when everything works (Step 16)
  4. Verify: Test gateway, internet, and DNS resolution

Why setup before static IP?

By doing all configuration while using DHCP, we ensure packages install correctly, SSH works, and VS Code connects successfully. Only after confirming everything works do we convert to static IP. This approach minimizes risk and makes troubleshooting easier.

If SSH Issues Occur:

# Check SSH service status
rc-service sshd status

# Verify SSH is listening on port 22
netstat -tlnp | grep :22

# Check authorized_keys permissions
ls -la ~/.ssh/authorized_keys
# Should be: -rw------- (600)

# Temporarily enable password auth for testing (if needed)
doas nano /etc/ssh/sshd_config
# Set: PasswordAuthentication yes
doas rc-service sshd restart

Quick Reference Commands

Category Command Description
System doas apk update Update package list
System doas apk upgrade Upgrade packages
System doas apk add packagename Install package
System doas reboot Reboot system
Service doas rc-service sshd restart Restart SSH
Service doas rc-service sshd status Check SSH status
Network ip addr show Show IP addresses
Network ping 8.8.8.8 Test internet
Firewall doas iptables -L -n -v List firewall rules

Appendix: Node201 nginx Configuration Reference

For reference when migrating to node222, here's the complete nginx configuration from node201 (Windows):

📄 Full Configuration File: nginx.conf.txt
Purpose: Reference for BBS proxy configuration and all domain/subdomain setups
Note: Alpine paths will be different (e.g., /etc/nginx/ instead of C:/node/nginx/)

Key Configuration Sections to Reference:

Alpine-specific adaptations needed: