Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 

Repository files navigation

>_ Web Terminal

A browser-based SSH terminal built with NuxtJS — access your Linux server from any browser, anywhere, without installing anything.

image

✨ Features

  • Multiple tabs — open several terminal sessions simultaneously, just like Windows Terminal
  • Full terminal emulation — colors, cursor movement, scrollback, ANSI support via xterm.js
  • Real-time connection — WebSocket-based communication with zero latency
  • Status bar — live connection status, server IP, port, uptime timer, and latency
  • PWA support — installable as a desktop/mobile app
  • Keyboard shortcutsCtrl+T new tab, Ctrl+W close tab

🛠 Tech Stack

Layer Technology
Frontend NuxtJS 3, Vue 3, xterm.js, xterm-addon-fit
Backend Nitro (Nuxt server), Socket.io, ssh2
Process manager pm2
HTTPS Cloudflare Tunnel
Server Hetzner VPS — Ubuntu 26.04 LTS

🏗 Architecture

Browser (xterm.js)
      │
      │  WebSocket (Socket.io)
      │
Nuxt Backend (Node.js / Nitro)
      │
      │  SSH (ssh2 library)
      │
Linux Server (bash shell)

The browser renders the terminal UI and sends keystrokes via WebSocket. The Nuxt server bridges the connection to the actual SSH session. All SSH credentials stay on the server — never exposed to the browser.

🚀 Getting Started

Prerequisites

  • Node.js 20+
  • A Linux server with SSH access
  • SSH key pair

1. Clone the repository

git clone https://github.com/yourusername/webterminal.git
cd webterminal

2. Install dependencies

npm install

3. Generate an SSH key (if you don't have one)

# On Linux/Mac
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519
 
# On Windows PowerShell
ssh-keygen -t ed25519 -f C:\Users\YourName\.ssh\id_ed25519

4. Add your public key to the server

# Linux/Mac
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@your-server-ip
 
# Windows PowerShell
type C:\Users\YourName\.ssh\id_ed25519.pub | ssh root@your-server-ip "cat >> ~/.ssh/authorized_keys"

5. Configure environment variables

Create a .env file in the project root:

# Your server IP or hostname
SSH_HOST=your-server-ip
 
# SSH port (default: 22)
SSH_PORT=22
 
# SSH username
SSH_USER=root
 
# Path to your private key (for local development)
SSH_PRIVATE_KEY_PATH=/path/to/.ssh/id_ed25519
 
# OR paste the raw key content (for cloud deployments like Vercel)
# SSH_PRIVATE_KEY=-----BEGIN OPENSSH PRIVATE KEY-----\n...\n-----END OPENSSH PRIVATE KEY-----

6. Run locally

npm run dev

Open http://localhost:3000 in your browser.

🌐 Deploying to a Server

Build the app

npm run build

Upload to your server

scp -r .output root@your-server-ip:/root/webterminal/

Set up environment variables on the server

ssh root@your-server-ip
nano /root/webterminal/.env

Paste:

SSH_HOST=127.0.0.1
SSH_PORT=22
SSH_USER=root
SSH_PRIVATE_KEY_PATH=/root/.ssh/id_ed25519

Start with pm2

export SSH_HOST=127.0.0.1
export SSH_PORT=22
export SSH_USER=root
export SSH_PRIVATE_KEY_PATH=/root/.ssh/id_ed25519
 
pm2 start /root/webterminal/.output/server/index.mjs --name webterminal
pm2 save
pm2 startup

Open the firewall port

ufw allow 3000

Your app is now live at http://your-server-ip:3000.

🔒 HTTPS with Cloudflare Tunnel (Free)

Get a free HTTPS URL without a domain:

# Install cloudflared
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 \
  -o /usr/local/bin/cloudflared
chmod +x /usr/local/bin/cloudflared
 
# Start tunnel with pm2
pm2 start /usr/local/bin/cloudflared \
  --name cloudflare-tunnel \
  -- tunnel --url http://localhost:3000
pm2 save
 
# Get your HTTPS URL
pm2 logs cloudflare-tunnel --lines 50 --nostream | grep trycloudflare

You'll get a free URL like https://random-words.trycloudflare.com.

⚙️ Environment Variables

Variable Required Description
SSH_HOST IP or hostname of the SSH target server
SSH_PORT SSH port (usually 22)
SSH_USER SSH username (e.g. root)
SSH_PRIVATE_KEY_PATH One of these Path to private key file (local dev)
SSH_PRIVATE_KEY One of these Raw private key content (cloud deploy)

🔐 Security

Warning: This app gives full shell access to your server. Take security seriously.

Recommended steps before sharing the URL:

  • Add a login page / password protection
  • Use HTTPS (Cloudflare Tunnel or Caddy)
  • Disable SSH password authentication on your server
  • Create a non-root user for the terminal session
  • Never commit .env or private keys to git
# Disable password SSH login (after confirming key works)
# In /etc/ssh/sshd_config:
PasswordAuthentication no
 
systemctl restart ssh

📁 Project Structure

webterminal/
├── app.vue                    # Main app — tab bar, layout
├── components/
│   └── TerminalTab.vue        # Individual terminal tab + xterm.js
├── server/
│   └── plugins/
│       └── socket.ts          # Socket.io server + SSH2 bridge
├── public/
│   └── terminal-icon.svg
├── nuxt.config.ts
├── package.json
└── .env                       # Never commit this!

📜 pm2 Commands

pm2 list                        # see all running processes
pm2 logs webterminal            # view live logs
pm2 restart webterminal         # restart the app
pm2 stop webterminal            # stop the app
pm2 monit                       # live monitoring dashboard

🤝 Contributing

Pull requests are welcome. For major changes, please open an issue first.

📄 License

MIT


Built with ❤️ using NuxtJS, Socket.io, ssh2, and xterm.js

About

A browser-based SSH terminal built with NuxtJS — access your Linux server from any browser, anywhere, without installing anything.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors