win-server-deploy
Pack TermLink server into a self-contained zip for Windows deployment, install/uninstall as a background service using pm2, and manage the running server. Use when packaging the server for another Win
SKILL.mdskills/win-server-deploy/SKILL.md
GitHubWindows Server Deploy
Use this skill to package the TermLink Node.js server into a portable zip and deploy it as a Windows background service.
Why Not Docker
node-pty requires native Windows conpty access for PowerShell/CMD terminals. Docker runs Linux containers and cannot provide Windows PTY, so the Win server must be deployed natively.
Prerequisites
- Build machine (this machine):
npm installalready done - Target machine: Node.js installed and available in
PATH - Target machine: Administrator PowerShell for install/uninstall and elevated-mode operations
pm2can be missing initially;install-service.ps1installs it globally when needed
Privilege Modes
Configure .env before install:
| Variable | Purpose |
|---|---|
PORT |
Listener port used by health checks and deploy guidance |
AUTH_ENABLED, AUTH_USER, AUTH_PASS |
BasicAuth protection |
TERMLINK_PRIVILEGE_MODE |
standard or elevated |
TERMLINK_ELEVATED_ENABLE |
Allows elevated mode when set to true |
TERMLINK_ELEVATED_AUDIT_PATH |
Elevated audit log path |
SESSION_* |
Session persistence and retention |
For TERMLINK_PRIVILEGE_MODE=elevated, the deployed process must run with administrator privileges, use non-default credentials, and keep the audit log writable. This is why the skill uses Windows Task Scheduler instead of pm2-windows-startup.
Pack
Create a self-contained zip with pruned node_modules (excludes @capacitor, xterm, nodemon — not needed on server):
powershell -ExecutionPolicy Bypass -File ./.codex/skills/win-server-deploy/scripts/pack-win-server.ps1
Output: dist/termlink-win-<timestamp>.zip
The zip contains:
src/— server sourcepublic/— web frontend assetsnode_modules/— pruned production dependencies (with pre-builtnode-pty)ecosystem.config.js— pm2 process config.env.example— environment configuration templatedeploy-scripts/— install/uninstall/start scripts pluspm2-admin-startup.cmddata/,logs/— empty runtime directories
Deploy on Target Machine
1. Extract
# Right-click zip → Extract All, or:
Expand-Archive termlink-win-*.zip -DestinationPath C:\TermLink
2. Configure
cd C:\TermLink
Copy-Item .env.example .env
notepad .env
Review at least:
| Variable | Default | Description |
|---|---|---|
AUTH_USER |
admin |
BasicAuth username |
AUTH_PASS |
see .env.example |
BasicAuth password |
PORT |
repo default from .env.example |
Listen port |
TERMLINK_PRIVILEGE_MODE |
standard |
Set elevated only when admin runtime is required |
TERMLINK_ELEVATED_ENABLE |
false |
Must be true when elevated mode is enabled |
3. Install Service (as Administrator)
powershell -ExecutionPolicy Bypass -File .\deploy-scripts\install-service.ps1
This automatically:
- Installs
pm2globally - Removes legacy
pm2-windows-startupRun entries when found - Creates scheduled task
PM2-Termlink-Admin - Starts TermLink through
pm2in fork mode - Saves the PM2 process list
- Verifies
/api/healthusing configured auth when needed - Refuses to reset PM2 if the current Windows user already hosts non-TermLink PM2 apps
4. Verify
pm2 list
pm2 logs termlink --lines 50 --nostream
curl -u <AUTH_USER>:<AUTH_PASS> http://localhost:<PORT>/api/health
Daily Management
pm2 list
pm2 restart termlink # Restart
pm2 stop termlink # Stop
pm2 start termlink # Start
pm2 logs termlink # View logs
pm2 flush termlink # Clear logs
pm2 save # Persist current process list
Run these from an Administrator terminal when the deployment uses elevated mode.
Auto-Start Strategy
Do not rely on pm2-windows-startup for elevated deployments. The skill installs a scheduled task named PM2-Termlink-Admin that:
- Runs at user logon with a 10-second delay
- Uses Highest privileges
- Executes
deploy-scripts\pm2-admin-startup.cmd
That startup script waits for the system to settle, refuses to proceed if other PM2 apps are present, resets the daemon, waits for shutdown to finish, then runs pm2 start ecosystem.config.js and pm2 save so the PM2 daemon inherits administrator rights correctly.
Important: Elevated startup assumes this Windows user is dedicated to TermLink's PM2 workload. If you already manage other PM2 apps under the same user profile, move TermLink to a separate user or keep it in
standardprivilege mode.
Uninstall
powershell -ExecutionPolicy Bypass -File .\deploy-scripts\uninstall-service.ps1
The script removes the TermLink PM2 process and can optionally remove the PM2-Termlink-Admin scheduled task.
Quick Test (No Service Install)
For local testing without pm2, just run directly:
cd C:\TermLink
node src/server.js
Rules
- Always exclude
@capacitor/*from server packages (contains Android DEX files with paths exceeding Windows MAX_PATH 260 limit). - Use
robocopy(notCopy-Item) when copyingnode_modulesto handle any remaining long paths. - The zip includes pre-compiled
node-ptynative bindings — the target machine does not need Python, Visual C++ Build Tools, or node-gyp. - pm2 must run in
forkmode (notcluster) becausenode-ptydoes not support cluster mode. - Include
deploy-scripts\pm2-admin-startup.cmdin packaged output. - Never reintroduce
pm2-windows-startup/pm2-startupas the auto-start mechanism for elevated deployments. - Do not share the same Windows user with unrelated PM2 apps when using elevated scheduled-task startup.