Standing Order Agent / MVP deployment
MVP deployment

Docker on the VPS. Chrome on the user’s computer.

The deployable prototype runs with Docker Compose while the future browser worker reaches a dedicated local Chrome profile through a tightly constrained reverse SSH tunnel.

2always-on services
1private bridge
1reverse tunnel
0public CDP ports
Topology

One outbound tunnel connects the two trust zones

The user’s computer initiates SSH to the VPS. Browser control traffic crosses the encrypted tunnel; Stop & Shop traffic originates from the local Chrome session.

Docker VPS to local Chrome tunnel
Docker VPS to local Chrome tunnel
Compose creates a fixed private bridge. OpenSSH listens only on its gateway, forwarding CDP traffic to loopback on the local computer. The Chrome profile is dedicated to this prototype.
Deploy

The current prototype is container-ready

VPS

cd mvp
cp .env.docker.example .env
# set POSTGRES_PASSWORD
docker compose build
docker compose up -d dashboard postgres
docker compose ps

The dashboard binds to 127.0.0.1:3000 by default. Put a TLS reverse proxy in front of it or use an SSH local forward.

Local Mac

./scripts/start-local-chrome-macos.sh
export VPS_HOST=<vps-host>
./scripts/open-chrome-tunnel.sh

Use the dedicated profile to sign in and complete MFA. Start Compose first so the private bridge address exists.

DOC
Copy-paste runbook

VPS user creation, SSH restrictions, upgrade commands, failure states, and security controls are in MVP_DOCKER_DEPLOYMENT.md.

Compose

Runtime contract for the prototype and target MVP

ComponentNowTarget implementation
dashboardBuilds the separate prototype-dashboard/ project into a standalone Node 22 imageReplaced by Nuxt web, Node API, and worker commands from the MVP workspaces
postgresHealthy persistent service; not yet consumed by the simulated UIStores preferences, products, schedules, order cycles, jobs, and audit
chrome-checkManual tools profile validates the tunnel from the Compose networkWorker health signal and browser-provider readiness gate
standing-order networkFixed 172.30.0.0/24 bridge with 172.30.0.1 gatewayPrivate CDP entrypoint; subnet remains configurable
Tunnel

Constrain SSH to one reverse listener

ssh -N -T   -o ExitOnForwardFailure=yes   -o ServerAliveInterval=30   -o ServerAliveCountMax=3   -R 172.30.0.1:9223:127.0.0.1:9222   chrome-tunnel@VPS_HOST

Server policy

Dedicated non-admin user, key-only authentication, remote forwarding only, GatewayPorts clientspecified, no PTY, no agent forwarding, and no X11 forwarding.

Key policy

restrict,port-forwarding,permitlisten="172.30.0.1:9223" limits the dedicated key to the single listener used by Compose.

!
CDP is equivalent to browser control

Never use 0.0.0.0, a VPS public IP, the user’s everyday Chrome profile, or a shared SSH key. A party that reaches this endpoint can inspect and control the signed-in browser.

Operations

Offline is a visible workflow state

ConditionSystem actionDashboard
Offline before runDo not start browser work; optionally wait for a bounded grace periodLocal browser offline · reconnect Chrome and SSH
Disconnect before writePause with no cart mutationNo cart changes were made
Disconnect after writeRe-read retailer state before considering any retryVerifying retailer state
Unknown resultNever repeat blindly; require user verificationManual verification required
docker compose --profile tools run --rm chrome-check
Decisions

Deployment questions still to answer

1

VPS baseline

Which Linux distribution, CPU architecture, SSH port, domain, and reverse proxy?

2

Local availability

Can the Mac remain awake and online during both weekly preparation windows?

3

Network collision

Is 172.30.0.0/24 free across Docker, VPN, and VPS networks?

4

Tunnel lifecycle

Manual start for the prototype or automatic restart with launchd?

5

Grace period

Skip an offline run immediately or wait up to a defined limit?

6

Fallback

Local Chrome only, or a separately approved managed-browser fallback?