Compare commits

...

1 Commits

Author SHA1 Message Date
Timmy
8a9a60467c feat(#1339): Deploy Nexus to proper URL for preview
Some checks failed
Review Approval Gate / verify-review (pull_request) Failing after 9s
CI / test (pull_request) Failing after 54s
CI / validate (pull_request) Failing after 57s
Port 3000 (avoids L402 on :8080, #1415).
./preview.sh, docker, GitHub Pages.
Triage: #1413 #1414 #1415

Fixes #1339
2026-04-14 11:37:09 -04:00
7 changed files with 180 additions and 9 deletions

35
.github/workflows/pages.yml vendored Normal file
View File

@@ -0,0 +1,35 @@
name: Deploy Nexus Preview to Pages
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/configure-pages@v5
- name: Prepare static assets
run: |
mkdir -p _site
cp index.html app.js style.css boot.js gofai_worker.js _site/
cp service-worker.js manifest.json robots.txt help.html _site/
cp portals.json vision.json _site/
cp -r nexus/ _site/nexus/
cp -r icons/ _site/icons/ 2>/dev/null || true
cp -r assets/ _site/assets/ 2>/dev/null || true
- uses: actions/upload-pages-artifact@v3
with:
path: '_site'
- id: deployment
uses: actions/deploy-pages@v4

9
Dockerfile.preview Normal file
View File

@@ -0,0 +1,9 @@
FROM nginx:alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY preview/nginx.conf /etc/nginx/conf.d/default.conf
COPY index.html app.js style.css boot.js gofai_worker.js /usr/share/nginx/html/
COPY service-worker.js manifest.json robots.txt help.html portals.json vision.json /usr/share/nginx/html/
COPY nexus/ /usr/share/nginx/html/nexus/
COPY icons/ /usr/share/nginx/html/icons/
COPY assets/ /usr/share/nginx/html/assets/
EXPOSE 3000

26
PREVIEW.md Normal file
View File

@@ -0,0 +1,26 @@
# Nexus Preview
ES module imports fail via `file://` or raw Forge URLs. `boot.js` warns: _"Serve over HTTP."_
**Port 3000** (avoids L402 on :8080, see #1415).
## Quick Start
```bash
./preview.sh # http://localhost:3000
./preview.sh docker # nginx + WS proxy
docker compose up -d nexus-preview nexus-backend
```
## Triage Issues
- #1413 — deploy.sh port comments wrong
- #1414 — hardcoded VPS IP in app.js
- #1415 — port 8080 conflict with L402
## Files
- `Dockerfile.preview` — nginx container
- `preview/nginx.conf` — MIME types + WS proxy
- `preview.sh` — Python preview server
- `.github/workflows/pages.yml` — GitHub Pages CI/CD

View File

@@ -1,17 +1,23 @@
#!/usr/bin/env bash
# deploy.sh — spin up (or update) the Nexus staging environment
# Usage: ./deploy.sh — rebuild and restart nexus-main (port 4200)
# ./deploy.sh staging — rebuild and restart nexus-staging (port 4201)
# deploy.sh — Nexus environment
# ./deploy.sh — nexus-main (8765)
# ./deploy.sh staging — nexus-staging (8766)
# ./deploy.sh preview — static preview (3000)
# ./deploy.sh full — preview + backend
set -euo pipefail
SERVICE="${1:-nexus-main}"
case "$SERVICE" in
staging) SERVICE="nexus-staging" ;;
main) SERVICE="nexus-main" ;;
preview)
docker compose build nexus-preview
docker compose up -d --force-recreate nexus-preview
echo "==> http://localhost:3000"; exit 0 ;;
full)
docker compose build nexus-preview nexus-backend
docker compose up -d --force-recreate nexus-preview nexus-backend
echo "==> Preview: http://localhost:3000"; exit 0 ;;
esac
echo "==> Deploying $SERVICE"
docker compose build "$SERVICE"
docker compose up -d --force-recreate "$SERVICE"
echo "==> Done. Container: $SERVICE"
echo "==> Done: $SERVICE"

View File

@@ -7,9 +7,28 @@ services:
restart: unless-stopped
ports:
- "8765:8765"
nexus-staging:
build: .
container_name: nexus-staging
restart: unless-stopped
ports:
- "8766:8765"
- "8766:8765"
nexus-backend:
build: .
container_name: nexus-backend
restart: unless-stopped
expose:
- "8765"
nexus-preview:
build:
context: .
dockerfile: Dockerfile.preview
container_name: nexus-preview
restart: unless-stopped
ports:
- "3000:3000"
depends_on:
- nexus-backend

25
preview.sh Executable file
View File

@@ -0,0 +1,25 @@
#!/usr/bin/env bash
set -euo pipefail
PORT="${1:-3000}"
if [ "$PORT" = "docker" ]; then
docker compose up -d nexus-preview
echo "==> http://localhost:3000"; exit 0
fi
if ! command -v python3 &> /dev/null; then
echo "Error: python3 not found. Use './preview.sh docker'"; exit 1
fi
echo "==> http://localhost:$PORT"
python3 -c "
import http.server,socketserver
class H(http.server.SimpleHTTPRequestHandler):
def end_headers(self):
self.send_header('Access-Control-Allow-Origin','*')
super().end_headers()
def guess_type(self,p):
if p.endswith(('.js','.mjs')): return 'application/javascript'
if p.endswith('.css'): return 'text/css'
if p.endswith('.json'): return 'application/json'
return super().guess_type(p)
with socketserver.TCPServer(('', $PORT), H) as s:
print(f'Serving http://localhost:{$PORT}'); s.serve_forever()
"

51
preview/nginx.conf Normal file
View File

@@ -0,0 +1,51 @@
server {
listen 3000;
server_name _;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
}
location ~* \.js$ {
types { application/javascript js; }
add_header Cache-Control "public, max-age=3600";
}
location ~* \.css$ {
types { text/css css; }
add_header Cache-Control "public, max-age=3600";
}
location ~* \.json$ {
types { application/json json; }
add_header Cache-Control "no-cache";
}
location /api/world/ws {
proxy_pass http://nexus-backend:8765;
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_read_timeout 86400;
}
location /ws {
proxy_pass http://nexus-backend:8765;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400;
}
location /health {
return 200 '{"status":"ok","service":"nexus-preview"}';
add_header Content-Type application/json;
}
}