2026-01-05 19:46:33 -08:00
|
|
|
# MacroPad Relay Server - Deployment Guide
|
|
|
|
|
|
|
|
|
|
## Cloud Node Container Deployment
|
|
|
|
|
|
|
|
|
|
For AnHonestHost cloud-node-container deployment:
|
|
|
|
|
|
|
|
|
|
### 1. Build Locally
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
cd /home/jknapp/code/macropad/macropad-relay
|
|
|
|
|
npm install
|
2026-07-17 10:15:23 -07:00
|
|
|
npm run build # required: the build is no longer triggered automatically on install
|
2026-01-05 19:46:33 -08:00
|
|
|
```
|
|
|
|
|
|
2026-07-17 10:15:23 -07:00
|
|
|
> Note: the `postinstall` build hook was removed. Always run `npm run build`
|
|
|
|
|
> explicitly (locally or in CI) after `npm install` to produce `dist/`.
|
|
|
|
|
|
2026-01-05 19:46:33 -08:00
|
|
|
### 2. Prepare Deployment Package
|
|
|
|
|
|
|
|
|
|
The build outputs to `dist/` with public files copied. Upload:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
# Upload built files to your node container app directory
|
|
|
|
|
rsync -avz --exclude 'node_modules' --exclude 'src' --exclude '.git' \
|
|
|
|
|
dist/ package.json public/ \
|
|
|
|
|
user@YOUR_SERVER:/path/to/app/
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 3. On Server
|
|
|
|
|
|
|
|
|
|
The cloud-node-container will automatically:
|
|
|
|
|
- Install dependencies from package.json
|
|
|
|
|
- Start the app using PM2
|
|
|
|
|
- Configure the process from package.json settings
|
|
|
|
|
|
|
|
|
|
### 4. Create Data Directory
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
mkdir -p /path/to/app/data
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Directory Structure on Server
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
app/
|
|
|
|
|
├── index.js # Main entry (compiled)
|
|
|
|
|
├── config.js
|
|
|
|
|
├── server.js
|
|
|
|
|
├── services/
|
|
|
|
|
├── handlers/
|
|
|
|
|
├── utils/
|
|
|
|
|
├── public/
|
|
|
|
|
│ ├── login.html
|
|
|
|
|
│ └── app.html
|
|
|
|
|
├── data/
|
|
|
|
|
│ └── sessions.json # Created automatically
|
|
|
|
|
└── package.json
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Update After Code Changes
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
# On local machine:
|
|
|
|
|
cd /home/jknapp/code/macropad/macropad-relay
|
|
|
|
|
npm run build
|
|
|
|
|
|
|
|
|
|
rsync -avz --exclude 'node_modules' --exclude 'src' --exclude '.git' --exclude 'data' \
|
|
|
|
|
dist/ package.json public/ \
|
|
|
|
|
user@YOUR_SERVER:/path/to/app/
|
|
|
|
|
|
|
|
|
|
# On server - restart via your container's control panel or:
|
|
|
|
|
pm2 restart macropad-relay
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Environment Variables
|
|
|
|
|
|
|
|
|
|
Set these in your container configuration:
|
|
|
|
|
|
|
|
|
|
- `PORT` - Server port (default: 3000)
|
|
|
|
|
- `DATA_DIR` - Data storage path (default: ./data)
|
|
|
|
|
- `NODE_ENV` - production or development
|
|
|
|
|
- `LOG_LEVEL` - info, debug, error
|
2026-07-17 18:13:33 -07:00
|
|
|
- `ALLOWED_ORIGINS` - Comma-separated list of allowed browser origins for the
|
|
|
|
|
WebSocket Origin check (e.g. `https://macropad.example.com`). **Set this to
|
|
|
|
|
your public origin(s) when running behind a reverse proxy** (see note below).
|
|
|
|
|
|
|
|
|
|
> **Reverse proxy note (`ALLOWED_ORIGINS`):** When `ALLOWED_ORIGINS` is unset,
|
|
|
|
|
> the WebSocket upgrade Origin check falls back to comparing the browser's
|
|
|
|
|
> `Origin` host against the raw `Host` header seen by the app. Behind a reverse
|
|
|
|
|
> proxy the internal `Host` (e.g. `localhost:3000`) often differs from the
|
|
|
|
|
> public origin the browser sends (e.g. `https://macropad.example.com`), so
|
|
|
|
|
> legitimate browser WebSocket upgrades get **rejected**. Set `ALLOWED_ORIGINS`
|
|
|
|
|
> to your public origin(s) to fix this. (Forwarding the public host via
|
|
|
|
|
> `proxy_set_header Host $host;`, as in the Nginx example below, also helps, but
|
|
|
|
|
> setting `ALLOWED_ORIGINS` explicitly is the reliable fix.)
|
2026-01-05 19:46:33 -08:00
|
|
|
|
|
|
|
|
## Test It Works
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
# Test health endpoint
|
|
|
|
|
curl http://localhost:3000/health
|
|
|
|
|
|
2026-07-17 10:15:23 -07:00
|
|
|
# Should return (counts only - no session ids are exposed):
|
|
|
|
|
# {"status":"ok","desktops":0,"webClients":0,"uptime":1.23}
|
2026-01-05 19:46:33 -08:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Nginx/Reverse Proxy (for HTTPS)
|
|
|
|
|
|
|
|
|
|
```nginx
|
|
|
|
|
location / {
|
|
|
|
|
proxy_pass http://localhost:3000;
|
|
|
|
|
proxy_http_version 1.1;
|
|
|
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
|
|
|
proxy_set_header Connection "upgrade";
|
|
|
|
|
proxy_set_header Host $host;
|
|
|
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
|
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
|
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
|
|
|
|
|
|
|
|
# WebSocket timeout (24 hours)
|
|
|
|
|
proxy_read_timeout 86400;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Troubleshooting
|
|
|
|
|
|
|
|
|
|
**Check logs:**
|
|
|
|
|
```bash
|
|
|
|
|
pm2 logs macropad-relay
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Check sessions:**
|
|
|
|
|
```bash
|
|
|
|
|
cat /path/to/app/data/sessions.json
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Port in use:**
|
|
|
|
|
```bash
|
|
|
|
|
lsof -i :3000
|
|
|
|
|
```
|