Skip to content

Instantly share code, notes, and snippets.

@erosika
Last active February 15, 2026 14:57
Show Gist options
  • Select an option

  • Save erosika/0830563e5d5b984609956866e83412da to your computer and use it in GitHub Desktop.

Select an option

Save erosika/0830563e5d5b984609956866e83412da to your computer and use it in GitHub Desktop.
ThinkPad Ubuntu post-install setup script
#!/bin/bash
set -euo pipefail
echo "=== ThinkPad Post-Install Setup ==="
echo ""
# System update
echo "[1/14] Updating system..."
sudo apt update && sudo apt upgrade -y
# Essential packages
echo "[2/14] Installing essential packages..."
sudo apt install -y \
git curl wget build-essential \
docker.io docker-compose \
ufw openssh-server \
htop tmux jq unzip
# Add current user to docker group
echo "[3/14] Adding $USER to docker group..."
sudo usermod -aG docker $USER
# Enable SSH
echo "[4/14] Enabling SSH..."
sudo systemctl enable --now ssh
# Firewall — allow SSH, block everything else on public interface
echo "[5/14] Configuring firewall..."
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 3000/tcp # Gitea web
sudo ufw allow 8384/tcp # Syncthing web UI
echo "y" | sudo ufw enable
# Install Bun
echo "[6/14] Installing Bun..."
curl -fsSL https://bun.sh/install | bash
export BUN_INSTALL="$HOME/.bun"
export PATH="$BUN_INSTALL/bin:$PATH"
# Install Node 22
echo "[7/14] Installing Node 22..."
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs
# Install Claude Code
echo "[8/14] Installing Claude Code..."
npm install -g @anthropic-ai/claude-code
# Install Tailscale
echo "[9/14] Installing Tailscale & Mullvad..."
curl -fsSL https://tailscale.com/install.sh | sh
# Install Mullvad
wget -qO- https://repository.mullvad.net/deb/mullvad-keyring.asc | sudo tee /usr/share/keyrings/mullvad-keyring.asc > /dev/null
echo "deb [signed-by=/usr/share/keyrings/mullvad-keyring.asc] https://repository.mullvad.net/deb/stable $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/mullvad.list
sudo apt update && sudo apt install -y mullvad-vpn
# Install Syncthing
echo "[10/14] Installing Syncthing..."
sudo apt install -y syncthing
systemctl --user enable syncthing
systemctl --user start syncthing
# Install Obsidian
echo "[11/14] Installing Obsidian..."
wget -qO /tmp/obsidian.deb "https://github.com/obsidianmd/obsidian-releases/releases/download/v1.7.7/obsidian_1.7.7_amd64.deb"
sudo dpkg -i /tmp/obsidian.deb || sudo apt install -f -y
rm /tmp/obsidian.deb
# Set up Gitea
echo "[12/14] Setting up Gitea..."
sudo mkdir -p /opt/gitea
sudo chown $USER:$USER /opt/gitea
cat > /opt/gitea/docker-compose.yml <<'COMPOSE'
version: "3"
services:
gitea:
image: gitea/gitea:latest
container_name: gitea
environment:
- USER_UID=1000
- USER_GID=1000
restart: always
volumes:
- ./data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "2222:22"
COMPOSE
# Start Gitea (needs docker group — use sudo for first run)
sudo docker-compose -f /opt/gitea/docker-compose.yml up -d
# Clone and build Companion
echo "[13/14] Setting up The Companion..."
sudo mkdir -p /opt/companion
sudo chown $USER:$USER /opt/companion
git clone https://github.com/The-Vibe-Company/companion.git /opt/companion
cd /opt/companion/web
$BUN_INSTALL/bin/bun install
$BUN_INSTALL/bin/bun run build
# Create systemd services
echo "[14/14] Creating systemd services..."
# Gitea service is managed by Docker's restart policy (already set to always)
# Companion systemd service
sudo tee /etc/systemd/system/companion.service > /dev/null <<SERVICE
[Unit]
Description=The Companion - Claude Code Web UI
After=network.target
[Service]
Type=simple
User=$USER
WorkingDirectory=/opt/companion/web
ExecStart=$BUN_INSTALL/bin/bun server/index.ts
Restart=on-failure
Environment=NODE_ENV=production
[Install]
WantedBy=multi-user.target
SERVICE
sudo systemctl daemon-reload
sudo systemctl enable companion
sudo systemctl start companion
echo ""
echo "=== Setup complete ==="
echo ""
echo "Next steps:"
echo " 1. Log out and back in (for docker group)"
echo " 2. Run: sudo tailscale up --ssh"
echo " 3. Run: claude auth login"
echo " 4. Set up Syncthing: open http://localhost:8384"
echo " - Share Obsidian vault from Mac (ThinkPad = receive only)"
echo " 5. Open Obsidian, enable CLI in settings"
echo " 6. Set up Gitea: open http://localhost:3000"
echo " - Create admin account (erosika username)"
echo " - Create org 'erosika', repo 'cosmania'"
echo " - Generate per-agent access tokens"
echo " 7. Verify Companion: http://localhost:3456"
echo " (or from Mac: http://thinkpad.tailnet:3456)"
echo ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment