# Updates the existing 9hits-viewer Render service so one container runs # both 9Hits and FeelingSurf AT THE SAME TIME on the free 512 MB plan. # Do not rename this service — a different Blueprint name would create a # second deployment instead of updating # https://dashboard.render.com/web/srv-da09a7dbedkc73a829cg services: - type: web name: 9hits-viewer runtime: docker dockerfilePath: ./Dockerfile plan: free healthCheckPath: /health envVars: # 9Hits access key (hard-coded). FeelingSurf token preconfigured below. - key: ACCESS_KEY value: "23f9097a8d823267188c49b3cc0598b1" - key: ACCESS_TOKEN value: "27f77ef00e768cdbdc7352f3456e35b5" - key: PORT value: "10000" # --- BOTH viewers, CONCURRENTLY, in 512 MB ----------------------------- # Measured with a real Chromium 149 (see README "Measured memory"): # LOW_MEMORY=extreme (both viewers --single-process) -> ~324 MB pair # 9Hits SP + FeelingSurf swiftshader (if SP crashes FS) -> ~458 MB # Both fit under the 512 MB budget, so the two viewers run at the same # time instead of alternating. Layers that make it safe: # 1. LOW_MEMORY=extreme shrinks both Chromiums hard. # 2. memguard.py watches total RSS (limit 512 MB, acts at 97% = 497 MB) # and restarts the heaviest viewer BEFORE the platform can OOM-kill # the container - a safety valve, not a scheduler. # 3. DUAL_VIEWER_MODE=concurrent = always run both, never time-slice. # 4. Crash auto-fallback: if a viewer crash-loops 3x at startup under # single-process, its SP flags are dropped automatically (it keeps # running on the balanced set; NH_SP/FS_SP=no force that manually). # If FeelingSurf specifically fails with swiftshader under SP, set # FS_GL_MODE=disable-gpu. - key: NINEHITS_ENABLED value: "yes" - key: FEELINGSURF_ENABLED value: "yes" - key: DUAL_VIEWER_MODE value: "concurrent" # both at the same time; auto escalates to time-slice - key: LOW_MEMORY value: "extreme" # balanced | extreme | auto | off - key: NH_SP value: "yes" # single-process for 9Hits (auto-fallback on crash) - key: FS_SP value: "yes" # single-process for FeelingSurf (auto-fallback on crash) - key: FS_GL_MODE value: "swiftshader" # swiftshader | disable-gpu (last resort) - key: MEMGUARD_LIMIT_MB value: "512" # Render free plan limit - key: MEMGUARD_HARD_PCT value: "97" # act at 497 MB so the platform OOM never fires - key: MEMGUARD_COOLDOWN value: "120" # min seconds between guardian restarts - key: CLEAR_ALL_SESSIONS value: "yes" - key: SYSTEM_SESSION value: "yes" - key: SESSION_NOTE value: "render-system" - key: NOTE value: "render" - key: HIDE_BROWSER value: "yes" - key: ALLOW_POPUPS value: "no" - key: ALLOW_ADULT value: "no" - key: ALLOW_CRYPTO value: "no" - key: CACHE_LIMIT value: "0" - key: RESET_INTERVAL value: "2h" - key: SUPERVISOR_DELAY value: "10"