1{2 "app": "qc26",3 "label": "QC26 — L'élection québécoise 2026, en données",4 "domain": "www.qc26.ca",5 "port": 8200,6 "health_path": "/healthz",7 "dir": "~/apps/qc26",8 "extra_paths": [],9 "sync_excludes": [10 "engine/.venv/",11 "__pycache__/",12 ".pytest_cache/",13 ".ruff_cache/",14 "*.egg-info/",15 ".git/",16 "web/node_modules/",17 "web/.next/",18 "engine/logs/",19 "logs/",20 ".DS_Store"21 ],22 "requires": {23 "runtimes": ["pm2", "ngrok", "node", "pnpm", "uv", "uv-python@3.12"],24 "ram_gb": 4,25 "ports": [8200, 8201]26 },27 "ram_mb_observed": 1200,28 "size_mb": 120,29 "placement": {30 "pin": null,31 "prefer": "M3U96a",32 "avoid": ["M3U96b", "M1M32"],33 "reason": "Monte Carlo numpy + build Next.js : cœurs et RAM ; uv-py3.12 + pnpm présents ; M3U96b réservé hfmarketdata"34 },35 "processes": [36 {37 "name": "qc26-engine",38 "manager": "pm2",39 "script": "{{HOME}}/apps/qc26/engine/.venv/bin/python",40 "args": ["-m", "uvicorn", "qc26.main:app", "--host", "127.0.0.1", "--port", "8201", "--no-access-log"],41 "interpreter": null,42 "cwd": "{{HOME}}/apps/qc26/engine",43 "env": {44 "QC26_ENVIRONMENT": "production",45 "QC26_PORT": "8201",46 "QC26_PUBLIC_URL": "https://www.qc26.ca",47 "QC26_ADMIN_TOKEN": "qc26-admin-2026-Kp8vT3nQ7zLw",48 "QC26_FIRECRAWL_API_KEY": "fc-8cc44cb683044aee82e8cbad6505a01a",49 "QC26_ANTHROPIC_API_KEY": "__SET_AT_DEPLOY__",50 "QC26_LLM_MODEL": "claude-opus-5",51 "QC26_N_SIMULATIONS": "20000",52 "PYTHONUNBUFFERED": "1"53 },54 "cron_restart": null,55 "autorestart": true,56 "max_memory_restart": "3G"57 },58 {59 "name": "qc26-web",60 "manager": "pm2",61 "script": "/opt/homebrew/bin/node",62 "args": ["node_modules/next/dist/bin/next", "start", "-p", "8200", "-H", "0.0.0.0"],63 "interpreter": null,64 "cwd": "{{HOME}}/apps/qc26/web",65 "env": {66 "NODE_ENV": "production",67 "QC26_ENGINE_URL": "http://127.0.0.1:8201",68 "NEXT_PUBLIC_SITE_URL": "https://www.qc26.ca",69 "NEXT_TELEMETRY_DISABLED": "1"70 },71 "cron_restart": null,72 "autorestart": true,73 "max_memory_restart": "1500M"74 }75 ],76 "ngrok": {77 "name": "qc26-ngrok",78 "url": "www.qc26.ca",79 "port": 820080 },81 "launchd": [],82 "env_overrides": {},83 "hooks": {84 "post_sync": [85 "export PATH=\"$HOME/.local/bin:/opt/homebrew/bin:$PATH\"; cd engine && (test -x .venv/bin/python || uv venv --python 3.12 .venv) && uv pip install -q --python .venv/bin/python -e . && echo ' engine deps ok'",86 "export PATH=\"/opt/homebrew/bin:$PATH\"; cd web && pnpm install --frozen-lockfile --silent && echo ' web deps ok'",87 "export PATH=\"/opt/homebrew/bin:$PATH\"; cd web && QC26_ENGINE_URL=http://127.0.0.1:8201 NEXT_PUBLIC_SITE_URL=https://www.qc26.ca NEXT_TELEMETRY_DISABLED=1 pnpm build 2>&1 | tail -3 && echo ' web build ok'",88 "mkdir -p engine/data/archive/polls engine/data/archive/documents engine/data/archive/live engine/data/cache engine/logs && echo ' data ok'"89 ],90 "post_start": []91 }92}93