# ๐Ÿณ Docker Guide โ€” OmniRoute (แžแŸ’แž˜แŸ‚แžš) ๐ŸŒ **Languages:** ๐Ÿ‡บ๐Ÿ‡ธ [English](../../../../guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ช๐Ÿ‡น [am](../../../am/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ธ๐Ÿ‡ฆ [ar](../../../ar/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฆ๐Ÿ‡ฟ [az](../../../az/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ง๐Ÿ‡ฌ [bg](../../../bg/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ง๐Ÿ‡ฉ [bn](../../../bn/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ง๐Ÿ‡ฆ [bs](../../../bs/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡จ๐Ÿ‡ฟ [cs](../../../cs/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฉ๐Ÿ‡ฐ [da](../../../da/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฉ๐Ÿ‡ช [de](../../../de/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฌ๐Ÿ‡ท [el](../../../el/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ช๐Ÿ‡ธ [es](../../../es/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ช๐Ÿ‡ช [et](../../../et/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฎ๐Ÿ‡ท [fa](../../../fa/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ซ๐Ÿ‡ฎ [fi](../../../fi/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ซ๐Ÿ‡ท [fr](../../../fr/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฎ๐Ÿ‡ช [ga](../../../ga/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฎ๐Ÿ‡ณ [gu](../../../gu/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ณ๐Ÿ‡ฌ [ha](../../../ha/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฎ๐Ÿ‡ฑ [he](../../../he/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฎ๐Ÿ‡ณ [hi](../../../hi/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ญ๐Ÿ‡ท [hr](../../../hr/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ญ๐Ÿ‡บ [hu](../../../hu/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฆ๐Ÿ‡ฒ [hy](../../../hy/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฎ๐Ÿ‡ฉ [id](../../../id/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ณ๐Ÿ‡ฌ [ig](../../../ig/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฎ๐Ÿ‡น [it](../../../it/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฏ๐Ÿ‡ต [ja](../../../ja/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฌ๐Ÿ‡ช [ka](../../../ka/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฎ๐Ÿ‡ณ [kn](../../../kn/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฐ๐Ÿ‡ท [ko](../../../ko/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฑ๐Ÿ‡น [lt](../../../lt/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฑ๐Ÿ‡ป [lv](../../../lv/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฎ๐Ÿ‡ณ [ml](../../../ml/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฎ๐Ÿ‡ณ [mr](../../../mr/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฒ๐Ÿ‡พ [ms](../../../ms/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฒ๐Ÿ‡น [mt](../../../mt/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฒ๐Ÿ‡ฒ [my](../../../my/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ณ๐Ÿ‡ต [ne](../../../ne/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ณ๐Ÿ‡ฑ [nl](../../../nl/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ณ๐Ÿ‡ด [no](../../../no/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฎ๐Ÿ‡ณ [or](../../../or/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฎ๐Ÿ‡ณ [pa](../../../pa/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ต๐Ÿ‡ญ [phi](../../../phi/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ต๐Ÿ‡ฑ [pl](../../../pl/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ต๐Ÿ‡น [pt](../../../pt/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ง๐Ÿ‡ท [pt-BR](../../../pt-BR/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ท๐Ÿ‡ด [ro](../../../ro/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ท๐Ÿ‡บ [ru](../../../ru/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฑ๐Ÿ‡ฐ [si](../../../si/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ธ๐Ÿ‡ฐ [sk](../../../sk/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ธ๐Ÿ‡ฎ [sl](../../../sl/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ท๐Ÿ‡ธ [sr](../../../sr/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ธ๐Ÿ‡ช [sv](../../../sv/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฐ๐Ÿ‡ช [sw](../../../sw/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฎ๐Ÿ‡ณ [ta](../../../ta/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ฎ๐Ÿ‡ณ [te](../../../te/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡น๐Ÿ‡ญ [th](../../../th/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡น๐Ÿ‡ท [tr](../../../tr/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡บ๐Ÿ‡ฆ [uk-UA](../../../uk-UA/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ต๐Ÿ‡ฐ [ur](../../../ur/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡บ๐Ÿ‡ฟ [uz](../../../uz/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ป๐Ÿ‡ณ [vi](../../../vi/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡ณ๐Ÿ‡ฌ [yo](../../../yo/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡จ๐Ÿ‡ณ [zh-CN](../../../zh-CN/docs/guides/DOCKER_GUIDE.md) ยท ๐Ÿ‡น๐Ÿ‡ผ [zh-TW](../../../zh-TW/docs/guides/DOCKER_GUIDE.md) --- > แžฏแž€แžŸแžถแžšแž™แŸ„แž„แž–แŸแž‰แž›แŸแž‰แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แžถแžšแžŠแžถแž€แŸ‹แžฑแŸ’แž™แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž‡แžถแž˜แžฝแž™ DockerแŸ” แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แžถแžšแž…แžถแž”แŸ‹แž•แŸ’แžŠแžพแž˜แžšแž แŸแžŸ แžŸแžผแž˜แž˜แžพแž› [แž•แŸ’แž“แŸ‚แž€ Docker แž€แŸ’แž“แžปแž„ README](../README.md#-docker)แŸ” ## แž˜แžถแžแžทแž€แžถ - [แžŠแŸ†แžŽแžพแžšแž€แžถแžšแžšแž แŸแžŸ](#quick-run) - [แž‡แžถแž˜แžฝแž™แžฏแž€แžŸแžถแžšแž”แžšแžทแžŸแŸ’แžแžถแž“](#with-environment-file) - [Docker Compose](#docker-compose) - [Profiles แžŠแŸ‚แž›แž˜แžถแž“](#available-profiles) - [แž€แžถแžšแž€แŸ†แžŽแžแŸ‹แžšแž…แž“แžถแžŸแž˜แŸ’แž–แŸแž“แŸ’แž’แžงแž”แž€แžšแžŽแŸ CLI แž›แžพ host แž“แŸ…แž–แŸแž› OmniRoute แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž€แŸ’แž“แžปแž„ Docker](#configuring-host-cli-tools-when-omniroute-runs-in-docker) - [Redis Sidecar](#redis-sidecar) - [Compose แžŸแž˜แŸ’แžšแžถแž”แŸ‹ Production](#production-compose) - [แžŠแŸ†แžŽแžถแž€แŸ‹แž€แžถแž› Dockerfile](#dockerfile-stages) - [แžขแžแŸแžšแž”แžšแžทแžŸแŸ’แžแžถแž“แžŸแŸ†แžแžถแž“แŸ‹แŸ—](#critical-environment-variables) - [Docker Compose แž‡แžถแž˜แžฝแž™ Caddy (HTTPS)](#docker-compose-with-caddy-https-auto-tls) - [Cloudflare Quick Tunnel](#cloudflare-quick-tunnel) - [Image Tags](#image-tags) - [แž€แžถแžšแžขแžถแž”แŸ‹แžŠแŸแž Dashboard แž€แŸ’แž“แžปแž„ Docker](#dashboard-updates-in-docker) - [แž›แž‘แŸ’แž’แž—แžถแž–แž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹แŸ– SQLite แž›แŸ†แž“แžถแŸ†แžŠแžพแž˜แž‚แžถแŸ†แž‘แŸ’แžš replica แžแŸ‚แž˜แžฝแž™](#availability-default-sqlite-is-single-replica) - [แž€แŸ†แž แžปแžŸแžแžถแž˜แžแŸ†แž”แž“แŸ‹แžšแž”แžŸแŸ‹ Gemini แž€แŸ’แž“แžปแž„ Docker](#gemini-regional-errors-inside-docker) - [แž…แŸ†แžŽแžถแŸ†แžŸแŸ†แžแžถแž“แŸ‹แŸ—](#important-notes) --- ## แžŠแŸ†แžŽแžพแžšแž€แžถแžšแžšแž แŸแžŸ > **แž…แž„แŸ‹ self-host แžŠแŸ„แž™แž”แŸ’แžšแžพแžแŸ‚ command แž˜แžฝแž™แž˜แŸ‚แž“แž‘แŸ?** แžŸแžผแž˜แž˜แžพแž› > [แž˜แž‚แŸ’แž‚แžปแž‘แŸ’แž‘แŸแžŸแž€แŸ Self-Host](../getting-started/SELF_HOST_GUIDE.md) โ€” > `docker compose -f docker-compose.selfhost.yml up -d` (image แžŠแŸ‚แž›แž”แžถแž“แž”แŸ„แŸ‡แž–แžปแž˜แŸ’แž–แž•แŸ’แžŸแžถแž™ + > Redis, แžŸแž˜แŸ’แžšแžถแž”แŸ‹แžแŸ‚ loopback, แž˜แžทแž“แž…แžถแŸ†แž”แžถแž…แŸ‹แž‡แŸ’แžšแžพแžŸ profile)แŸ” Quick Run แžแžถแž„แž€แŸ’แžšแŸ„แž˜แž‚แžบแž‡แžถ > แžœแžทแž’แžธแž”แŸ’แžšแžพ container แžแŸ‚แž˜แžฝแž™ แžŸแž˜แŸ’แžšแžถแž”แŸ‹แžขแŸ’แž“แž€แž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹แžŠแŸ‚แž›แž€แŸ†แž–แžปแž„แžŠแŸ†แžŽแžพแžšแž€แžถแžš Redis แž“แŸ…แž€แž“แŸ’แž›แŸ‚แž„แž•แŸ’แžŸแŸแž„แžšแžฝแž…แž แžพแž™แŸ” ```bash docker run -d \ --name omniroute \ --restart unless-stopped \ --stop-timeout 40 \ -p 20128:20128 \ -v omniroute-data:/app/data \ diegosouzapw/omniroute:latest ``` ## แž‡แžถแž˜แžฝแž™แžฏแž€แžŸแžถแžšแž”แžšแžทแžŸแŸ’แžแžถแž“ ```bash # แž‡แžถแžŠแŸ†แž”แžผแž„ แžŸแžผแž˜แž…แž˜แŸ’แž›แž„ แž“แžทแž„แž€แŸ‚แžŸแž˜แŸ’แžšแžฝแž› .env cp .env.example .env docker run -d \ --name omniroute \ --restart unless-stopped \ --stop-timeout 40 \ --env-file .env \ -p 20128:20128 \ -v omniroute-data:/app/data \ diegosouzapw/omniroute:latest ``` ## Docker Compose ```bash # Profile แž˜แžผแž›แžŠแŸ’แž‹แžถแž“ (แž‚แŸ’แž˜แžถแž“แžงแž”แž€แžšแžŽแŸ CLI) docker compose --profile base up -d # Profile CLI (แž˜แžถแž“ Claude Code, Codex แž“แžทแž„ OpenClaw แž—แŸ’แž‡แžถแž”แŸ‹แž˜แž€แž‡แžถแž˜แžฝแž™) docker compose --profile cli up -d # Profile host (แž•แŸ’แžแŸ„แžแž›แžพ Linux แž‡แžถแž…แž˜แŸ’แž”แž„; mount CLI binaries แžšแž”แžŸแŸ‹ host แž‡แžถ read-only) docker compose --profile host up -d # Profile Web (Chromium/Playwright แžŸแž˜แŸ’แžšแžถแž”แŸ‹ providers แžŠแŸ‚แž›แž”แŸ’แžšแžพ web-session) docker compose --profile web up -d # แž•แŸ’แžŸแŸ† CLI + CLIProxyAPI sidecar docker compose --profile cli --profile cliproxyapi up -d ``` ## Profiles แžŠแŸ‚แž›แž˜แžถแž“ OmniRoute แž•แŸ’แžŠแž›แŸ‹แž‡แžผแž“ Compose profiles แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž‘แž˜แŸ’แžšแž„แŸ‹แžŸแŸ†แžแžถแž“แŸ‹แŸ—แž“แŸƒแž€แžถแžšแžŠแžถแž€แŸ‹แžฑแŸ’แž™แžŠแŸ†แžŽแžพแžšแž€แžถแžšแŸ” แžŸแžผแž˜แž‡แŸ’แžšแžพแžŸแžšแžพแžŸแž˜แžฝแž™แžŠแŸ‚แž›แžแŸ’แžšแžผแžœแž“แžนแž„แž”แžšแžทแžŸแŸ’แžแžถแž“แžšแž”แžŸแŸ‹แžขแŸ’แž“แž€แŸ” | Profile | Service | แž–แŸแž›แžŠแŸ‚แž›แž‚แžฝแžšแž”แŸ’แžšแžพ | Command | | ----------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | | `base` (แž›แŸ†แž“แžถแŸ†แžŠแžพแž˜) | `omniroute-base` | Server แžŠแŸ‚แž›แž‚แŸ’แž˜แžถแž“ UI / runtime แžขแž”แŸ’แž”แž”แžšแž˜แžถ แž“แžทแž„แž˜แžทแž“แž˜แžถแž“ provider CLIs แž—แŸ’แž‡แžถแž”แŸ‹แž˜แž€แž‡แžถแž˜แžฝแž™ | `docker compose --profile base up -d` | | `cli` | `omniroute-cli` | แž›แŸ†แž แžผแžšแž€แžถแžšแž„แžถแžšแž”แŸ‚แž” agentic แžŠแŸ‚แž›แž แŸ… `omniroute providers/setup/doctor` แž“แžทแž„ CLIs แžŠแŸ‚แž›แž—แŸ’แž‡แžถแž”แŸ‹แž˜แž€แž‡แžถแž˜แžฝแž™ (Codex, Claude Code, Droid, OpenClaw) | `docker compose --profile cli up -d` | | `host` | `omniroute-host` | Linux hosts แžŠแŸ‚แž›แž…แž„แŸ‹แž”แžถแž“แžŸแžทแž‘แŸ’แž’แžทแž…แžผแž›แž”แŸ’แžšแžพ host CLIs แžŸแŸ’แžšแžŠแŸ€แž„ `network_mode` แžŠแŸ„แž™ mount `~/.local/bin`, `~/.codex`, `~/.claude` แž‡แžถแžŠแžพแž˜ แž€แŸ’แž“แžปแž„แžšแž”แŸ€แž” read-only | `docker compose --profile host up -d` | | `cliproxyapi` | `cliproxyapi` | แžŠแŸ†แžŽแžพแžšแž€แžถแžš [CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI) sidecar แž›แžพ port `8317` แžŸแž˜แŸ’แžšแžถแž”แŸ‹ upstream CLI proxying | `docker compose --profile cliproxyapi up -d` | | `web` | `omniroute-web` | Web-session providers แžŠแŸ‚แž›แžแŸ’แžšแžผแžœแž€แžถแžšแž€แž˜แŸ’แž˜แžœแžทแž’แžธแžšแžปแž€แžšแž€แŸ– `gemini-web`, `claude-web`, `claude-turnstile` (build `runner-web` แžŠแŸ„แž™แžšแžฝแž˜แž”แž‰แŸ’แž…แžผแž› Chromium) | `docker compose --profile web up -d` | > แžขแžถแž…แž•แŸ’แžŸแŸ† profiles แž…แŸ’แžšแžพแž“แž‡แžถแž˜แžฝแž™แž‚แŸ’แž“แžถแž”แžถแž“แŸ– `docker compose --profile cli --profile cliproxyapi up -d`แŸ” ## แž€แžถแžšแž€แŸ†แžŽแžแŸ‹แžšแž…แž“แžถแžŸแž˜แŸ’แž–แŸแž“แŸ’แž’แžงแž”แž€แžšแžŽแŸ CLI แž›แžพ host แž“แŸ…แž–แŸแž› OmniRoute แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž€แŸ’แž“แžปแž„ Docker `omniroute setup-codex`, `setup-claude`, `config set ` แž“แžทแž„แž”แŸŠแžผแžแžปแž„ **แžšแž€แŸ’แžŸแžถแž‘แžปแž€แž€แžถแžšแž€แŸ†แžŽแžแŸ‹แžšแž…แž“แžถแžŸแž˜แŸ’แž–แŸแž“แŸ’แž’** แžšแž”แžŸแŸ‹ dashboard แžŸแžปแž‘แŸ’แž’แžแŸ‚แžŸแžšแžŸแŸแžšแžฏแž€แžŸแžถแžšแžŠแžผแž…แž‡แžถ `~/.codex/*.config.toml`แŸ” แž•แŸ’แž›แžผแžœแž‘แžถแŸ†แž„แž“แŸ„แŸ‡ แž˜แžถแž“แž“แŸแž™แžแŸ‚แž“แŸ…แž›แžพแž˜แŸ‰แžถแžŸแŸŠแžธแž“แžŠแŸ‚แž› CLI แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž–แžทแžแž”แŸ’แžšแžถแž€แžŠแž”แŸ‰แžปแžŽแŸ’แžŽแŸ„แŸ‡แŸ” แž”แŸ’แžšแžŸแžทแž“แž”แžพแžŠแŸ†แžŽแžพแžšแž€แžถแžšแž–แžฝแž€แžœแžถแž“แŸ…แž€แŸ’แž“แžปแž„ container แž€แžถแžšแžŸแžšแžŸแŸแžšแž“แŸ„แŸ‡แž“แžนแž„แž’แŸ’แž›แžถแž€แŸ‹แž‘แŸ…แž€แŸ’แž“แžปแž„ home แž•แŸ’แž‘แžถแž›แŸ‹แžšแž”แžŸแŸ‹ container (`/home/node` โ€” image แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž‡แžถ `USER node`) แžŠแŸ‚แž› CLI แžŽแžถแž˜แžฝแž™แž“แŸ…แž›แžพ host แž“แžนแž„แž˜แžทแž“แžขแžถแž“แžœแžถแžกแžพแž™ แž แžพแž™แžœแžถแž“แžนแž„แžแŸ’แžšแžผแžœ แž›แžปแž”แž…แŸ„แž›แž—แŸ’แž›แžถแž˜แŸ—แž“แŸ…แž–แŸแž› container แžแŸ’แžšแžผแžœแž”แžถแž“แž”แž„แŸ’แž€แžพแžแžกแžพแž„แžœแžทแž‰แŸ” OmniRoute แžšแž€แžƒแžพแž‰แž€แžšแžŽแžธแž“แŸแŸ‡ แž แžพแž™แž”แžŠแžทแžŸแŸแž’แž€แžถแžšแžŸแžšแžŸแŸแžš แžŠแŸ„แž™แž•แŸ’แžแž›แŸ‹แžŸแŸแž…แž€แŸ’แžแžธแžŽแŸ‚แž“แžถแŸ†แž‡แŸ†แž“แžฝแžŸแžฑแŸ’แž™ แž€แžถแžšแžšแžถแž™แž€แžถแžšแžŽแŸแžแžถแž‡แŸ„แž‚แž‡แŸแž™แžŠแŸ‚แž›แžขแŸ’แž“แž€แž˜แžทแž“แžขแžถแž…แž”แŸ’แžšแžพแž”แžถแž“แŸ– CLI แž”แž‰แŸ’แž…แž”แŸ‹แžŠแŸ„แž™แž›แŸแžแž€แžผแžŠ `2` แž แžพแž™ API แž†แŸ’แž›แžพแž™แžแž” `422` แž‡แžถแž˜แžฝแž™ `containerEphemeralTarget: true`แŸ” ### แž”แžถแž“แžŽแŸ‚แž“แžถแŸ†แŸ– แžŠแŸ†แžŽแžพแžšแž€แžถแžš CLI แž“แŸ…แž›แžพ host แž“แžทแž„ OmniRoute แž€แŸ’แž“แžปแž„ Docker Container แž•แŸ’แžแž›แŸ‹แžŸแŸแžœแžถ API; CLI แž€แŸ†แžŽแžแŸ‹แžšแž…แž“แžถแžŸแž˜แŸ’แž–แŸแž“แŸ’แž’แžงแž”แž€แžšแžŽแŸแž“แŸ…แž›แžพ host แžšแž”แžŸแŸ‹แžขแŸ’แž“แž€แŸ” ```bash docker compose --profile base up -d npm install -g omniroute omniroute connect http://localhost:20128 # แžแž˜แŸ’แžšแž„แŸ‹ CLI แž‘แŸ…แž€แžถแž“แŸ‹ container omniroute setup-codex # แžŸแžšแžŸแŸแžšแž‘แŸ… ~/.codex แž–แžทแžแž”แŸ’แžšแžถแž€แžŠแž“แŸ…แž›แžพ host แžšแž”แžŸแŸ‹แžขแŸ’แž“แž€ ``` แž“แŸแŸ‡แž‡แžถแž‡แž˜แŸ’แžšแžพแžŸแžแŸ’แžšแžนแž˜แžแŸ’แžšแžผแžœ แž“แŸ…แž–แŸแž› Codex, Claude Code, Cursor แžฌแžงแž”แž€แžšแžŽแŸแžŸแŸ’แžšแžŠแŸ€แž„แž‚แŸ’แž“แžถ แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž›แžพ laptop แžšแž”แžŸแŸ‹แžขแŸ’แž“แž€ โ€” แžŠแŸ‚แž›แž‡แžถแž€แžถแžšแžšแŸ€แž”แž…แŸ†แž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹แž’แž˜แŸ’แž˜แžแžถแŸ” ### แž‡แž˜แŸ’แžšแžพแžŸแž•แŸ’แžŸแŸแž„แŸ– bind-mount แžแž config แžšแž”แžŸแŸ‹ host (profile `host`) แž”แŸ’แžšแžŸแžทแž“แž”แžพแžขแŸ’แž“แž€แž…แž„แŸ‹แžฑแŸ’แž™ container แžแŸ’แž›แžฝแž“แžฏแž„แžŸแžšแžŸแŸแžš config แžšแž”แžŸแŸ‹ host แžŸแžผแž˜ mount แžแžแž‘แžถแŸ†แž„แž“แŸ„แŸ‡แž…แžผแž› แž แžพแž™แžแž˜แŸ’แžšแž„แŸ‹ `CLI_CONFIG_HOME` แž‘แŸ…แž€แžถแž“แŸ‹ root แžšแž”แžŸแŸ‹ mountแŸ” Profile `host` แž”แžถแž“แž’แŸ’แžœแžพแžŠแžผแž…แŸ’แž“แŸแŸ‡แžšแžฝแž…แž แžพแž™แŸ– ```yaml environment: - CLI_CONFIG_HOME=/host-home - CLI_ALLOW_CONFIG_WRITES=true volumes: - ~/.codex:/host-home/.codex:rw - ~/.claude:/host-home/.claude:rw ``` Bind mount แž‚แžบแž‡แžถแžขแŸ’แžœแžธแžŠแŸ‚แž›แž’แŸ’แžœแžพแžฑแŸ’แž™ path แžขแžถแž…แž‘แžปแž€แž…แžทแžแŸ’แžแž”แžถแž“แŸ– OmniRoute แžขแžถแž“ `/proc/self/mountinfo` แž แžพแž™แžขแž“แžปแž‰แŸ’แž‰แžถแžแžฑแŸ’แž™แžŸแžšแžŸแŸแžšแž‘แŸ…แž€แžถแž“แŸ‹ path แžŠแŸ‚แž›แž”แžถแž“ mount (แž“แžทแž„แžแž แžŠแŸ‚แž›แžแžแž€แžผแž“แžšแž”แžŸแŸ‹แžœแžถแž‡แžถ mount แžŠแŸ‚แž›แžแŸ’แžšแžผแžœแž‚แŸ’แž“แžถแž–แžทแžแž”แŸ’แžšแžถแž€แžŠแž“แžนแž„แž‘แž˜แŸ’แžšแž„แŸ‹ `/host-home` แžแžถแž„แž›แžพ) แžแžŽแŸˆแžŠแŸ‚แž› แž“แŸ…แžแŸ‚แž”แžŠแžทแžŸแŸแž’ path แžŠแŸ‚แž›แž˜แžทแž“แž”แžถแž“ mountแŸ” ### แž…แŸ’แžšแž€แž”แž“แŸ’แž‘แžถแž“แŸ‹แŸ– แž€แŸ†แžŽแžแŸ‹แžšแž…แž“แžถแžŸแž˜แŸ’แž–แŸแž“แŸ’แž’ CLI แž•แŸ’แž‘แžถแž›แŸ‹แžšแž”แžŸแŸ‹ container (แž”แŸ’แžšแžพแžŠแŸ„แž™แž”แŸ’แžšแžปแž„แž”แŸ’แžšแž™แŸแžแŸ’แž“) แž“แŸ…แž–แŸแž› CLI แž–แžทแžแž‡แžถแžŸแŸ’แžแžทแžแž“แŸ…แž€แŸ’แž“แžปแž„ container (profile `cli`) แž€แžถแžšแžŸแžšแžŸแŸแžšแž“แŸ„แŸ‡ แž‚แžบแž‡แžถแž…แŸแžแž“แžถแŸ” แž”แž‰แŸ’แž‡แžผแž“ `--allow-container-write` แž‘แŸ…แž€แžถแž“แŸ‹แž–แžถแž€แŸ’แž™แž”แž‰แŸ’แž‡แžถ `setup-*` แžŽแžถแž˜แžฝแž™ แžฌแž€แŸ†แžŽแžแŸ‹ `OMNIROUTE_ALLOW_CONTAINER_CONFIG_WRITE=true` แžŸแž˜แŸ’แžšแžถแž”แŸ‹ serverแŸ” แž€แžถแžšแžŸแžšแžŸแŸแžšแž“แžนแž„แž”แž“แŸ’แž แž‡แžถแž˜แžฝแž™แž€แžถแžšแž–แŸ’แžšแž˜แžถแž“แžแžถ แžœแžถแž“แžนแž„แž˜แžทแž“แž“แŸ…แžŸแž›แŸ‹แž€แŸ’แžšแŸ„แž™ container แžแŸ’แžšแžผแžœแž”แžถแž“แž”แž„แŸ’แž€แžพแžแžกแžพแž„แžœแžทแž‰แž‘แŸแŸ” > **แž€แžถแžšแž–แŸ’แžšแž˜แžถแž“แžŸแžปแžœแžแŸ’แžแžทแž—แžถแž– โ€” profile `cli` + mount `docker.sock`แŸ”** > Profile `cli` แž’แŸ’แžœแžพ bind-mount `/var/run/docker.sock` แžŠแžพแž˜แŸ’แž”แžธแžฑแŸ’แž™ > auto-updater แž“แŸ…แž€แŸ’แž“แžปแž„ container แžขแžถแž…แž”แž„แŸ’แž€แžพแž stack แžกแžพแž„แžœแžทแž‰แžแžถแž˜แžšแž™แŸˆ daemon แžšแž”แžŸแŸ‹ host > (`src/lib/system/autoUpdate.ts` แž–แžทแž“แžทแžแŸ’แž™แžšแž€ socket แž“แŸ„แŸ‡ แž แžพแž™แžšแŸ†แž›แž„ > แž•แŸ’แž›แžผแžœ Docker แž“แŸ…แž–แŸแž›แžœแžถแž˜แžทแž“แž˜แžถแž“)แŸ” Socket แž“แŸ„แŸ‡แž‚แžบแž‡แžถ **แž–แŸ’แžšแŸ†แžŠแŸ‚แž“แž‘แŸ†แž“แžปแž€แž…แžทแžแŸ’แžแž€แž˜แŸ’แžšแžทแž root > แžšแž”แžŸแŸ‹ host**แŸ– แžขแŸ’แžœแžธแž€แŸแžŠแŸ„แž™แžŠแŸ‚แž›แžขแžถแž…แž…แžผแž›แž”แŸ’แžšแžพแžœแžถแž”แžถแž“ แžขแžถแž…แž”แž‰แŸ’แž‡แžถ Docker daemon แžšแž”แžŸแŸ‹ host แž‡แžถ > root โ€” แžœแžถแžขแžถแž…แž”แž„แŸ’แž€แžพแž แž–แžทแž“แžทแžแŸ’แž™ แž”แž‰แŸ’แžˆแž”แŸ‹ แž“แžทแž„แž›แžปแž” container แžŽแžถแž˜แžฝแž™แž“แŸ…แž›แžพ hostแŸ” > แž•แž›แž”แŸ‰แŸ‡แž–แžถแž›แŸ‹แŸ– > > 1. **แž€แžปแŸ†แž”แžพแž€ port แžšแž”แžŸแŸ‹ profile `cli` แž‘แŸ…แž€แžถแž“แŸ‹ network แžŠแžถแž…แŸ‹แžแžถแžแŸ”** Publish > แžœแžถแž“แŸ…แž›แžพ `127.0.0.1` (`ports: "127.0.0.1:${DASHBOARD_PORT:-20128}:..."`) > โ€” profile `cli` แžŠแŸ‚แž›แžขแžถแž…แž…แžผแž›แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž”แžถแž“แž–แžธ LAN แž“แžนแž„แž”แž˜แŸ’แž›แŸ‚แž„ RCE แž€แž˜แŸ’แžšแžทแž dashboard แžŽแžถแž˜แžฝแž™แž‘แŸ…แž‡แžถ > แž€แžถแžšแž€แžถแž“แŸ‹แž€แžถแž”แŸ‹ host แž‘แžถแŸ†แž„แžŸแŸ’แžšแžปแž„แŸ” > 2. **แž€แžปแŸ† bind แžแžแž”แž“แŸ’แžแŸ‚แž˜แžŽแžถแž˜แžฝแž™แžšแž”แžŸแŸ‹ host แž…แžผแž›แž€แŸ’แž“แžปแž„ profile `cli`แŸ”** > Docker socket แžšแžฝแž˜แž‡แžถแž˜แžฝแž™ mount แž”แž“แŸ’แžแŸ‚แž˜แžŽแžถแž˜แžฝแž™ แž“แžนแž„แž•แŸ’แžแž›แŸ‹แžฑแŸ’แž™ container แž“แžผแžœแžŸแžทแž‘แŸ’แž’แžท > แžขแžถแž“/แžŸแžšแžŸแŸแžšแž–แŸแž‰แž›แŸแž‰แž‘แŸ…แž€แžถแž“แŸ‹ filesystem แž“แžทแž„ config แžšแž”แžŸแŸ‹ hostแŸ” แž”แŸ’แžšแžŸแžทแž“แž”แžพแžขแŸ’แž“แž€แžแŸ’แžšแžผแžœแž€แžถแžšแžฑแŸ’แž™แžงแž”แž€แžšแžŽแŸแž˜แžฝแž™ > แž˜แžพแž›แžƒแžพแž‰ project แžŸแžผแž˜แžŠแŸ†แžŽแžพแžšแž€แžถแžšแžœแžถแž“แŸ… local แž‡แžถแž˜แžฝแž™ binary แžšแž”แžŸแŸ‹ CLI โ€” แž€แžปแŸ† mount แžœแžถ > แž…แžผแž›แž€แŸ’แž“แžปแž„ container `cli`แŸ” > > แž”แŸ’แžšแžŸแžทแž“แž”แžพแžขแŸ’แž“แž€แž˜แžทแž“แžแŸ’แžšแžผแžœแž€แžถแžš auto-update แž“แŸ…แž€แŸ’แž“แžปแž„ container แž‘แŸ แžŸแžผแž˜แž‘แžปแž€ profile `cli` แžฑแŸ’แž™แž”แžทแž‘ > (`COMPOSE_PROFILES=core,redis` แžฌแžแŸ’แž›แžธแž‡แžถแž„แž“แŸแŸ‡)แŸ” Profile แž•แŸ’แžŸแŸแž„แž‘แŸ€แžแž˜แžทแž“ > mount Docker socket แž‘แŸแŸ” > > แžŸแžผแž˜แž˜แžพแž› `docs/security/MITM-TPROXY-DECRYPT.md` (git; แž˜แžทแž“แžแŸ’แžšแžผแžœแž”แžถแž“ compile แž…แžผแž›แž€แŸ’แž“แžปแž„ `/docs`) แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž‚แŸ†แžšแžผแž‚แŸ†แžšแžถแž˜แž€แŸ†แž แŸ‚แž„แžŠแŸ‚แž›แž–แžถแž€แŸ‹แž–แŸแž“แŸ’แž’ > แž‡แžปแŸ†แžœแžทแž‰ MITM แž“แžทแž„ `docs/security/SUPPLY_CHAIN.md` แžŸแž˜แŸ’แžšแžถแž”แŸ‹ > แžแŸ’แžŸแŸ‚แžŸแž„แŸ’แžœแžถแž€แŸ‹แž”แŸ’แžšแž—แž–แžŠแžพแž˜แž“แŸƒ binary `codex`/`claude-code`/`droid`/`openclaw`แŸ” ## Redis Sidecar OmniRoute แž–แžนแž„แž•แŸ’แžขแŸ‚แž€แž›แžพ Redis แžŠแžพแž˜แŸ’แž”แžธแž‚แžถแŸ†แž‘แŸ’แžšแž€แž˜แŸ’แž˜แžœแžทแž’แžธแž€แŸ†แžŽแžแŸ‹แžขแžแŸ’แžšแžถแž”แŸ‚แž”แž…แŸ‚แž€แž…แžถแž™ แž“แžทแž„แžƒแŸ’แž›แžถแŸ†แž„แžŸแž˜แŸ’แž„แžถแžแŸ‹แžšแžฝแž˜แŸ” แžŸแŸแžœแžถ `redis` แžแŸ’แžšแžผแžœแž”แžถแž“แž€แŸ†แžŽแžแŸ‹ **แž‡แžถแž“แžทแž…แŸ’แž…** แž“แŸ…แž€แŸ’แž“แžปแž„ `docker-compose.yml` (แžœแžถแž˜แžทแž“แž˜แžถแž“แž€แžถแžšแž€แŸ†แžŽแžแŸ‹แžแžถแž˜ profile แž‘แŸ) แž แžพแž™แž…แžถแž”แŸ‹แž•แŸ’แžŠแžพแž˜แž‡แžถแž˜แžฝแž™ profile แž•แŸ’แžŸแŸแž„แž‘แŸ€แžแžŽแžถแž˜แžฝแž™แŸ” | แž–แŸแžแŸŒแž˜แžถแž“แž›แž˜แŸ’แžขแžทแž | แžแž˜แŸ’แž›แŸƒ | | -------------------------------- | ------------------------------------------ | | Image | `redis:7-alpine` | | แžˆแŸ’แž˜แŸ„แŸ‡ container | `omniroute-redis` | | Port แžแžถแž„แž€แŸ’แž“แžปแž„ | `6379` | | Port แžšแž”แžŸแŸ‹ host (แžขแžถแž…แž€แŸ†แžŽแžแŸ‹แž‡แŸ†แž“แžฝแžŸ) | `REDIS_PORT` (แž›แŸ†แž“แžถแŸ†แžŠแžพแž˜แž‡แžถ `6379`) | | แž€แžถแžšแž…แž„แž—แŸ’แž‡แžถแž”แŸ‹ host (แžขแžถแž…แž€แŸ†แžŽแžแŸ‹แž‡แŸ†แž“แžฝแžŸ) | `REDIS_BIND_HOST` (แž›แŸ†แž“แžถแŸ†แžŠแžพแž˜แž‡แžถ `127.0.0.1`) | | Volume | `omniroute-redis-data` โ†’ `/data` | | แž€แžถแžšแž–แžทแž“แžทแžแŸ’แž™แžŸแžปแžแž—แžถแž– | `redis-cli ping` (แž…แž“แŸ’แž›แŸ„แŸ‡แž–แŸแž› 10 แžœแžทแž“แžถแž‘แžธ) | แžขแžแŸแžšแž”แžšแžทแžŸแŸ’แžแžถแž“แžŠแŸ‚แž›แž–แžถแž€แŸ‹แž–แŸแž“แŸ’แž’แŸ– - `REDIS_URL` โ€” แžแŸ’แžŸแŸ‚แžขแž€แŸ’แžŸแžšแžแž—แŸ’แž‡แžถแž”แŸ‹แžŠแŸ‚แž›แžแŸ’แžšแžผแžœแž”แžถแž“แž”แž‰แŸ’แž…แžผแž›แž‘แŸ…แž€แŸ’แž“แžปแž„แž€แž˜แŸ’แž˜แžœแžทแž’แžธ (`redis://redis:6379` แž‡แžถแž›แŸ†แž“แžถแŸ†แžŠแžพแž˜)แŸ” - `REDIS_PORT` โ€” แž€แžถแžšแž•แŸ’แž‚แžผแž•แŸ’แž‚แž„ port แžแžถแž„ host แžŸแž˜แŸ’แžšแžถแž”แŸ‹ container แžšแž”แžŸแŸ‹ RedisแŸ” - `REDIS_BIND_HOST` โ€” interface แžšแž”แžŸแŸ‹ host แžŠแŸ‚แž› port แžแŸ’แžšแžผแžœแž”แžถแž“แž•แŸ’แžŸแž–แŸ’แžœแž•แŸ’แžŸแžถแž™แž“แŸ…แž›แžพแžœแžถแŸ” แž›แŸ†แž“แžถแŸ†แžŠแžพแž˜แž‡แžถ `127.0.0.1`แŸ” > **แž˜แžผแž›แž แŸแžแžปแžŠแŸ‚แž›แž”แŸ’แžšแžพ loopback แž‡แžถแž›แŸ†แž“แžถแŸ†แžŠแžพแž˜แŸ–** sidecar แžŠแŸ†แžŽแžพแžšแž€แžถแžšแžŠแŸ„แž™แž‚แŸ’แž˜แžถแž“ `requirepass` แž แžพแž™ container > แžšแž”แžŸแŸ‹แž€แž˜แŸ’แž˜แžœแžทแž’แžธแž…แžผแž›แž”แŸ’แžšแžพแžœแžถแžแžถแž˜แž”แžŽแŸ’แžŠแžถแž‰ compose (`redis:6379`) โ€” port แžŠแŸ‚แž›แž”แžถแž“แž•แŸ’แžŸแž–แŸ’แžœแž•แŸ’แžŸแžถแž™แž˜แžถแž“ > แžŸแž˜แŸ’แžšแžถแž”แŸ‹แžแŸ‚แžงแž”แž€แžšแžŽแŸแž“แŸ…แžแžถแž„ host แž”แŸ‰แžปแžŽแŸ’แžŽแŸ„แŸ‡ (`redis-cli`, `npm run dev` แž“แŸ…แž›แžพแž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แžผแž›แžŠแŸ’แž‹แžถแž“)แŸ” แž€แžถแžšแž•แŸ’แžŸแž–แŸ’แžœแž•แŸ’แžŸแžถแž™แž“แŸ…แž›แžพ > `0.0.0.0` แž“แžนแž„แž’แŸ’แžœแžพแžฑแŸ’แž™ Redis แžŠแŸ‚แž›แž‚แŸ’แž˜แžถแž“แž€แžถแžšแž•แŸ’แž‘แŸ€แž„แž•แŸ’แž‘แžถแžแŸ‹แžขแžแŸ’แžแžŸแž‰แŸ’แž‰แžถแžŽแžขแžถแž…แž…แžผแž›แž”แŸ’แžšแžพแž”แžถแž“แž–แžธแž‚แŸ’แžšแž”แŸ‹ host แž“แŸ…แž›แžพ LAN แžšแž”แžŸแŸ‹แžขแŸ’แž“แž€แŸ” แž”แŸ’แžšแžŸแžทแž“แž”แžพแžขแŸ’แž“แž€แž€แŸ†แžŽแžแŸ‹ > `REDIS_BIND_HOST=0.0.0.0` แžŸแžผแž˜แž”แž“แŸ’แžแŸ‚แž˜ `--requirepass` แž‘แŸ…แž€แŸ’แž“แžปแž„ `command:` แžšแž”แžŸแŸ‹แžŸแŸแžœแžถแž•แž„แžŠแŸ‚แžšแŸ” **แž€แžถแžšแž”แžทแž‘ Redis** แž˜แžทแž“แžแŸ’แžšแžผแžœแž”แžถแž“แžŽแŸ‚แž“แžถแŸ†แž‘แŸ (แž€แž˜แŸ’แž˜แžœแžทแž’แžธแž€แŸ†แžŽแžแŸ‹แžขแžแŸ’แžšแžถแž“แžนแž„แž”แž“แŸ’แžแž™แž‘แŸ…แž”แŸ’แžšแžพแž˜แžปแžแž„แžถแžšแž”แž˜แŸ’แžšแžปแž„แž‘แžปแž€แž€แŸ’แž“แžปแž„แžขแž„แŸ’แž‚แž…แž„แž…แžถแŸ†)แŸ” แž”แŸ’แžšแžŸแžทแž“แž”แžพแž…แžถแŸ†แž”แžถแž…แŸ‹ แžขแŸ’แž“แž€แžขแžถแž…แž›แžปแž”/แžŠแžถแž€แŸ‹แž‡แžถ comment แž“แžผแžœแž”แŸ’แž›แžปแž€แžŸแŸแžœแžถ `redis:` แž€แŸ’แž“แžปแž„ `docker-compose.yml` แžฌแž€แŸ†แžŽแžแŸ‹ scale แžšแž”แžŸแŸ‹แžœแžถแž‘แŸ…แžŸแžผแž“แŸ’แž™แŸ– ```bash docker compose up -d --scale redis=0 ``` ## Production Compose แžŸแž˜แŸ’แžšแžถแž”แŸ‹ snapshot แž•แž›แžทแžแž€แž˜แŸ’แž˜แžŠแžถแž…แŸ‹แžŠแŸ„แž™แžกแŸ‚แž€แžŠแŸ‚แž›แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž‘แž“แŸ’แž‘แžนแž˜แž‡แžถแž˜แžฝแž™ dev แžŸแžผแž˜แž”แŸ’แžšแžพ `docker-compose.prod.yml`แŸ” | แž–แŸแžแŸŒแž˜แžถแž“แž›แž˜แŸ’แžขแžทแž | แžแž˜แŸ’แž›แŸƒ | | ---------------------------- | --------------------------------------------------------------------------------------------- | | แžฏแž€แžŸแžถแžš | `docker-compose.prod.yml` | | Port แž•แŸ’แž‘แžถแŸ†แž„แž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแž„แž›แŸ†แž“แžถแŸ†แžŠแžพแž˜ | `PROD_DASHBOARD_PORT=20130` (แž•แŸ’แž‚แžผแž•แŸ’แž‚แž„แž‘แŸ… `${DASHBOARD_PORT:-20128}` แžแžถแž„แž€แŸ’แž“แžปแž„) | | Port API แž›แŸ†แž“แžถแŸ†แžŠแžพแž˜ | `PROD_API_PORT=20131` | | Image | `omniroute:prod` (แž”แžถแž“ build แž–แžธ target `runner-cli`) | | Container แžšแž”แžŸแŸ‹ Redis | `omniroute-redis-prod` (`redis:8.6.2`, แž”แŸ’แžšแžพ volume `redis-prod-data` แžŠแžถแž…แŸ‹แžŠแŸ„แž™แžกแŸ‚แž€) | | Volume แž‘แžทแž“แŸ’แž“แž“แŸแž™ | `omniroute-prod-data` (แž˜แžถแž“แžˆแŸ’แž˜แŸ„แŸ‡ แž“แžทแž„แžšแž€แŸ’แžŸแžถแž‘แžปแž€แž”แž“แŸ’แžแž€แŸ’แžšแŸ„แž™แž€แžถแžš rebuild) | | แž€แžถแžšแž–แžทแž“แžทแžแŸ’แž™แžŸแžปแžแž—แžถแž– | `node healthcheck.mjs` + `redis-cli ping` แžŠแŸ„แž™ `depends_on` แžแŸ’แžšแžผแžœแž”แžถแž“แž€แŸ†แžŽแžแŸ‹แžฑแŸ’แž™แžšแž„แŸ‹แž…แžถแŸ†แžŸแžปแžแž—แžถแž– Redis | แžšแž”แŸ€แž”แž”แŸ’แžšแžพแŸ– ```bash # Build แž“แžทแž„แž…แžถแž”แŸ‹แž•แŸ’แžŠแžพแž˜ stack แž•แž›แžทแžแž€แž˜แŸ’แž˜ docker compose -f docker-compose.prod.yml up -d --build # แž”แž„แŸ’แž แžถแž‰ log แž‡แžถแž”แž“แŸ’แžแž”แž“แŸ’แž‘แžถแž”แŸ‹ docker compose -f docker-compose.prod.yml logs -f # แž”แžทแž‘ stack (แžšแž€แŸ’แžŸแžถแž‘แžปแž€ volume) docker compose -f docker-compose.prod.yml down ``` Stack แž•แž›แžทแžแž€แž˜แŸ’แž˜แžŠแŸ†แžŽแžพแžšแž€แžถแžšแžŸแŸ’แžšแž”แž‚แŸ’แž“แžถแž‡แžถแž˜แžฝแž™ dev compose (แž˜แžถแž“แžˆแŸ’แž˜แŸ„แŸ‡ container, port แž“แžทแž„ volume แžแžปแžŸแž‚แŸ’แž“แžถ) แžŠแžผแž…แŸ’แž“แŸแŸ‡แžขแŸ’แž“แž€แžขแžถแž…แž”แž“แŸ’แžแžขแž—แžทแžœแžŒแŸ’แžแž“แŸ…แž›แžพแž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แžผแž›แžŠแŸ’แž‹แžถแž“ แžแžŽแŸˆแžŠแŸ‚แž›แž”แŸ’แžšแž–แŸแž“แŸ’แž’แž•แž›แžทแžแž€แž˜แŸ’แž˜แž“แŸ…แžแŸ‚แžŠแŸ†แžŽแžพแžšแž€แžถแžšแŸ” ## แžŠแŸ†แžŽแžถแž€แŸ‹แž€แžถแž› Dockerfile แžƒแŸ’แž›แžถแŸ†แž„แž€แžผแžŠแž“แŸแŸ‡แž•แŸ’แžแž›แŸ‹แž‡แžผแž“ Dockerfile แž–แž แžปแžŠแŸ†แžŽแžถแž€แŸ‹แž€แžถแž› (`Dockerfile`)แŸ” แž˜แžถแž“แžŠแŸ†แžŽแžถแž€แŸ‹แž€แžถแž›แž…แŸ†แž“แžฝแž“แž”แžฝแž“แžŠแŸ‚แž›แžขแžถแž…แž”แŸ’แžšแžพแž”แžถแž“; แžŸแžผแž˜แž‡แŸ’แžšแžพแžŸแžšแžพแžŸ `target` แžฑแŸ’แž™แžแŸ’แžšแžนแž˜แžแŸ’แžšแžผแžœแžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แžšแžŽแžธแž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹แžšแž”แžŸแŸ‹แžขแŸ’แž“แž€แŸ” | แžŠแŸ†แžŽแžถแž€แŸ‹แž€แžถแž› | Image แž˜แžผแž›แžŠแŸ’แž‹แžถแž“ | แž‚แŸ„แž›แž”แŸ†แžŽแž„ | | ------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `builder` | `node:26-trixie-slim` | แžŠแŸ†แžกแžพแž„ dependencies (`npm ci --legacy-peer-deps`) แž“แžทแž„แžŠแŸ†แžŽแžพแžšแž€แžถแžš `npm run build` (แžแžถแž˜แž›แŸ†แž“แžถแŸ†แžŠแžพแž˜แž”แŸ’แžšแžพ Turbopack โ€” แžŸแžผแž˜แž˜แžพแž›แž’แž“แž’แžถแž“แž–แŸแž› build แžแžถแž„แž€แŸ’แžšแŸ„แž˜) | | `runner-base` | `node:26-trixie-slim` | แž”แžšแžทแžŸแŸ’แžแžถแž“ runtime แžŸแž˜แŸ’แžšแžถแž”แŸ‹ production แž‡แžถแž˜แžฝแž™แž›แž‘แŸ’แž’แž•แž› standalone แžšแž”แžŸแŸ‹ Next.jsแŸ” **แž˜แžทแž“แž˜แžถแž“ provider CLI แž—แŸ’แž‡แžถแž”แŸ‹แž˜แž€แž‡แžถแž˜แžฝแž™แž‘แŸแŸ”** | | `runner-cli` | `runner-base` | แž”แž“แŸ’แžแŸ‚แž˜ `git`, `docker.io`, `docker-compose` แž“แžทแž„ CLI แžŸแž€แž›แŸ– `@openai/codex`, `@anthropic-ai/claude-code`, `droid`, `openclaw`แŸ” **แžŸแžผแž˜แž‡แŸ’แžšแžพแžŸแžšแžพแžŸแžœแžถแžŸแž˜แŸ’แžšแžถแž”แŸ‹แž›แŸ†แž แžผแžšแž€แžถแžšแž„แžถแžšแž”แŸ‚แž” agenticแŸ”** | | `runner-web` | `runner-base` | แž”แž“แŸ’แžแŸ‚แž˜ Playwright + แž€แž˜แŸ’แž˜แžœแžทแž’แžธแžšแžปแž€แžšแž€ Chromium (`--with-deps`) แžŸแž˜แŸ’แžšแžถแž”แŸ‹ provider แž“แŸƒ web-sessionแŸ– `gemini-web`, `claude-web`, `claude-turnstile`แŸ” **แžŸแžผแž˜แž‡แŸ’แžšแžพแžŸแžšแžพแžŸแžœแžถแž“แŸ…แž–แŸแž›แžขแŸ’แž“แž€แž”แŸ’แžšแžพ provider แž‘แžถแŸ†แž„แž“แŸ„แŸ‡** โ€” image แž’แž˜แŸ’แž˜แžแžถแž“แžนแž„แž”แžšแžถแž‡แŸแž™แž“แŸ…แž–แŸแž›แž˜แžถแž“ request แž”แŸ’แžšแžŸแžทแž“แž”แžพแž‚แŸ’แž˜แžถแž“แžœแžถ (แžŸแžผแž˜แž˜แžพแž›แž€แŸ†แžŽแžแŸ‹แžŸแž˜แŸ’แž‚แžถแž›แŸ‹ `-web` แž€แŸ’แžšแŸ„แž˜ Release Channels)แŸ” | Build target แž‡แžถแž€แŸ‹แž›แžถแž€แŸ‹แžŠแŸ„แž™แžŠแŸƒแŸ– ```bash docker build --target runner-base -t omniroute:base . docker build --target runner-cli -t omniroute:cli . docker build --target runner-web -t omniroute:web . ``` ### แž’แž“แž’แžถแž“แž–แŸแž› build build args แž…แŸ†แž“แžฝแž“แž”แžธแž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแž„แž€แžถแžšแž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹แž’แž“แž’แžถแž“แžšแž”แžŸแŸ‹แžŠแŸ†แžŽแžถแž€แŸ‹แž€แžถแž› `builder`แŸ” แž–แžฝแž€แžœแžถแžŸแž˜แŸ’แžšแžถแž”แŸ‹แžแŸ‚แž–แŸแž› build แž”แŸ‰แžปแžŽแŸ’แžŽแŸ„แŸ‡ โ€” `OMNIROUTE_MEMORY_MB` (แžแžถแž„แž€แŸ’แžšแŸ„แž˜) แž‚แžบแž‡แžถแž€แžถแžšแž€แŸ†แžŽแžแŸ‹ runtime แžŠแžถแž…แŸ‹แžŠแŸ„แž™แžกแŸ‚แž€แŸ” | Build arg | แž›แŸ†แž“แžถแŸ†แžŠแžพแž˜ | แžฅแž‘แŸ’แž’แžทแž–แž› | | --------------------------- | -------- | ----------------------------------------------------------------------------------------------------- | | `OMNIROUTE_USE_TURBOPACK` | `0` | `0` build แžŠแŸ„แž™แž”แŸ’แžšแžพ webpackแŸ– แž”แŸ’แžšแžพแžขแž„แŸ’แž‚แž…แž„แž…แžถแŸ†แž€แž˜แŸ’แžšแžทแžแž€แŸ†แž–แžผแž›แž‘แžถแž”แž‡แžถแž„ แž”แŸ‰แžปแž“แŸ’แžแŸ‚แž™แžบแžแž‡แžถแž„แŸ” `1` แž‡แŸ’แžšแžพแžŸแž”แŸ’แžšแžพ TurbopackแŸ” | | `OMNIROUTE_BUILD_MEMORY_MB` | `6144` | แž€แž˜แŸ’แžšแžทแžแžขแžแžทแž”แžšแž˜แžถ heap แžšแž”แžŸแŸ‹ V8 (`--max-old-space-size`) แžŸแž˜แŸ’แžšแžถแž”แŸ‹ `next build` แžŠแŸ‚แž›แžแŸ’แžšแžผแžœแž”แžถแž“แž”แž„แŸ’แž€แžพแžแž‡แžถแžŠแŸ†แžŽแžพแžšแž€แžถแžšแŸ” | | `OMNIROUTE_BUILD_WORKERS` | `2` | แž•แŸ’แžแž›แŸ‹แžแž˜แŸ’แž›แŸƒแž‘แŸ… `CIRCLE_NODE_TOTAL`; Next แž€แŸ†แžŽแžแŸ‹ `workers = N - 1` แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แžถแžšแž”แŸ’แžšแž˜แžผแž›แž‘แžทแž“แŸ’แž“แž“แŸแž™แž‘แŸ†แž–แŸแžšแŸ” | `OMNIROUTE_BUILD_WORKERS` แž‚แžบแž‡แžถแžแž˜แŸ’แž›แŸƒแžŠแŸ‚แž›แžแŸ’แžšแžผแžœแž”แž„แŸ’แž€แžพแž“แž›แžพ builder แžŠแŸ‚แž›แž˜แžถแž“แž’แž“แž’แžถแž“แžแŸ’แž–แžŸแŸ‹ แž แžพแž™แž€แŸแž‡แžถแžแž˜แŸ’แž›แŸƒแžŠแŸ‚แž›แžแŸ’แžšแžผแžœ แžŸแž„แŸ’แžŸแŸแž™แž•แž„แžŠแŸ‚แžš แž“แŸ…แž–แŸแž› build แžŠแŸ‚แž›แž˜แžถแž“แž’แž“แž’แžถแž“แž€แŸ†แžŽแžแŸ‹แž”แžถแž“แž”แžšแžถแž‡แŸแž™ **แž”แž“แŸ’แž‘แžถแž”แŸ‹แž–แžธ** `โœ“ Compiled successfully`แŸ” worker แž‘แžทแž“แŸ’แž“แž“แŸแž™แž‘แŸ†แž–แŸแžšแž“แžธแž˜แžฝแž™แŸ—แž‚แžบแž‡แžถ process แžŠแžถแž…แŸ‹แžŠแŸ„แž™แžกแŸ‚แž€ แž แžพแž™ process แž˜แŸ `next build` แž€แŸแžŠแžผแž…แž‚แŸ’แž“แžถ; แž€แžถแžšแž’แŸ’แžœแžพแžแŸแžŸแŸ’แžแž•แŸ’แž‘แžถแž›แŸ‹แž›แžพ VPS (issue #7518) แž”แžถแž“แžœแžถแžŸแŸ‹แžƒแžพแž‰ peak RSS แžšแž”แžŸแŸ‹ process แž“แžธแž˜แžฝแž™แŸ—แž“แŸ… ~4.5 GB แžŠแŸ„แž™แž˜แžทแž“แž–แžถแž€แŸ‹แž–แŸแž“แŸ’แž’แž“แžนแž„ flag heap `NODE_OPTIONS` (Turbopack compile แžŠแŸ„แž™แž”แŸ’แžšแžพ แžขแž„แŸ’แž‚แž…แž„แž…แžถแŸ† native/Rust แž“แŸ…แž€แŸ’แžšแŸ… V8 heap)แŸ” แžแž˜แŸ’แž›แŸƒแž›แŸ†แž“แžถแŸ†แžŠแžพแž˜ `2` (โ†’ worker 1, แžŸแžšแžปแž” 2 processes) แžแŸ’แžšแžผแžœแž”แžถแž“แž€แŸ†แžŽแžแŸ‹แžŸแž˜แŸ’แžšแžถแž”แŸ‹ runner แžŠแŸ‚แž› host แžŠแŸ„แž™ GitHub แž˜แžถแž“ RAM 16 GB / 4 vCPU แžŠแŸ‚แž› pipeline แžŸแž˜แŸ’แžšแžถแž”แŸ‹ publish แž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹แŸ” แž“แŸ…แžแž˜แŸ’แž›แŸƒ `8` (โ†’ workers 7) runner แž“แŸ„แŸ‡แž”แžถแž“แžขแžŸแŸ‹แžขแž„แŸ’แž‚แž…แž„แž…แžถแŸ† แž แžพแž™ buildkit แž”แžถแž“แž’แŸ’แžœแžพแžฑแŸ’แž™แž‡แŸ†แž แžถแž“แž“แŸ„แŸ‡แž”แžšแžถแž‡แŸแž™แž‡แžถแž˜แžฝแž™ `ResourceExhausted: ... cannot allocate memory`; `3` (โ†’ workers 2) แž“แŸ…แžแŸ‚แž˜แžทแž“แžขแžถแž…แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž”แžถแž“ แž”แž“แŸ’แž‘แžถแž”แŸ‹แž–แžธ RSS แž€แŸ’แž“แžปแž„แž˜แžฝแž™ process แžแŸ’แžšแžผแžœแž”แžถแž“แžœแžถแžŸแŸ‹ แžŠแŸ„แž™แž•แŸ’แž‘แžถแž›แŸ‹แž‡แŸ†แž“แžฝแžŸแžฑแŸ’แž™แž€แžถแžšแžŸแž“แŸ’แž“แžทแžŠแŸ’แž‹แžถแž“แŸ” `tests/unit/docker-build-memory-budget.test.ts` แž’แŸ’แžœแžพแž€แžถแžšแž‚แžŽแž“แžถแžŠแŸ„แž™แž•แŸ’แžขแŸ‚แž€แž›แžพแžแžฝแž›แŸแžแžŠแŸ‚แž›แž”แžถแž“แžœแžถแžŸแŸ‹ แž แžพแž™แž“แžนแž„แž”แžšแžถแž‡แŸแž™ แž”แŸ’แžšแžŸแžทแž“แž”แžพแž€แžถแžšแž€แŸ†แžŽแžแŸ‹แžŽแžถแž˜แžฝแž™ แž€แžพแž“แž›แžพแžŸแžŸแž˜แžแŸ’แžแž—แžถแž–แžšแž”แžŸแŸ‹ runnerแŸ” Turbopack compile แžŠแŸ„แž™แž”แŸ’แžšแžพแžขแž„แŸ’แž‚แž…แž„แž…แžถแŸ† native Rust แžŠแŸ‚แž›แžŸแŸ’แžแžทแžแž“แŸ… **แž€แŸ’แžšแŸ…** V8 heap แžŠแžผแž…แŸ’แž“แŸแŸ‡ `OMNIROUTE_BUILD_MEMORY_MB` แž˜แžทแž“แžขแžถแž…แž€แŸ†แžŽแžแŸ‹แž–แŸ’แžšแŸ†แžŠแŸ‚แž“แžœแžถแž”แžถแž“แž‘แŸแŸ” แž›แžพ host แžŠแŸ‚แž›แž˜แžถแž“แž–แŸ’แžšแŸ†แžŠแŸ‚แž“แžขแž„แŸ’แž‚แž…แž„แž…แžถแŸ† build แž“แžนแž„แžแŸ’แžšแžผแžœ OOM killer แž”แž‰แŸ’แž…แž”แŸ‹แžŠแŸ„แž™ SIGKILL แžŠแŸ„แž™แž˜แžทแž“แž˜แžถแž“แžŸแžถแžšแž€แŸ†แž แžปแžŸแžขแŸ’แžœแžธแž‘แžถแŸ†แž„แžขแžŸแŸ‹ โ€” แžœแžถแž‚แŸ’แžšแžถแž“แŸ‹แžแŸ‚ แžˆแž”แŸ‹แž“แŸ…แž–แžถแž€แŸ‹แž€แžŽแŸ’แžแžถแž› `Creating an optimized production build` แžŠแŸ‚แž›แž˜แžพแž›แž‘แŸ…แžŠแžผแž…แž‡แžถแž‡แžถแž”แŸ‹แž‚แžถแŸ†แž„ แž‡แžถแž‡แžถแž„ แžขแžŸแŸ‹แžขแž„แŸ’แž‚แž…แž„แž…แžถแŸ†แŸ” แž“แŸแŸ‡แž‡แžถแž˜แžผแž›แž แŸแžแžปแžŠแŸ‚แž› `Dockerfile` แž”แŸ’แžšแžพ webpack แž‡แžถแž›แŸ†แž“แžถแŸ†แžŠแžพแž˜ (`OMNIROUTE_USE_TURBOPACK=0`) แžแžปแžŸแž–แžธ `npm run dev` / `npm run build` แžŠแŸ‚แž› Turbopack แž‡แžถแž›แŸ†แž“แžถแŸ†แžŠแžพแž˜แžšแž”แžŸแŸ‹แž€แžผแžŠแŸ– `docker build .` แž’แž˜แŸ’แž˜แžแžถแžŠแŸ‚แž›แž‚แŸ’แž˜แžถแž“ build args (แžŠแŸ‚แž› Railway แž“แžทแž„ host แžŠแŸ†แžกแžพแž„แžŠแŸ„แž™แž…แžปแž…แžแŸ‚แž˜แŸ’แžแž„แž•แŸ’แžŸแŸแž„แž‘แŸ€แžแžŠแŸ†แžŽแžพแžšแž€แžถแžš) แž˜แžทแž“แžแŸ’แžšแžผแžœแž”แžšแžถแž‡แŸแž™แžŠแŸ„แž™แžŸแŸ’แž„แžถแžแŸ‹แžŸแŸ’แž„แŸ€แž˜แž›แžพ builder แžŠแŸ‚แž›แž˜แžถแž“แž€แžถแžšแž€แŸ†แžŽแžแŸ‹แžขแž„แŸ’แž‚แž…แž„แž…แžถแŸ†แž“แŸ„แŸ‡แž‘แŸแŸ” image แžŠแŸ‚แž›แž”แžถแž“ publish แžšแžฝแž…แž แžพแž™แž”แžถแž“แž”แž‰แŸ’แž‡แžผแž“ `OMNIROUTE_USE_TURBOPACK=0` แž™แŸ‰แžถแž„แž‡แžถแž€แŸ‹แž›แžถแž€แŸ‹แž“แŸ…แž€แŸ’แž“แžปแž„ `docker-publish.yml`แŸ” แž›แžพ builder แžŠแŸ‚แž›แž˜แžถแž“ RAM แž…แŸ’แžšแžพแž“ แžŸแžผแž˜แž‡แŸ’แžšแžพแžŸแž”แŸ’แžšแžพ Turbopack แžŠแžพแž˜แŸ’แž”แžธแžฑแŸ’แž™ build แž›แžฟแž“แž‡แžถแž„แž˜แžปแž“แŸ– ```bash docker build --target runner-base \ --build-arg OMNIROUTE_USE_TURBOPACK=1 \ -t omniroute:base . ``` `webpackBuildWorker` แžแŸ’แžšแžผแžœแž”แžถแž“แž”แžพแž€ แžŠแžผแž…แŸ’แž“แŸแŸ‡ `next build` แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž‘แžถแŸ†แž„ process แž˜แŸ **แž“แžทแž„** process worker แž แžพแž™ process แž“แžธแž˜แžฝแž™แŸ—แž‚แŸ„แžšแž–แžแžถแž˜ `OMNIROUTE_BUILD_MEMORY_MB` แžŠแŸ„แž™แžกแŸ‚แž€แž–แžธแž‚แŸ’แž“แžถแŸ” แž€แŸ†แžŽแžแŸ‹แž–แŸ’แžšแŸ†แžŠแŸ‚แž“ container แžฑแŸ’แž™แžแŸ’แž–แžŸแŸ‹แž‡แžถแž„แžแž˜แŸ’แž›แŸƒแž“แŸ„แŸ‡แž”แŸ’แžšแž แŸ‚แž›แž–แžธแžšแžŠแž„ แž˜แžทแž“แž˜แŸ‚แž“แžแŸ’แžšแžนแž˜แžแŸ‚แž˜แžฝแž™แžŠแž„แž‘แŸแŸ” แž”แžถแž“แžœแžถแžŸแŸ‹แž›แžพ code tree แž“แŸแŸ‡ (`--target runner-base`, `OMNIROUTE_BUILD_MEMORY_MB=6144`)แŸ– | Bundler | แž–แŸ’แžšแŸ†แžŠแŸ‚แž“ container | แž›แž‘แŸ’แž’แž•แž› | | --------- | ----------------- | ------------------------------------------ | | Turbopack | 8 GiB / 16 GiB | แžแŸ’แžšแžผแžœแž”แžถแž“ OOM-kill แž“แŸ…แž‘แžถแŸ†แž„แž–แžธแžš แžŠแŸ„แž™แžŸแŸ’แž„แžถแžแŸ‹แžŸแŸ’แž„แŸ€แž˜ | | webpack | 8 GiB | build worker แžแŸ’แžšแžผแžœแž”แžถแž“แž”แž‰แŸ’แž…แž”แŸ‹แžŠแŸ„แž™ SIGKILL | | webpack | 12 GiB | แž‡แŸ„แž‚แž‡แŸแž™ แžŠแŸ„แž™แžกแžพแž„แžŠแž›แŸ‹แž€แž˜แŸ’แžšแžทแžแž€แŸ†แž–แžผแž› 11.1 GiB | ### แžแž˜แŸ’แž›แŸƒแž›แŸ†แž“แžถแŸ†แžŠแžพแž˜แžŸแž˜แŸ’แžšแžถแž”แŸ‹ runtime แžแž˜แŸ’แž›แŸƒแž›แŸ†แž“แžถแŸ†แžŠแžพแž˜แžŠแŸ‚แž› export แžŠแŸ„แž™ `runner-base`แŸ– `PORT=20128`, `HOSTNAME=0.0.0.0`, `OMNIROUTE_MEMORY_MB=1024`, `NODE_OPTIONS=--max-old-space-size=1024`, `DATA_DIR=/app/data`, `OMNIROUTE_MIGRATIONS_DIR=/app/migrations`แŸ” แžฅแžšแžทแž™แžถแž”แžแžขแž„แŸ’แž‚แž…แž„แž…แžถแŸ†แž“แŸ…แž€แŸ’แž“แžปแž„ DockerแŸ– - Image แž“แŸแŸ‡แž€แŸ†แžŽแžแŸ‹ `OMNIROUTE_MEMORY_MB=1024` แž แžพแž™แž‘แžถแž‰แž™แž€ `NODE_OPTIONS=--max-old-space-size=1024` แž–แžธแžœแžถแŸ” - แžŠแŸ†แžŽแžพแžšแž€แžถแžš server แž–แžทแžแž”แŸ’แžšแžถแž€แžŠแžแŸ’แžšแžผแžœแž”แžถแž“แž…แžถแž”แŸ‹แž•แŸ’แžŠแžพแž˜แžŠแŸ„แž™ standalone launcher แžŠแŸ‚แž›แžขแžถแž“ `OMNIROUTE_MEMORY_MB` แž แžพแž™แž”แž“แŸ’แžแŸ‚แž˜ `--max-old-space-size=`แŸ” - Node แž”แŸ’แžšแžพแžแž˜แŸ’แž›แŸƒ `--max-old-space-size` แžŠแŸ‚แž›แž”แžถแž“แž’แŸ’แžœแžพแž˜แŸ’แžแž„แž‘แŸ€แžแž“แŸ…แž…แžปแž„แž€แŸ’แžšแŸ„แž™ แžŠแžผแž…แŸ’แž“แŸแŸ‡แž€แžถแžšแž€แŸ†แžŽแžแŸ‹ `OMNIROUTE_MEMORY_MB` แž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแž„แžŠแŸ‚แž“แž€แŸ†แžŽแžแŸ‹ heap แž‡แžถแž€แŸ‹แžŸแŸ’แžแŸ‚แž„แžšแž”แžŸแŸ‹ DockerแŸ” - แžŠแŸ„แž™แžŸแžถแžš image แžแŸ‚แž„แžแŸ‚แž€แŸ†แžŽแžแŸ‹แžœแžถ fallback แžŠแŸ‚แž›แž€แŸ‚แžแž˜แŸ’แžšแžผแžœแžแžถแž˜ RAM แžšแž”แžŸแŸ‹ launcher แž•แŸ’แž‘แžถแž›แŸ‹แž˜แžทแž“แžŠแŸ‚แž›แžแŸ’แžšแžผแžœแž”แžถแž“แžขแž“แžปแžœแžแŸ’แžแž€แŸ’แžšแŸ„แž˜ Docker แž‘แŸแŸ” แž”แž„แŸ’แž€แžพแž“แžœแžถแžฑแŸ’แž™แž…แŸ’แž”แžถแžŸแŸ‹แž›แžถแžŸแŸ‹แžแžถแž˜ workload (แžแžถแžšแžถแž„แžแžถแž„แž€แŸ’แžšแŸ„แž˜)แŸ” `2048` แž“แŸ…แžแŸ‚แžแžผแž…แž–แŸแž€แžŸแž˜แŸ’แžšแžถแž”แŸ‹ coding-agent `/v1/responses`แŸ” ### RAM แž–แŸแž›แžŠแŸ†แžŽแžพแžšแž€แžถแžšแžŸแž˜แŸ’แžšแžถแž”แŸ‹ coding agents แžแž˜แŸ’แž›แŸƒแž›แŸ†แž“แžถแŸ†แžŠแžพแž˜ 1โ€ฏGiB แžšแž”แžŸแŸ‹ Docker แž‚แžบแž‡แžถแž€แž˜แŸ’แžšแžทแžแžขแž”แŸ’แž”แž”แžšแž˜แžถแžŸแž˜แŸ’แžšแžถแž”แŸ‹ dashboard/light-chat แž˜แžทแž“แž˜แŸ‚แž“แž‡แžถแž‘แŸ†แž แŸ†แžŸแž˜แŸ’แžšแžถแž”แŸ‹ production แž‘แŸแŸ” Body แžœแŸ‚แž„แŸ—แžšแž”แžŸแŸ‹ `POST /v1/responses` (แžŸแžถแžšแžšแžถแž”แŸ‹แžšแž™ แž“แžทแž„ tools แžšแžถแž”แŸ‹แžŸแžทแž”) แžšแž€แŸ’แžŸแžถแž‘แžปแž€แž€แŸ’แžšแžถแž แŸ’แžœแž‡แžถแž…แŸ’แžšแžพแž“แž“แŸ…แž€แŸ’แž“แžปแž„ memory แžขแŸ†แžกแžปแž„แž–แŸแž› compressionแŸ” Request แž–แžธแžšแžŠแŸ‚แž›แžแŸ’แžšแžฝแžแž‚แŸ’แž“แžถ แž“แžทแž„แž˜แžถแž“แž‘แŸ†แž แŸ†แž”แŸ’แžšแž แŸ‚แž› ~3โ€ฏMiB / ~750k-token แž”แžถแž“แž’แŸ’แžœแžพแžฑแŸ’แž™ V8 แž”แž‰แŸ’แžˆแž”แŸ‹แž“แŸ… old-space แž‘แŸ†แž แŸ† **12โ€ฏGiB** (`FATAL ERROR: Reached heap limit`) แž แžพแž™แž€แŸแž”แžถแž“แž‡แžฝแž” cgroup OOM แž‘แŸ†แž แŸ† 16โ€ฏGiB แž•แž„แžŠแŸ‚แžšแŸ” แžŸแžผแž˜แž˜แžพแž› [#7849](https://github.com/diegosouzapw/OmniRoute/issues/7849)แŸ” แž€แŸ†แžŽแžแŸ‹แž‘แŸ†แž แŸ† **cgroup `--memory` แžฑแŸ’แž™แžแŸ’แž–แžŸแŸ‹แž‡แžถแž„ heap** โ€” native buffers, SQLite แž“แžทแž„แž‘แžทแž“แŸ’แž“แž“แŸแž™แž”แžŽแŸ’แžŠแŸ„แŸ‡แžขแžถแžŸแž“แŸ’แž“แžšแž”แžŸแŸ‹ compression แžŸแŸ’แžแžทแžแž“แŸ…แž€แŸ’แžšแŸ… V8แŸ” | Workload | `OMNIROUTE_MEMORY_MB` | Container / cgroup | แž€แŸ†แžŽแžแŸ‹แžŸแž˜แŸ’แž‚แžถแž›แŸ‹ | | ------------------------------------------ | --------------------------- | ------------------------------ | -------------------------------------------------------------------------------------------------------------- | | Dashboard แž“แžทแž„ light chat แž˜แžฝแž™ | `1024` (แž›แŸ†แž“แžถแŸ†แžŠแžพแž˜แžšแž”แžŸแŸ‹ image) | โ‰ฅ2โ€ฏGiB | | | Coding agent แž˜แžฝแž™ (Claude/Codex/Grok) | `8192` | โ‰ฅ10โ€ฏGiB | `/v1/responses` แžŸแž˜แŸ’แžšแžถแž”แŸ‹ session แžแŸ‚แž˜แžฝแž™แž‡แžถแž‘แžผแž‘แŸ… | | `/v1/responses` แžœแŸ‚แž„แž–แžธแžšแžŠแŸ†แžŽแžพแžšแž€แžถแžšแž–แŸ’แžšแž˜แž‚แŸ’แž“แžถ | `10240`โ€“`12288` | โ‰ฅ12โ€“16โ€ฏGiB | แž”แžถแž“แžœแžถแžŸแŸ‹แžƒแžพแž‰แžแžถ V8 แž”แž‰แŸ’แžˆแž”แŸ‹แž“แŸ… heap แž”แŸ’แžšแž แŸ‚แž› ~12โ€ฏGiB | | Context แžœแŸ‚แž„แž”แžธ แžฌแž…แŸ’แžšแžพแž“แž‡แžถแž„แž“แŸแŸ‡แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž–แŸ’แžšแž˜แž‚แŸ’แž“แžถ | แž€แžปแŸ†แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž›แžพ process แžแŸ‚แž˜แžฝแž™ | แžŠแŸ†แžŽแžพแžšแž€แžถแžšแžแžถแž˜แž›แŸ†แžŠแžถแž”แŸ‹ / RAM แž”แž“แŸ’แžแŸ‚แž˜ | แž‡แžถแž›แŸ†แž“แžถแŸ†แžŠแžพแž˜ แž€แžถแžšแž‘แž‘แžฝแž› workload แž’แŸ’แž„แž“แŸ‹แŸ—แž€แŸ†แžŽแžแŸ‹แžแŸ’แžšแžนแž˜ 1 in-flight; แž€แžถแžšแž”แž„แŸ’แž€แžพแž“แžœแžถแžŠแŸ„แž™แž‚แŸ’แž˜แžถแž“ RAM แž“แžนแž„แž’แŸ’แžœแžพแžฑแŸ’แž™แž€แžถแžšแž”แž‰แŸ’แžˆแž”แŸ‹แž€แžพแžแžกแžพแž„แžœแžทแž‰ | `omniroute serve` แž›แžพ bare metal แž€แŸ‚แžแž˜แŸ’แžšแžผแžœแž‘แŸ…แž”แŸ’แžšแž แŸ‚แž› ~35% แž“แŸƒ RAM (แž€แŸ†แžŽแžแŸ‹แž€แŸ’แž“แžปแž„แž…แž“แŸ’แž›แŸ„แŸ‡ `[512, 4096]`) แž“แŸ…แž–แŸแž› `OMNIROUTE_MEMORY_MB` **แž˜แžทแž“แžแŸ’แžšแžผแžœแž”แžถแž“แž€แŸ†แžŽแžแŸ‹**แŸ” Docker แžแŸ‚แž„แžแŸ‚แž€แŸ†แžŽแžแŸ‹แžœแžถแž‡แžถ `1024` แžŠแžผแž…แŸ’แž“แŸแŸ‡แž€แžถแžšแž€แŸ‚แžแž˜แŸ’แžšแžผแžœแž“แŸ„แŸ‡แž˜แžทแž“แžŠแŸ‚แž›แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž“แŸ…แž€แŸ’แž“แžปแž„ image แž•แŸ’แž›แžผแžœแž€แžถแžšแž‘แŸแŸ” ```bash docker run -d --name omniroute --restart unless-stopped --stop-timeout 40 \ -e OMNIROUTE_MEMORY_MB=8192 --memory=10g \ -p 127.0.0.1:20128:20128 -v omniroute-data:/app/data diegosouzapw/omniroute:latest ``` ## แžขแžแŸแžšแž”แžšแžทแžŸแŸ’แžแžถแž“แžŸแŸ†แžแžถแž“แŸ‹แŸ— แž€แŸ’แžšแŸ…แž–แžธแžแž˜แŸ’แž›แŸƒแž›แŸ†แž“แžถแŸ†แžŠแžพแž˜แžŠแŸ‚แž›แž”แžถแž“แž…แž„แž€แŸ’แžšแž„แž‡แžถแžฏแž€แžŸแžถแžšแž“แŸ…แž€แŸ’แž“แžปแž„ [ENVIRONMENT.md](../reference/ENVIRONMENT.md) แžขแžแŸแžšแžแžถแž„แž€แŸ’แžšแŸ„แž˜แž˜แžถแž“แžŸแžถแžšแŸˆแžŸแŸ†แžแžถแž“แŸ‹แž”แŸ†แž•แžปแžแž“แŸ…แž–แŸแž›แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž€แŸ’แžšแŸ„แž˜ DockerแŸ– | แžขแžแŸแžš | แž‚แŸ„แž›แž”แŸ†แžŽแž„ | แž›แŸ†แž“แžถแŸ†แžŠแžพแž˜ | | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | | `OMNIROUTE_WS_BRIDGE_SECRET` | แž–แžถแž€แŸ’แž™แžŸแž˜แŸ’แž„แžถแžแŸ‹แžšแžฝแž˜แžŸแž˜แŸ’แžšแžถแž”แŸ‹ WebSocket bridgeแŸ” **แžแž˜แŸ’แžšแžผแžœแžฑแŸ’แž™แž˜แžถแž“แž€แŸ’แž“แžปแž„แž”แžšแžทแžŸแŸ’แžแžถแž“ production** โ€” แž€แŸ†แžŽแžแŸ‹แžœแžถแž‡แžถแžแŸ’แžŸแŸ‚แžขแž€แŸ’แžŸแžšแž…แŸƒแžŠแž“แŸ’แž™แžŠแŸ‚แž›แž˜แžถแž“แžŸแžปแžœแžแŸ’แžแžทแž—แžถแž–แžแŸ’แž–แžŸแŸ‹แŸ” | แž˜แžทแž“แž”แžถแž“แž€แŸ†แžŽแžแŸ‹ (แžแŸ’แžšแžผแžœแžแŸ‚แž•แŸ’แžแž›แŸ‹) | | `REDIS_URL` | แžแŸ’แžŸแŸ‚แžขแž€แŸ’แžŸแžšแžแž—แŸ’แž‡แžถแž”แŸ‹แžŸแž˜แŸ’แžšแžถแž”แŸ‹ rate limiter / cache backend | `redis://redis:6379` | | `REDIS_PORT` | แž…แŸ’แžšแž€แž“แŸ…แžแžถแž„ host แžŸแž˜แŸ’แžšแžถแž”แŸ‹ Redis container แžŠแŸ‚แž›แž—แŸ’แž‡แžถแž”แŸ‹แž˜แž€แž‡แžถแž˜แžฝแž™ | `6379` | | `REDIS_BIND_HOST` | host interface แžŠแŸ‚แž›แž…แŸ’แžšแž€ Redis แž—แŸ’แž‡แžถแž”แŸ‹แž˜แž€แž‡แžถแž˜แžฝแž™แžแŸ’แžšแžผแžœแž”แžถแž“แžŠแžถแž€แŸ‹แžฑแŸ’แž™แž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹แž›แžพแžœแžถ (loopback แž›แžปแŸ‡แžแŸ’แžšแžถแžแŸ‚แžขแŸ’แž“แž€แž”แž“แŸ’แžแŸ‚แž˜ AUTH) | `127.0.0.1` | | `AUTO_UPDATE_HOST_REPO_DIR` | path แžšแž”แžŸแŸ‹ host แžŠแŸ‚แž›แž”แžถแž“ mount แž‘แŸ…แž€แŸ’แž“แžปแž„ profile `cli` แž“แŸ… `/workspace/omniroute` แžŸแž˜แŸ’แžšแžถแž”แŸ‹ workflow แž’แŸ’แžœแžพแž”แž…แŸ’แž…แžปแž”แŸ’แž”แž“แŸ’แž“แž—แžถแž–แžŠแŸ„แž™แžแŸ’แž›แžฝแž“แžฏแž„ | `.` (แžแžแž”แž…แŸ’แž…แžปแž”แŸ’แž”แž“แŸ’แž“) | | `OMNIROUTE_MEMORY_MB` | แž€แž˜แŸ’แžšแžทแžแžขแžแžทแž”แžšแž˜แžถ Node heap แž“แŸ… runtime แžŸแž˜แŸ’แžšแžถแž”แŸ‹ Docker standalone server; แžœแžถแž‡แŸ†แž“แžฝแžŸแžแž˜แŸ’แž›แŸƒแž›แŸ†แž“แžถแŸ†แžŠแžพแž˜แžšแž”แžŸแŸ‹ image แžแžถแž„แž›แžพแŸ” แžŸแž˜แŸ’แžšแžถแž”แŸ‹ coding agentsแŸ– `8192`+ (แžŸแžผแž˜แž˜แžพแž› [RAM แž“แŸ… runtime](#runtime-ram-for-coding-agents))แŸ” | `1024` | | `DASHBOARD_PORT` / `API_PORT` | แž€แŸ†แžŽแžแŸ‹แž…แŸ’แžšแž€แžŠแŸ‚แž›แž”แžพแž€แž”แž„แŸ’แž แžถแž‰แžŸแž˜แŸ’แžšแžถแž”แŸ‹ dashboard (20128) แž“แžทแž„ API (20129) แž‡แŸ†แž“แžฝแžŸแžแž˜แŸ’แž›แŸƒแž›แŸ†แž“แžถแŸ†แžŠแžพแž˜ | `20128` / `20129` | | `APP_BIND_HOST` | host interface แžŠแŸ‚แž› docker-compose แž”แžพแž€แž•แŸ’แžŸแžถแž™แž…แŸ’แžšแž€ dashboard/API/live-WS แž›แžพแžœแžถแŸ” แž‡แžถแž˜แžฝแž™ `REQUIRE_API_KEY=false` (แžแž˜แŸ’แž›แŸƒแž›แŸ†แž“แžถแŸ†แžŠแžพแž˜) `0.0.0.0` แž“แžนแž„แž”แžพแž€ anonymous proxy `/v1` แž‘แŸ…แž€แžถแž“แŸ‹ LAN โ€” แž‚แžฝแžšแž–แž„แŸ’แžšแžธแž€แž€แžถแžšแž…แžผแž›แž”แŸ’แžšแžพแžแŸ‚แž“แŸ…แž–แŸแž›แž”แŸ’แžšแžพ `REQUIRE_API_KEY=true` แžฌแž˜แžถแž“ reverse proxy แž“แŸ…แžแžถแž„แž˜แžปแžแŸ” | `127.0.0.1` | | `CLIPROXY_BIND_HOST` | host interface แžŠแŸ‚แž› docker-compose แž”แžพแž€แž•แŸ’แžŸแžถแž™ sidecar `cliproxyapi` แž›แžพแžœแžถ โ€” data volume แžšแž”แžŸแŸ‹แžœแžถแž•แŸ’แž‘แžปแž€แž–แŸแžแŸŒแž˜แžถแž“แžŸแž˜แŸ’แž‚แžถแž›แŸ‹แžขแžแŸ’แžแžŸแž‰แŸ’แž‰แžถแžŽแžšแž”แžŸแŸ‹ providerแŸ” | `127.0.0.1` | | `OMNIROUTE_PLUGINS_DIR` | แžแžแžŠแŸ‚แž› runtime plugin scanner แžขแžถแž“ แž“แžทแž„แžŠแŸ†แžกแžพแž„ plugin แž‘แŸ…แž€แŸ’แž“แžปแž„แŸ” แž€แŸ†แžŽแžแŸ‹แžœแžถแž“แŸ…แž–แŸแž› plugin แžแŸ’แžšแžผแžœแž”แžถแž“ bind-mountแŸ– แžแž˜แŸ’แž›แŸƒแž›แŸ†แž“แžถแŸ†แžŠแžพแž˜แžขแžถแžŸแŸ’แžšแŸแž™แžแžถแž˜ `HOME` แžŠแŸ‚แž› image แž˜แžทแž“แž…แžถแŸ†แž”แžถแž…แŸ‹ export แž“แŸ„แŸ‡แž‘แŸแŸ” | `~/.omniroute/plugins` | | `OMNIROUTE_BASE_PATH` | URL subpath แž“แŸ…แž–แŸแž› app แžแŸ’แžšแžผแžœแž”แžถแž“แž”แžพแž€แž•แŸ’แžŸแžถแž™แž“แŸ…แž–แžธแž€แŸ’แžšแŸ„แž™ reverse proxy (แžง. `/omniroute`) | _(แž‘แž‘แŸ = root)_ | | `NEXT_PUBLIC_BASE_URL` | origin แžŸแžถแž’แžถแžšแžŽแŸˆแžŸแž˜แŸ’แžšแžถแž”แŸ‹ browser แžŠแŸ‚แž›แžšแžฝแž˜แž”แž‰แŸ’แž…แžผแž› subpath (แžง. `https://host/omniroute`) | แž˜แžทแž“แž”แžถแž“แž€แŸ†แžŽแžแŸ‹ | | `PROD_DASHBOARD_PORT` | แž…แŸ’แžšแž€ dashboard แž“แŸ…แžแžถแž„ host แžŸแž˜แŸ’แžšแžถแž”แŸ‹ `docker-compose.prod.yml` | `20130` | | `CLIPROXYAPI_PORT` | แž…แŸ’แžšแž€แž“แŸ…แžแžถแž„ host แžŸแž˜แŸ’แžšแžถแž”แŸ‹ sidecar `cliproxyapi` | `8317` | ## แž”แŸ’แžšแžผแž€แžŸแŸŠแžธแž”แž‰แŸ’แž…แŸ’แžšแžถแžŸแž›แžพแž•แŸ’แž›แžผแžœแžšแž„ (Traefik / nginx) `basePath` แžšแž”แžŸแŸ‹ Next.js แžแŸ’แžšแžผแžœแž”แžถแž“แž…แž„แž€แŸ’แžšแž„แž”แž‰แŸ’แž…แžผแž›แž‘แŸ…แž€แŸ’แž“แžปแž„แž”แžŽแŸ’แžŠแžปแŸ† standaloneแŸ” OmniRoute แž€แžแŸ‹แžแŸ’แžšแžถแžแž˜แŸ’แž›แŸƒแžŠแŸ‚แž›แž”แžถแž“แž”แž„แŸ’แž€แž”แŸ‹แž“แŸแŸ‡แž“แŸ…แž€แŸ’แž“แžปแž„แžฏแž€แžŸแžถแžš sentinel แž˜แžฝแž™แž“แŸ…แžแžแž‚แŸ„แž›แžšแž”แžŸแŸ‹แž€แž˜แŸ’แž˜แžœแžทแž’แžธ (แžŸแžšแžŸแŸแžšแž€แŸ’แž“แžปแž„แžขแŸ†แžกแžปแž„แž–แŸแž› `npm run build`; แžขแžถแž“แžŠแŸ„แž™ `scripts/docker/ensure-docker-base-path.mjs`) แž แžพแž™แž”แŸ’แžšแŸ€แž”แž’แŸ€แž”แžœแžถแž‡แžถแž˜แžฝแž™ `OMNIROUTE_BASE_PATH` แž“แŸ…แž–แŸแž› container แž…แžถแž”แŸ‹แž•แŸ’แžŠแžพแž˜แŸ” แž“แŸ…แž–แŸแž›แžแž˜แŸ’แž›แŸƒแž‘แžถแŸ†แž„แž–แžธแžšแžแžปแžŸแž‚แŸ’แž“แžถ แž แžพแž™ image แžแŸ’แžšแžผแžœแž”แžถแž“ build แžŸแž˜แŸ’แžšแžถแž”แŸ‹แžแžแž‚แŸ„แž›แžšแž”แžŸแŸ‹แžŠแŸ‚แž“ entrypoint แž“แžนแž„แžŸแžšแžŸแŸแžšแžกแžพแž„แžœแžทแž‰แž“แžผแžœ manifest แžšแž”แžŸแŸ‹ standalone, literal `basePath`/`assetPrefix` แžŠแŸ‚แž›แž”แžถแž“แž”แž„แŸ’แž€แž”แŸ‹ (Next 16 แž”แž„แŸ’แž แžถแž‰ URL asset แžšแž”แžŸแŸ‹ SSR แž–แžธ `assetPrefix` แžแŸ‚แž”แŸ‰แžปแžŽแŸ’แžŽแŸ„แŸ‡ โ€” patcher แž…แž˜แŸ’แž›แž„แž•แŸ’แž›แžผแžœแžšแž„แž‘แŸ…แž€แŸ’แž“แžปแž„แžœแžถแž•แž„แžŠแŸ‚แžš), URL asset `/_next/static` แžŠแŸ‚แž›แž”แžถแž“แž”แž„แŸ’แž€แž”แŸ‹ (manifest แž™แŸ„แž„แžšแž”แžŸแŸ‹ client, แž€แžถแžšแž“แžถแŸ†แž…แžผแž› media, แž‘แŸ†แž–แŸแžšแž€แŸ†แž แžปแžŸแžŠแŸ‚แž›แž”แžถแž“ render แž‡แžถแž˜แžปแž“) แž“แžทแž„ shim `process.env` แžšแž”แžŸแŸ‹ client แž˜แžปแž“แž–แŸแž› `node dev/run-standalone.mjs` แžŠแŸ†แžŽแžพแžšแž€แžถแžšแŸ” ### แž€แžถแžš build แžŠแŸ„แž™ Compose (แž”แžถแž“แžŽแŸ‚แž“แžถแŸ†) แž€แŸ†แžŽแžแŸ‹แžขแžแŸแžšแž‘แžถแŸ†แž„แž–แžธแžšแž“แŸ…แž€แŸ’แž“แžปแž„ `.env` แž”แž“แŸ’แž‘แžถแž”แŸ‹แž˜แž€ build แžกแžพแž„แžœแžทแž‰ แžŠแžพแž˜แŸ’แž”แžธแžฑแŸ’แž™ image แž“แžทแž„ runtime แžแŸ’แžšแžผแžœแž‚แŸ’แž“แžถแŸ– ```bash # .env OMNIROUTE_BASE_PATH=/omniroute NEXT_PUBLIC_BASE_URL=https://myhostname.example.com/omniroute ``` ```bash docker compose --profile base up -d --build ``` `docker-compose.yml` แž”แž‰แŸ’แž‡แžผแž“แž”แž“แŸ’แž `OMNIROUTE_BASE_PATH` แž‡แžถ Docker build-arg แž“แžทแž„แž‡แžถแžขแžแŸแžšแž”แžšแžทแžŸแŸ’แžแžถแž“ runtimeแŸ” ### Root image แžŠแŸ‚แž›แž”แžถแž“ build แž‡แžถแž˜แžปแž“ + แž•แŸ’แž›แžผแžœแžšแž„ runtime Image `diegosouzapw/omniroute:*` แžŠแŸ‚แž›แž”แžถแž“แž…แŸแž‰แž•แŸ’แžŸแžถแž™ แžแŸ’แžšแžผแžœแž”แžถแž“ build แžŸแž˜แŸ’แžšแžถแž”แŸ‹แžแžแž‚แŸ„แž›แžšแž”แžŸแŸ‹แžŠแŸ‚แž“แŸ” แžขแŸ’แž“แž€แž“แŸ…แžแŸ‚แžขแžถแž…แž€แŸ†แžŽแžแŸ‹ `OMNIROUTE_BASE_PATH` แž“แŸ…แž–แŸแž› runtime แž”แžถแž“; container แž“แžนแž„ patch แž”แžŽแŸ’แžŠแžปแŸ†แž˜แŸ’แžŠแž„แž“แŸ…แž–แŸแž›แž…แžถแž”แŸ‹แž•แŸ’แžŠแžพแž˜แŸ” แž”แŸ’แžšแžพแžœแžถแž‚แžผแž‡แžถแž˜แžฝแž™ public origin แžŠแŸ‚แž›แžแŸ’แžšแžผแžœแž‚แŸ’แž“แžถแŸ– ```yaml services: omniroute: image: diegosouzapw/omniroute:latest environment: OMNIROUTE_BASE_PATH: /omniroute NEXT_PUBLIC_BASE_URL: https://myhostname.example.com/omniroute ``` แž€แŸ†แžŽแžแŸ‹แžšแž…แž“แžถแžŸแž˜แŸ’แž–แŸแž“แŸ’แž’แž”แŸ’แžšแžผแž€แžŸแŸŠแžธแž”แž‰แŸ’แž…แŸ’แžšแžถแžŸแžฑแŸ’แž™แž”แž‰แŸ’แž‡แžผแž“แž”แž“แŸ’แžแž•แŸ’แž›แžผแžœแžแžถแž„แž€แŸ’แžšแŸ… **แž‘แžถแŸ†แž„แž˜แžผแž›** (แž€แžปแŸ†แžŠแž€แž”แžปแž–แŸ’แžœแž”แž‘แž…แŸแž‰)แŸ” Traefik แž‚แžฝแžšแžแŸ‚แž”แž‰แŸ’แž‡แžผแž“ `PathPrefix(`/omniroute`)` แž‘แŸ…แž€แžถแž“แŸ‹ container แžŠแŸ„แž™แž‚แŸ’แž˜แžถแž“ `StripPrefix` แžŠแžผแž…แŸ’แž“แŸแŸ‡ Next.js แž“แžนแž„แž‘แž‘แžฝแž›แž”แžถแž“ `/omniroute/...` แž“แžทแž„แž•แŸ’แžŠแž›แŸ‹ asset แž–แžธ `/omniroute/_next/...`แŸ” Docker healthcheck แž–แžทแž“แžทแžแŸ’แž™ endpoint lifecycle แžŸแŸ’แžšแžถแž› `/healthz` แžŠแŸ‚แž›แž˜แžถแž“แž”แžปแž–แŸ’แžœแž”แž‘แž‡แžถ `OMNIROUTE_BASE_PATH` แž€แŸ†แž–แžปแž„แž”แŸ’แžšแžพแŸ” `/api/monitoring/health` แž“แŸ…แžแŸ‚แžขแžถแž…แž”แŸ’แžšแžพแž”แžถแž“แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แžถแžšแž’แŸ’แžœแžพแžšแŸ„แž‚แžœแžทแž“แžทแž…แŸ’แž†แŸแž™แžŠแŸ„แž™แž˜แž“แžปแžŸแŸ’แžŸ/dashboard; แžŠแžพแž˜แŸ’แž”แžธแž€แŸ†แžŽแžแŸ‹แžฑแŸ’แž™ HEALTHCHECK แžšแž”แžŸแŸ‹ container แžแŸ’แžšแžกแž”แŸ‹แž‘แŸ…แž–แžทแž“แžทแžแŸ’แž™แžœแžถแžœแžทแž‰ (แžงแž‘แžถแž แžšแžŽแŸ แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แžถแžšแžขแž“แžปแžœแžแŸ’แžแž€แžถแžšแžแŸ’แžšแžฝแžแž–แžทแž“แžทแžแŸ’แž™แžŸแžปแžแž—แžถแž–แžŸแŸŠแžธแž‡แž˜แŸ’แžšแŸ…) แžŸแžผแž˜แž€แŸ†แžŽแžแŸ‹ `OMNIROUTE_HEALTHCHECK_PATH=/api/monitoring/health`แŸ” แž•แŸ’แž›แžผแžœแž“แŸ„แŸ‡แž‚แžบแž‡แžถแž€แžถแžšแžแŸ’แžšแžฝแžแž–แžทแž“แžทแžแŸ’แž™ **แžŸแŸŠแžธแž‡แž˜แŸ’แžšแŸ…** (DB + แžŸแŸแž…แž€แŸ’แžŠแžธแžŸแž„แŸ’แžแŸแž”แž€แžถแžšแžแŸ’แžšแžฝแžแž–แžทแž“แžทแžแŸ’แž™) โ€” แžŸแž˜แžŸแŸ’แžšแž”แžŸแž˜แŸ’แžšแžถแž”แŸ‹ `HEALTHCHECK` แžŠแŸ‚แž›แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž˜แžทแž“แž‰แžนแž€แž‰แžถแž”แŸ‹แžšแž”แžŸแŸ‹ Docker แž”แŸ’แžšแžŸแžทแž“แž”แžพแžขแŸ’แž“แž€แž‡แŸ’แžšแžพแžŸแžšแžพแžŸแž”แŸ’แžšแžพแžœแžถแžœแžทแž‰ แž”แŸ‰แžปแž“แŸ’แžแŸ‚ **แž˜แžทแž“แžŸแž˜แžŸแŸ’แžšแž”** แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž…แž“แŸ’แž›แŸ„แŸ‡แž–แŸแž› `livenessProbe` แžšแž”แžŸแŸ‹ Kubernetes แž‘แŸแŸ” แžŸแž˜แŸ’แžšแžถแž”แŸ‹ orchestrator (Kubernetes, Nomad แž‡แžถแžŠแžพแž˜)แŸ– | Probe | แž‚แžฝแžšแž”แŸ’แžšแžพ | แž‚แžฝแžšแž‡แŸ€แžŸแžœแžถแž„ | | --------------- | ---------------------------------------------------------------- | ------------------------------------------------------- | | Liveness | HTTP `GET /livez` แžฌ TCP แž›แžพ port แž…แž˜แŸ’แž”แž„ (`PORT`, แž›แŸ†แž“แžถแŸ†แžŠแžพแž˜ `20128`) | แž€แžถแžšแž”แŸ’แžšแžพ `/api/monitoring/health` แž‡แžถ liveness | | Readiness | HTTP `GET /healthz` | timeout แžแŸ’แž›แžธแž–แŸแž€แžŠแŸ‚แž›แž…แžถแžแŸ‹แž‘แžปแž€ event-loop แžŠแŸ‚แž›แžšแžœแž›แŸ‹แžแžถแž”แžถแž“แžŸแŸ’แž›แžถแž”แŸ‹ | | Deep / blackbox | `/api/monitoring/health` | โ€” | `/healthz` แžšแžถแž™แž€แžถแžšแžŽแŸแž–แžธ lifecycle แžšแž”แžŸแŸ‹ process (`ok` / `starting` / `stopping`)แŸ” `/livez` แž–แžทแž“แžทแžแŸ’แž™แžแŸ‚แžแžถ process แž“แŸ…แžŠแŸ†แžŽแžพแžšแž€แžถแžš (200 แžšแžถแž›แŸ‹แž–แŸแž› handler แžขแžถแž…แžŠแŸ†แžŽแžพแžšแž€แžถแžš; แžœแžถแž˜แžทแž“แžšแž„แŸ‹แž…แžถแŸ† readiness แž‘แŸ)แŸ” แž‘แžถแŸ†แž„แž–แžธแžšแž“แŸ…แžแŸ‚แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž›แžพ Node event loop แžŠแžผแž…แž‚แŸ’แž“แžถแž“แžนแž„แž€แžถแžšแžŠแŸ„แŸ‡แžŸแŸ’แžšแžถแž™ request แžŠแžผแž…แŸ’แž“แŸแŸ‡แž€แžถแžšแž„แžถแžš catalog แžฌ compression แžŠแŸ‚แž›แž”แŸ’แžšแžพ CPU แžแŸ’แž›แžถแŸ†แž„ แžขแžถแž…แž’แŸ’แžœแžพแžฑแŸ’แž™แžœแžถแž™แžบแž โ€” แžšแžœแž›แŸ‹ โ‰  แžŸแŸ’แž›แžถแž”แŸ‹แŸ” แž‚แžฝแžšแž”แŸ’แžšแžพ TCP liveness แž”แŸ’แžšแžŸแžทแž“แž”แžพ HTTP probe แžขแžŸแŸ‹แž–แŸแž›แŸ” แž€แžถแžšแžŽแŸ‚แž“แžถแŸ†แž–แŸแž‰แž›แŸแž‰แžขแŸ†แž–แžธ probeแŸ– [แž˜แž‚แŸ’แž‚แžปแž‘แŸ’แž‘แŸแžŸแž€แŸแž€แžถแžšแžแŸ’แžšแžฝแžแž–แžทแž“แžทแžแŸ’แž™ โ€” แžขแž“แžปแžŸแžถแžŸแž“แŸแžขแŸ†แž–แžธ probe แžšแž”แžŸแŸ‹ Kubernetes](../ops/MONITORING_GUIDE.md#kubernetes-probe-recommendations)แŸ” ## Docker Compose แž‡แžถแž˜แžฝแž™ Caddy (HTTPS Auto-TLS) OmniRoute แžขแžถแž…แžแŸ’แžšแžผแžœแž”แžถแž“แžŠแžถแž€แŸ‹แžฑแŸ’แž™แž…แžผแž›แž”แŸ’แžšแžพแžŠแŸ„แž™แžŸแžปแžœแžแŸ’แžแžทแž—แžถแž– แžŠแŸ„แž™แž”แŸ’แžšแžพแž€แžถแžšแž•แŸ’แžŠแž›แŸ‹ SSL แžŠแŸ„แž™แžŸแŸ’แžœแŸแž™แž”แŸ’แžšแžœแžแŸ’แžแžทแžšแž”แžŸแŸ‹ CaddyแŸ” แžŸแžผแž˜แž”แŸ’แžšแžถแž€แžŠแžแžถ DNS A record แžšแž”แžŸแŸ‹แžŠแŸ‚แž“แžขแŸ’แž“แž€แž…แž„แŸ’แžขแžปแž›แž‘แŸ…แž€แžถแž“แŸ‹แžขแžถแžŸแž™แžŠแŸ’แž‹แžถแž“ IP แžšแž”แžŸแŸ‹แž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แŸแžขแŸ’แž“แž€แŸ” ```yaml services: omniroute: image: diegosouzapw/omniroute:latest container_name: omniroute restart: unless-stopped volumes: - omniroute-data:/app/data environment: - PORT=20128 # แž”แŸ’แžšแž—แž–แžŠแžพแž˜แžŠแŸ‚แž›แž”แž„แŸ’แž แžถแž‰แž…แŸ†แž–แŸ„แŸ‡แž€แž˜แŸ’แž˜แžœแžทแž’แžธแžšแžปแž€แžšแž€ แžŸแž˜แŸ’แžšแžถแž”แŸ‹ OAuth callbacks แžแŸ†แžŽแž•แŸ’แž‘แžถแŸ†แž„แž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแž„ แž“แžทแž„ URL แžŸแžถแž’แžถแžšแžŽแŸˆแžŠแŸ‚แž›แž”แžถแž“แž”แž„แŸ’แž€แžพแžแŸ” - NEXT_PUBLIC_BASE_URL=https://your-domain.com # URL แžแžถแž„แž€แŸ’แž“แžปแž„แž–แžธแž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แŸแž‘แŸ…แž˜แŸ‰แžถแžŸแŸŠแžธแž“แž˜แŸ แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แžถแžšแž„แžถแžšแžŠแŸ‚แž›แž”แžถแž“แž€แŸ†แžŽแžแŸ‹แž–แŸแž› / แž€แžถแžšแž‘แžถแž‰แž™แž€แžŠแŸ„แž™แžแŸ’แž›แžฝแž“แžฏแž„แŸ” - BASE_URL=http://omniroute:20128 - AUTH_COOKIE_SECURE=true caddy: image: caddy:latest container_name: caddy restart: unless-stopped ports: - "80:80" - "443:443" command: caddy reverse-proxy --from https://your-domain.com --to http://omniroute:20128 volumes: omniroute-data: ``` Caddy แž€แŸ†แžŽแžแŸ‹ forwarding headers แžŸแŸ’แžแž„แŸ‹แžŠแžถแžšแžŸแž˜แŸ’แžšแžถแž”แŸ‹ container แžแžถแž„แžŠแžพแž˜แŸ” OmniRoute แž”แŸ’แžšแžพ `NEXT_PUBLIC_BASE_URL` แž‡แžถแž”แŸ’แžšแž—แž–แžŠแžพแž˜แžŸแžถแž’แžถแžšแžŽแŸˆแž•แŸ’แž›แžผแžœแž€แžถแžšแžŸแž˜แŸ’แžšแžถแž”แŸ‹ OAuth callbacks แž“แžทแž„แžแŸ†แžŽแžŸแžถแž’แžถแžšแžŽแŸˆ แžŠแŸ‚แž›แž”แžถแž“แž”แž„แŸ’แž€แžพแžแŸ” แž€แžถแžšแžŸแžšแžŸแŸแžšแžŠแŸ‚แž›แž”แžถแž“แž•แŸ’แž‘แŸ€แž„แž•แŸ’แž‘แžถแžแŸ‹แž‘แŸ…แž•แŸ’แž‘แžถแŸ†แž„แž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแž„ แž”แŸ’แžšแžพแžŸแŸ†แžŽแžพ same-origin แžšแžฝแž˜แž‡แžถแž˜แžฝแž™แž€แžถแžšแž€แžถแžšแž–แžถแžš CSRF แžŠแŸ‚แž›แž—แŸ’แž‡แžถแž”แŸ‹แž“แžนแž„ sessionแŸ” แž”แžพแž€แž”แŸ’แžšแžพ `OMNIROUTE_TRUST_PROXY` แžแŸ‚แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แžถแžšแžŠแžถแž€แŸ‹แžฑแŸ’แž™แž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹แž€แž˜แŸ’แžšแžทแžแžแŸ’แž–แžŸแŸ‹ แžŠแŸ‚แž›แžขแŸ’แž“แž€แž˜แžถแž“แž”แŸ†แžŽแž„ แžฑแŸ’แž™ OmniRoute แž€แŸ†แžŽแžแŸ‹แž”แŸ’แžšแž—แž–แžŠแžพแž˜แžŸแžถแž’แžถแžšแžŽแŸˆแž–แžธ forwarded headers แžŠแŸ‚แž›แž‘แžปแž€แž…แžทแžแŸ’แž แž‡แŸ†แž“แžฝแžŸแžฑแŸ’แž™แž€แžถแžšแž€แŸ†แžŽแžแŸ‹แžšแž…แž“แžถแžŸแž˜แŸ’แž–แŸแž“แŸ’แž’ แž‡แžถแž€แŸ‹แž›แžถแž€แŸ‹แŸ” ## Cloudflare Quick Tunnel แž€แžถแžšแž‚แžถแŸ†แž‘แŸ’แžšแž•แŸ’แž‘แžถแŸ†แž„แž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแž„แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แžถแžšแžŠแžถแž€แŸ‹แžฑแŸ’แž™แž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹แžแžถแž˜ Docker แžšแžฝแž˜แž”แž‰แŸ’แž…แžผแž› **Cloudflare Quick Tunnel** แžŠแŸ‚แž›แžขแžถแž…แž”แžพแž€แžŠแŸ„แž™แž…แžปแž…แžแŸ‚แž˜แžฝแž™แžŠแž„แž“แŸ…แž›แžพ `Dashboard โ†’ Endpoints`แŸ” แž€แžถแžšแž”แžพแž€แž”แŸ’แžšแžพแž›แžพแž€แžŠแŸ†แž”แžผแž„แž“แžนแž„แž‘แžถแž‰แž™แž€ `cloudflared` แžแŸ‚แž“แŸ…แž–แŸแž›แž…แžถแŸ†แž”แžถแž…แŸ‹ แž”แžพแž€แžŠแŸ†แžŽแžพแžšแž€แžถแžš tunnel แž”แžŽแŸ’แžŠแŸ„แŸ‡แžขแžถแžŸแž“แŸ’แž“แž‘แŸ…แž€แžถแž“แŸ‹ endpoint `/v1` แž”แž…แŸ’แž…แžปแž”แŸ’แž”แž“แŸ’แž“แžšแž”แžŸแŸ‹แžขแŸ’แž“แž€ แž“แžทแž„แž”แž„แŸ’แž แžถแž‰ URL `https://*.trycloudflare.com/v1` แžŠแŸ‚แž›แž”แžถแž“แž”แž„แŸ’แž€แžพแž แžŠแŸ„แž™แž•แŸ’แž‘แžถแž›แŸ‹แž“แŸ…แžแžถแž„แž€แŸ’แžšแŸ„แž˜ URL แžŸแžถแž’แžถแžšแžŽแŸˆแž’แž˜แŸ’แž˜แžแžถแžšแž”แžŸแŸ‹แžขแŸ’แž“แž€แŸ” แž•แŸ’แž‘แžถแŸ†แž„ tunnel แžšแž”แžŸแŸ‹ endpoint (Cloudflare, Tailscale, ngrok) แžขแžถแž…แžแŸ’แžšแžผแžœแž”แžถแž“แž”แž„แŸ’แž แžถแž‰ แžฌแž›แžถแž€แŸ‹แž–แžธ `Settings โ†’ Appearance` แžŠแŸ„แž™แž˜แžทแž“แž•แŸ’แž›แžถแžŸแŸ‹แž”แŸ’แžŠแžผแžšแžŸแŸ’แžแžถแž“แž—แžถแž– tunnel แžŠแŸ‚แž›แž€แŸ†แž–แžปแž„แžŸแž€แž˜แŸ’แž˜แŸ” ### แž€แŸ†แžŽแžแŸ‹แžŸแž˜แŸ’แž‚แžถแž›แŸ‹แžขแŸ†แž–แžธ Tunnel - URL แžšแž”แžŸแŸ‹ Quick Tunnel แž‚แžบแž”แžŽแŸ’แžŠแŸ„แŸ‡แžขแžถแžŸแž“แŸ’แž“ แž แžพแž™แž•แŸ’แž›แžถแžŸแŸ‹แž”แŸ’แžŠแžผแžšแž”แž“แŸ’แž‘แžถแž”แŸ‹แž–แžธแž€แžถแžšแž…แžถแž”แŸ‹แž•แŸ’แžŠแžพแž˜แžกแžพแž„แžœแžทแž‰แžšแžถแž›แŸ‹แž›แžพแž€แŸ” - Quick Tunnels แž˜แžทแž“แžแŸ’แžšแžผแžœแž”แžถแž“แžŸแŸ’แžŠแžถแžšแžกแžพแž„แžœแžทแž‰แžŠแŸ„แž™แžŸแŸ’แžœแŸแž™แž”แŸ’แžšแžœแžแŸ’แžแžท แž”แž“แŸ’แž‘แžถแž”แŸ‹แž–แžธ OmniRoute แžฌ container แž…แžถแž”แŸ‹แž•แŸ’แžŠแžพแž˜แžกแžพแž„แžœแžทแž‰แž‘แŸแŸ” แž”แžพแž€แž–แžฝแž€แžœแžถแžกแžพแž„แžœแžทแž‰แž–แžธแž•แŸ’แž‘แžถแŸ†แž„แž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแž„แž“แŸ…แž–แŸแž›แž…แžถแŸ†แž”แžถแž…แŸ‹แŸ” - แž€แžถแžšแžŠแŸ†แžกแžพแž„แžŠแŸ‚แž›แž”แžถแž“แž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแž„ แž”แž…แŸ’แž…แžปแž”แŸ’แž”แž“แŸ’แž“แž‚แžถแŸ†แž‘แŸ’แžš Linux, macOS แž“แžทแž„ Windows แž›แžพ `x64` / `arm64`แŸ” - Managed Quick Tunnels แž”แŸ’แžšแžพ HTTP/2 transport แžแžถแž˜แž›แŸ†แž“แžถแŸ†แžŠแžพแž˜ แžŠแžพแž˜แŸ’แž”แžธแž‡แŸ€แžŸแžœแžถแž„แž€แžถแžšแž–แŸ’แžšแž˜แžถแž“แžขแŸ†แž–แžธ QUIC UDP buffer แžŠแŸ‚แž›แžšแŸ†แžแžถแž“ แž“แŸ…แž€แŸ’แž“แžปแž„แž”แžšแžทแžŸแŸ’แžแžถแž“ container แžŠแŸ‚แž›แž˜แžถแž“แž’แž“แž’แžถแž“แž€แŸ†แžŽแžแŸ‹แŸ” แž€แŸ†แžŽแžแŸ‹ `CLOUDFLARED_PROTOCOL=quic` แžฌ `auto` แž”แŸ’แžšแžŸแžทแž“แž”แžพแžขแŸ’แž“แž€แž…แž„แŸ‹แž”แŸ’แžšแžพ transport แž•แŸ’แžŸแŸแž„แŸ” - Docker images แžšแžฝแž˜แž”แž‰แŸ’แž…แžผแž› system CA roots แž“แžทแž„แž”แž‰แŸ’แž‡แžผแž“แž–แžฝแž€แžœแžถแž‘แŸ…แžฑแŸ’แž™ `cloudflared` แžŠแŸ‚แž›แž”แžถแž“แž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแž„ แžŠแžพแž˜แŸ’แž”แžธแž‡แŸ€แžŸแžœแžถแž„แž”แž‰แŸ’แž แžถแž”แžšแžถแž‡แŸแž™แž“แŸƒแž€แžถแžšแž‘แžปแž€แž…แžทแžแŸ’แž TLS แž“แŸ…แž–แŸแž› tunnel แž…แžถแž”แŸ‹แž•แŸ’แžŠแžพแž˜แž“แŸ…แž€แŸ’แž“แžปแž„ containerแŸ” - แž€แŸ†แžŽแžแŸ‹ `CLOUDFLARED_BIN=/absolute/path/to/cloudflared` แž”แŸ’แžšแžŸแžทแž“แž”แžพแžขแŸ’แž“แž€แž…แž„แŸ‹แžฑแŸ’แž™ OmniRoute แž”แŸ’แžšแžพ binary แžŠแŸ‚แž›แž˜แžถแž“แžŸแŸ’แžšแžถแž”แŸ‹ แž‡แŸ†แž“แžฝแžŸแžฑแŸ’แž™แž€แžถแžšแž‘แžถแž‰แž™แž€แžแŸ’แž˜แžธแž˜แžฝแž™แŸ” ## แžŸแŸ’แž›แžถแž€ Image | Image | แžŸแŸ’แž›แžถแž€ | แž‘แŸ†แž แŸ† | แžŸแŸแž…แž€แŸ’แžŠแžธแž–แžทแž–แžŽแŸŒแž“แžถ | | ------------------------ | -------- | ------ | ------------------------------------------------------------------------- | | `diegosouzapw/omniroute` | `latest` | ~250MB | SemVer แž˜แžถแž“แžŸแŸ’แžแžทแžšแž—แžถแž–แžŠแŸ‚แž›แž”แžถแž“ **แž”แŸ„แŸ‡แž–แžปแž˜แŸ’แž–แž•แŸ’แžŸแžถแž™** แžแŸ’แž–แžŸแŸ‹แž”แŸ†แž•แžปแž (แž˜แžทแž“แž˜แŸ‚แž“ git `main`) | | `diegosouzapw/omniroute` | `3.8.0` | ~250MB | แž…แžถแž€แŸ‹แžŸแŸ„แžŸแŸ’แž›แžถแž€แž”แŸ’แžšแž—แŸแž‘แž“แŸแŸ‡แžŸแž˜แŸ’แžšแžถแž”แŸ‹ GitOps | Manifest แž–แž แžปแžœแŸแž‘แžทแž€แžถแŸ– `linux/amd64` + `linux/arm64` แžŠแžพแž˜ (Apple Silicon, AWS Graviton, Raspberry Pi)แŸ” Docker แž‡แŸ’แžšแžพแžŸแžšแžพแžŸแžŸแŸ’แžแžถแž”แžแŸ’แž™แž€แž˜แŸ’แž˜แžŠแŸ‚แž›แžแŸ’แžšแžผแžœแž‚แŸ’แž“แžถแžŠแŸ„แž™แžŸแŸ’แžœแŸแž™แž”แŸ’แžšแžœแžแŸ’แžแžทแŸ” แž”แž‰แŸ’แž‡แžผแž“ `--platform linux/amd64` แž”แŸ’แžšแžŸแžทแž“แž”แžพแžขแŸ’แž“แž€แžแŸ’แžšแžผแžœแž€แžถแžšแž”แž„แŸ’แžแŸ†แžฑแŸ’แž™แž’แŸ’แžœแžพ AMD64 emulation แž“แŸ…แž›แžพ ARM hostsแŸ” ### แž”แžŽแŸ’แžŠแžถแž‰แž…แŸแž‰แž•แŸ’แžŸแžถแž™ OmniRoute แž”แŸ„แŸ‡แž–แžปแž˜แŸ’แž–แž•แŸ’แžŸแžถแž™แž”แžŽแŸ’แžŠแžถแž‰ Docker แžŠแžถแž…แŸ‹แžŠแŸ„แž™แžกแŸ‚แž€แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แžถแžšแž…แŸแž‰แž•แŸ’แžŸแžถแž™แž˜แžถแž“แžŸแŸ’แžแžทแžšแž—แžถแž– แž€แžถแžšแžŸแžถแž€แž›แŸ’แž”แž„ release branch แžŠแŸ‚แž›แž€แŸ†แž–แžปแž„แžŸแž€แž˜แŸ’แž˜ แž“แžทแž„ development buildsแŸ” | แž”แžŽแŸ’แžŠแžถแž‰ | แž”แŸ’แžšแž—แž– | แž›แž‘แŸ’แž’แž—แžถแž–แž€แŸ‚แž”แŸ’แžšแŸ‚ | แž€แžถแžšแž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹แžŠแŸ‚แž›แž”แžถแž“แžŽแŸ‚แž“แžถแŸ† | | ------------------------------- | ----------------------------------------------------- | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | `:` / `:-web` | แž€แžถแžšแž…แŸแž‰แž•แŸ’แžŸแžถแž™แžŠแŸ‚แž›แž”แžถแž“แž…แžปแŸ‡แž แžแŸ’แžแž›แŸแžแžถ/แž€แŸ†แžŽแžแŸ‹แž€แŸ†แžŽแŸ‚ | แž˜แžทแž“แžขแžถแž…แž€แŸ‚แž”แŸ’แžšแŸ‚แž”แžถแž“ | แž€แžถแžšแžŠแžถแž€แŸ‹แžฑแŸ’แž™แž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹ production แžŠแŸ‚แž›แž…แžถแž€แŸ‹แžŸแŸ„แž€แŸ†แžŽแŸ‚แž…แŸแž‰แž•แŸ’แžŸแžถแž™แž‡แžถแž€แŸ‹แž›แžถแž€แŸ‹ | | `:latest` / `:latest-web` | SemVer แž˜แžถแž“แžŸแŸ’แžแžทแžšแž—แžถแž–แžŠแŸ‚แž›แž”แžถแž“ **แž”แŸ„แŸ‡แž–แžปแž˜แŸ’แž–แž•แŸ’แžŸแžถแž™** แžแŸ’แž–แžŸแŸ‹แž”แŸ†แž•แžปแž | แž‘แŸ’แžšแž“แžทแž…แž˜แžถแž“แžŸแŸ’แžแžทแžšแž—แžถแž–แžŠแŸ‚แž›แžขแžถแž…แž€แŸ‚แž”แŸ’แžšแŸ‚แž”แžถแž“ | แžแžถแž˜แžŠแžถแž“แž€แžถแžšแž…แŸแž‰แž•แŸ’แžŸแžถแž™แž˜แžถแž“แžŸแŸ’แžแžทแžšแž—แžถแž– **แž”แž“แŸ’แž‘แžถแž”แŸ‹แž–แžธ** แž€แžถแžšแž„แžถแžšแž”แŸ„แŸ‡แž–แžปแž˜แŸ’แž– SemVer โ€” **แž˜แžทแž“** แžแžถแž˜แžŠแžถแž“ `main` แžฌ commit `release/v*` แžŠแŸ‚แž›แž˜แžทแž“แž‘แžถแž“แŸ‹แž…แŸแž‰แž•แŸ’แžŸแžถแž™แž‘แŸ | | `:next` / `:next-web` | branch `release/v*` แž›แŸ†แž“แžถแŸ†แžŠแžพแž˜แž”แž…แŸ’แž…แžปแž”แŸ’แž”แž“แŸ’แž“ | แž‘แŸ’แžšแž“แžทแž…แž˜แžปแž“แž€แžถแžšแž…แŸแž‰แž•แŸ’แžŸแžถแž™แžŠแŸ‚แž›แžขแžถแž…แž€แŸ‚แž”แŸ’แžšแŸ‚แž”แžถแž“ | แžŸแžถแž€แž›แŸ’แž”แž„แž€แžถแžšแž€แŸ‚แžแž˜แŸ’แžšแžผแžœแžŠแŸ‚แž›แž”แžถแž“แž”แž‰แŸ’แž…แžผแž›แž‘แŸ…แž€แŸ’แž“แžปแž„ release branch แžŸแž€แž˜แŸ’แž˜ แž”แŸ‰แžปแž“แŸ’แžแŸ‚แž˜แžทแž“แž‘แžถแž“แŸ‹แž˜แžถแž“แž€แŸ’แž“แžปแž„แž€แžถแžšแž…แŸแž‰แž•แŸ’แžŸแžถแž™แž˜แžถแž“แžŸแŸ’แžแžทแžšแž—แžถแž– | | `:main` / `:main-web` | branch `main` | แž‘แŸ’แžšแž“แžทแž…แžขแž—แžทแžœแžŒแŸ’แžแž“แŸแžŠแŸ‚แž›แžขแžถแž…แž€แŸ‚แž”แŸ’แžšแŸ‚แž”แžถแž“ | แžŸแž˜แŸ’แžšแžถแž”แŸ‹แžแŸ‚แž€แžถแžšแžขแž—แžทแžœแžŒแŸ’แž แž“แžทแž„แž€แžถแžšแžŸแžถแž€แž›แŸ’แž”แž„แžšแžฝแž˜แž”แž‰แŸ’แž…แžผแž›แž”แŸ‰แžปแžŽแŸ’แžŽแŸ„แŸ‡ | #### แž€แŸ’แžšแžปแž˜แž แŸŠแžปแž“แž•แŸ’แžŠแž›แŸ‹ web-sessionแŸ– images `-web` แž”แžŽแŸ’แžŠแžถแž‰แž“แžธแž˜แžฝแž™แŸ—แžแžถแž„แž›แžพแž€แŸแž˜แžถแž“แž‡แžถแžŸแŸ’แž›แžถแž€ `-web` แž•แž„แžŠแŸ‚แžš (`:latest-web`, `:-web`, `:next-web`, `:main-web`) แžŠแŸ‚แž›แžแŸ’แžšแžผแžœแž”แžถแž“ build แž–แžธ stage `runner-web` โ€” แž‡แžถ image แžŠแžผแž…แž‚แŸ’แž“แžถ แž”แŸ‰แžปแž“แŸ’แžแŸ‚แž”แž“แŸ’แžแŸ‚แž˜ Playwright แž“แžทแž„แž€แž˜แŸ’แž˜แžœแžทแž’แžธแžšแžปแž€แžšแž€ ChromiumแŸ” image แž’แž˜แŸ’แž˜แžแžถแžแŸ’แžšแžผแžœแž”แžถแž“แž…แŸ‚แž€แž…แžถแž™ **แžŠแŸ„แž™แž‚แŸ’แž˜แžถแž“** ChromiumแŸ” `gemini-web`, `claude-web` แž“แžทแž„ `claude-turnstile` แžแŸ’แžšแžผแžœแž€แžถแžšแžœแžถแŸ” แž€แžถแžšแž”แžšแžถแž‡แŸแž™แžแŸ’แžšแžผแžœแž”แžถแž“แž–แž“แŸ’แž™แžถแžšแž–แŸแž› แž˜แžทแž“แž˜แŸ‚แž“แž€แžพแžแžกแžพแž„แž“แŸ…แž–แŸแž›แž…แžถแž”แŸ‹แž•แŸ’แžŠแžพแž˜แž‘แŸแŸ– แž€แŸ’แžšแžปแž˜แž แŸŠแžปแž“แž•แŸ’แžŠแž›แŸ‹แž‘แžถแŸ†แž„แž“แŸ„แŸ‡แžšแžถแž™แž”แž‰แŸ’แž‡แžธ model แžšแž”แžŸแŸ‹แž–แžฝแž€แž‚แŸ แž“แžทแž„แž”แž„แŸ’แž แžถแž‰แžแžถแž”แžถแž“แž—แŸ’แž‡แžถแž”แŸ‹แž“แŸ…แž€แŸ’แž“แžปแž„แž•แŸ’แž‘แžถแŸ†แž„แž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแž„ แž แžพแž™แž˜แžถแž“แžแŸ‚แžŸแŸ†แžŽแžพแžŠแŸ†แž”แžผแž„แž”แŸ‰แžปแžŽแŸ’แžŽแŸ„แŸ‡แžŠแŸ‚แž›แž”แžšแžถแž‡แŸแž™แž‡แžถแž˜แžฝแž™ ``` [500]: Failed to load external module playwright: Error: Cannot find module '/app/node_modules/playwright/node_modules/playwright-core/browsers.json' ``` แž”แŸ’แžšแžŸแžทแž“แž”แžพแžขแŸ’แž“แž€แž”แŸ’แžšแžพแž€แŸ’แžšแžปแž˜แž แŸŠแžปแž“แž•แŸ’แžŠแž›แŸ‹แž‘แžถแŸ†แž„แž“แŸ„แŸ‡ แžŸแžผแž˜แž‘แžถแž‰แž™แž€แžŸแŸ’แž›แžถแž€ `-web` แž“แŸƒแž”แžŽแŸ’แžŠแžถแž‰แžŠแŸ‚แž›แžขแŸ’แž“แž€แž€แŸ†แž–แžปแž„แž”แŸ’แžšแžพแžšแžฝแž…แž แžพแž™ โ€” แž˜แžทแž“แž˜แžถแž“แžขแŸ’แžœแžธแž•แŸ’แžŸแŸแž„แž‘แŸ€แžแž•แŸ’แž›แžถแžŸแŸ‹แž”แŸ’แžŠแžผแžšแž‘แŸแŸ” แž“แŸ…แž›แžพแž€แžถแžšแžŠแŸ†แžกแžพแž„ npm/CLI (แž‚แŸ’แž˜แžถแž“ Docker image) แž•แŸ’แž“แŸ‚แž€แžŠแŸ‚แž›แžแŸ’แžœแŸ‡แžŸแž˜แž˜แžผแž›แž‚แžบ browser binaryแŸ– แžŠแŸ†แžŽแžพแžšแž€แžถแžš `npx playwright install chromium` แž“แŸ…แž›แžพ hostแŸ” #### แž€แžถแžšแž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹แž”แžŽแŸ’แžŠแžถแž‰แž˜แžปแž“แž€แžถแžšแž…แŸแž‰แž•แŸ’แžŸแžถแž™ แž†แžถแž“แŸ‚แž› `next` แžแŸ’แžšแžผแžœแž”แžถแž“แž”แž„แŸ’แž€แžพแžแžกแžพแž„แžœแžทแž‰แžšแžถแž›แŸ‹แž–แŸแž›แž˜แžถแž“แž€แžถแžšแžšแžปแž‰แž€แžผแžŠแž‘แŸ…แžŸแžถแžแžถแž›แŸ†แž“แžถแŸ†แžŠแžพแž˜ `release/v*` แž”แž…แŸ’แž…แžปแž”แŸ’แž”แž“แŸ’แž“ แž แžพแž™แžแŸ’แžšแžผแžœแž”แžถแž“แž…แŸแž‰แž•แŸ’แžŸแžถแž™แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž‘แžถแŸ†แž„ AMD64 แž“แžทแž„ ARM64แŸ” แžŸแžถแžแžถแžแŸ‚แž‘แžถแŸ†แž…แžถแžŸแŸ‹แŸ—แž˜แžทแž“แžขแžถแž…แžŸแžšแžŸแŸแžšแž‡แžถแž“แŸ‹แž›แžพแžœแžถแž”แžถแž“แž‘แŸแŸ” แž†แžถแž“แŸ‚แž›แž“แŸแŸ‡แž•แŸ’แžŠแž›แŸ‹ image แžŠแŸ‚แž›แžขแžถแž…แž‘แžถแž‰แž™แž€แž”แžถแž“ แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แžถแžšแž€แŸ‚แžแž˜แŸ’แžšแžผแžœแžŠแŸ‚แž›แž”แžถแž“แž”แž‰แŸ’แž…แžผแž›แž‘แŸ…แž€แŸ’แž“แžปแž„แžŸแžถแžแžถ release แžŸแž€แž˜แŸ’แž˜ แž˜แžปแž“แž–แŸแž›แž”แž„แŸ’แž€แžพแž tag แžŸแŸ’แžแžทแžšแž—แžถแž–แž”แž“แŸ’แž‘แžถแž”แŸ‹แŸ” ```bash docker pull diegosouzapw/omniroute:next docker pull diegosouzapw/omniroute:next-web ``` แžŸแž˜แŸ’แžšแžถแž”แŸ‹ Docker Compose แžŸแžผแž˜แž€แŸ†แžŽแžแŸ‹แž‡แŸ†แž“แžฝแžŸ image tag แžŠแŸ‚แž›แž”แŸ’แžšแžพแžŠแŸ„แž™ profile แžŠแŸ‚แž›แž”แžถแž“แž‡แŸ’แžšแžพแžŸแžšแžพแžŸ แž”แž“แŸ’แž‘แžถแž”แŸ‹แž˜แž€แž‘แžถแž‰แž™แž€ แž“แžทแž„แž”แž„แŸ’แž€แžพแž service แžกแžพแž„แžœแžทแž‰แŸ– ```yaml services: omniroute: image: diegosouzapw/omniroute:next ``` ```bash docker compose pull docker compose up -d ``` #### แžŸแžปแžœแžแŸ’แžแžทแž—แžถแž– แž“แžทแž„แž€แžถแžšแžแŸ’แžšแžกแž”แŸ‹แž‘แŸ…แž€แŸ†แžŽแŸ‚แž˜แžปแž“ `next` แž‚แžบแž‡แžถแž†แžถแž“แŸ‚แž›แž˜แžปแž“แž€แžถแžšแž…แŸแž‰แž•แŸ’แžŸแžถแž™แžŠแŸ‚แž›แžขแžถแž…แž•แŸ’แž›แžถแžŸแŸ‹แž”แŸ’แžŠแžผแžšแž”แžถแž“แŸ” แžœแžถแžขแžถแž…แž•แŸ’แž›แžถแžŸแŸ‹แž”แŸ’แžŠแžผแžšแž“แŸ…แžšแžถแž›แŸ‹แž–แŸแž›แž˜แžถแž“แž€แžถแžšแžšแžปแž‰แž€แžผแžŠแž‘แŸ…แžŸแžถแžแžถ release แžŸแž€แž˜แŸ’แž˜ แž แžพแž™ **แž˜แžทแž“แžแŸ’แžšแžผแžœแž”แžถแž“แž‚แžถแŸ†แž‘แŸ’แžšแžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แžถแžšแž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹แž€แŸ’แž“แžปแž„ production แž‘แŸ**แŸ” แžŸแžผแž˜แž…แžถแž€แŸ‹แžŸแŸ„ image digest แžแžŽแŸˆแž–แŸแž›แžœแžถแž™แžแž˜แŸ’แž›แŸƒ build แž‡แžถแž€แŸ‹แž›แžถแž€แŸ‹แž˜แžฝแž™แŸ– ```bash docker pull diegosouzapw/omniroute:next docker image inspect diegosouzapw/omniroute:next --format '{{index .RepoDigests 0}}' ``` แž˜แžปแž“แž–แŸแž›แžŸแžถแž€แž›แŸ’แž”แž„ แžŸแžผแž˜แž”แž˜แŸ’แžšแžปแž„แž‘แžปแž€ volume แž‘แžทแž“แŸ’แž“แž“แŸแž™ OmniRoute แžฌแžแžแž‘แžทแž“แŸ’แž“แž“แŸแž™แžŠแŸ‚แž›แž”แžถแž“ bind-mountแŸ” แžŠแžพแž˜แŸ’แž”แžธแžแŸ’แžšแžกแž”แŸ‹แž‘แŸ…แž€แŸ†แžŽแŸ‚แž˜แžปแž“ แžŸแžผแž˜แžŸแŸ’แžŠแžถแžšแž€แŸ†แžŽแŸ‚แžŸแŸ’แžแžทแžšแž—แžถแž– แžฌ digest แžŠแŸ‚แž›แž’แŸ’แž›แžถแž”แŸ‹แž”แžถแž“แž”แŸ’แžšแžพแž–แžธแž˜แžปแž“ แž แžพแž™แž”แž„แŸ’แž€แžพแž container แžกแžพแž„แžœแžทแž‰แŸ– ```bash docker pull diegosouzapw/omniroute: docker compose up -d ``` build แž–แžธแžŸแžถแžแžถ release แž˜แžทแž“แžขแžถแž…แž•แŸ’แž›แžถแžŸแŸ‹แž‘แžธ `latest` แž”แžถแž“แžกแžพแž™แŸ” แž˜แžถแž“แžแŸ‚แž€แŸ†แžŽแŸ‚ semantic แžŸแŸ’แžแžทแžšแž—แžถแž–แžŠแŸ‚แž›แž˜แžถแž“แž›แž€แŸ’แžแžŽแŸˆแžŸแž˜แŸ’แž”แžแŸ’แžแžทแž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแžถแž“แŸ‹แž”แŸ‰แžปแžŽแŸ’แžŽแŸ„แŸ‡ แžŠแŸ‚แž›แžขแžถแž…แžŠแŸ†แžกแžพแž„ pointer แžŸแŸ’แžแžทแžšแž—แžถแž–แž”แžถแž“แŸ” image `next` แž“แŸ…แžแŸ‚แžšแž€แŸ’แžŸแžถแž€แžถแžšแžแŸ’แžšแžฝแžแž–แžทแž“แžทแžแŸ’แž™ release image แž“แžทแž„แž…แŸ’แžšแž€แž‘แž”แŸ‹แžŸแŸ’แž€แžถแžแŸ‹แž—แžถแž–แž„แžถแž™แžšแž„แž‚แŸ’แžšแŸ„แŸ‡แž€แž˜แŸ’แžšแžทแž CRITICALแŸ” **`latest` แž˜แžทแž“แž˜แŸ‚แž“แž‡แžถแž€แžถแžšแž’แžถแž“แžถแžแžถ git แž‘แžถแž“แŸ‹แžŸแž˜แŸแž™แž“แŸ„แŸ‡แž‘แŸแŸ”** แž€แžถแžšแž€แŸ‚แžแž˜แŸ’แžšแžผแžœแžŠแŸ‚แž›แž”แžถแž“แž”แž‰แŸ’แž…แžผแž›แž“แŸ…แž›แžพ `main` แžฌแž“แŸ…แž›แžพแžŸแžถแžแžถ `release/v*` แžŸแž€แž˜แŸ’แž˜ **แž˜แžทแž“แž˜แžถแž“** แž“แŸ…แž€แŸ’แž“แžปแž„ `:latest` แž‘แŸ แžšแž แžผแžแžŠแž›แŸ‹ image SemVer แžŸแŸ’แžแžทแžšแž—แžถแž–แžแŸ’แžšแžผแžœแž”แžถแž“แž…แŸแž‰แž•แŸ’แžŸแžถแž™ แž แžพแž™ job แž…แŸแž‰แž•แŸ’แžŸแžถแž™แžŠแŸ†แžกแžพแž„ `:latest` (digest แžŠแžผแž…แž‚แŸ’แž“แžถแž“แžนแž„ SemVer แž“แŸ„แŸ‡)แŸ” แž”แŸ’แžšแžŸแžทแž“แž”แžพ `latest` แž แžถแž€แŸ‹แžŠแžผแž…แž‡แžถแž˜แžทแž“แž•แŸ’แž›แžถแžŸแŸ‹แž”แŸ’แžŠแžผแžš แžแžŽแŸˆแžŠแŸ‚แž› GitHub แž”แž„แŸ’แž แžถแž‰แž€แžถแžšแž€แŸ‚แžแž˜แŸ’แžšแžผแžœแžšแžฝแž…แž แžพแž™ แžŸแžผแž˜แž‘แžถแž‰แž™แž€ `:next` แžŠแžพแž˜แŸ’แž”แžธแžŸแžถแž€แž›แŸ’แž”แž„แžŸแžถแžแžถ release แžฌแžšแž„แŸ‹แž…แžถแŸ† tag SemVerแŸ” | แžขแŸ’แžœแžธแžŠแŸ‚แž›แžขแŸ’แž“แž€แž…แž„แŸ‹แž”แžถแž“ | แž”แŸ’แžšแžพ | | ----------------------------------------------------------------------- | ---------------------------------- | | GitOps / production แžŠแŸ‚แž›แž˜แžทแž“แžแŸ’แžšแžผแžœแž•แŸ’แž›แžถแžŸแŸ‹แž”แŸ’แžŠแžผแžšแžŠแŸ„แž™แžŸแŸ’แžœแŸแž™แž”แŸ’แžšแžœแžแŸ’แžแžท | แž…แžถแž€แŸ‹แžŸแŸ„แž‘แŸ… `:X.Y.Z` (แžฌ image digest) | | แžแžถแž˜แžŠแžถแž“แž€แŸ†แžŽแŸ‚แžŸแŸ’แžแžทแžšแž—แžถแž–แžŠแŸ‚แž›แž”แžถแž“แž…แŸแž‰แž•แŸ’แžŸแžถแž™ แž“แžทแž„แž‘แž‘แžฝแž›แž™แž€แž€แžถแžšแž”แž„แŸ’แž€แžพแžแžกแžพแž„แžœแžทแž‰แž“แŸ…แžšแžถแž›แŸ‹ release | `:latest` | | แžŸแžถแž€แž›แŸ’แž”แž„ commit `release/v*` แžŠแŸ‚แž›แž˜แžทแž“แž‘แžถแž“แŸ‹แž…แŸแž‰แž•แŸ’แžŸแžถแž™ | `:next` (แž˜แžทแž“แž˜แŸ‚แž“ production) | | แžŸแžถแž€แž›แŸ’แž”แž„ `main` | `:main` (แž˜แžทแž“แž˜แŸ‚แž“ production) | ## แž€แžถแžšแžขแžถแž”แŸ‹แžŠแŸแžแž•แŸ’แž‘แžถแŸ†แž„แž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแž„แž€แŸ’แž“แžปแž„ Docker แž€แžปแž„แžแžบแž“แŸแžšแžŠแŸ‚แž›แž”แŸ’แžšแžพ image แž”แžถแž“แž”แŸ„แŸ‡แž–แžปแž˜แŸ’แž–แž•แŸ’แžŸแžถแž™แž˜แžทแž“แžขแžถแž…แž‡แŸ†แž“แžฝแžŸแžแŸ’แž›แžฝแž“แžฏแž„แž”แžถแž“แž‘แŸแŸ” แž“แŸ…แž–แŸแž› OmniRoute แžšแž€แžƒแžพแž‰แžแžถแžœแžถแž€แŸ†แž–แžปแž„แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž“แŸ…แž€แŸ’แž“แžปแž„ แž€แžปแž„แžแžบแž“แŸแžš (แž‚แŸ’แž˜แžถแž“แž€แžถแžšแž‘แžถแž‰แž™แž€ `.git` แž“แžทแž„แž˜แžทแž“แž˜แŸ‚แž“แž‡แžถแž€แžถแžšแžŠแŸ†แžกแžพแž„แžแžถแž˜ npm) แž”แžŠแžถแžขแžถแž”แŸ‹แžŠแŸแžแž“แŸ…แž›แžพแž•แŸ’แž‘แžถแŸ†แž„แž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแž„แž‘แŸ†แž–แŸแžšแžŠแžพแž˜แž“แžนแž„แž”แž„แŸ’แž แžถแž‰ แž–แžถแž€แŸ’แž™แž”แž‰แŸ’แž‡แžถ host แžŠแŸ‚แž›แžแŸ’แžšแžผแžœแžŠแŸ†แžŽแžพแžšแž€แžถแžš แž‡แŸ†แž“แžฝแžŸแžฑแŸ’แž™แžŸแŸแž…แž€แŸ’แžแžธแžŽแŸ‚แž“แžถแŸ† npm/git แžŠแŸ„แž™แž˜แžถแž“แž”แŸŠแžผแžแžปแž„แž…แž˜แŸ’แž›แž„แŸ– ```bash docker compose pull omniroute && docker compose up -d --force-recreate omniroute ``` แžˆแŸ’แž˜แŸ„แŸ‡แžŸแŸแžœแžถแž€แž˜แŸ’แž˜แž˜แž€แž–แžธ `AUTO_UPDATE_SERVICE` (แžแž˜แŸ’แž›แŸƒแž›แŸ†แž“แžถแŸ†แžŠแžพแž˜แž‚แžบ `omniroute` แžŠแŸ‚แž›แž‡แžถแžŸแŸแžœแžถแž€แž˜แŸ’แž˜แž“แŸ…แž€แŸ’แž“แžปแž„ `docker-compose.selfhost.yml`)แŸ” `pull` แž•แŸ’แž›แžถแžŸแŸ‹แž‘แžธแžแŸ‚ tag แžขแžŽแŸ’แžแŸ‚แž (`latest`, `next`) แž”แŸ‰แžปแžŽแŸ’แžŽแŸ„แŸ‡แŸ” แžŸแž˜แŸ’แžšแžถแž”แŸ‹ tag `:X.Y.Z` แžŠแŸ‚แž›แž”แžถแž“แž€แŸ†แžŽแžแŸ‹แž‡แžถแž€แŸ‹แž›แžถแž€แŸ‹ แžŸแžผแž˜แž€แŸ‚แžŸแž˜แŸ’แžšแžฝแž› tag แž‡แžถแž˜แžปแž“แžŸแžทแž“แŸ” ### แž€แžถแžšแžขแžถแž”แŸ‹แžŠแŸแžแžŠแŸ„แž™แž…แžปแž…แžแŸ‚แž˜แŸ’แžแž„แž‡แžถแž˜แžฝแž™แžฏแž€แžŸแžถแžš trigger แžšแž”แžŸแŸ‹ host แžŠแžพแž˜แŸ’แž”แžธแžฑแŸ’แž™ **แžขแžถแž”แŸ‹แžŠแŸแžแžฅแžกแžผแžœแž“แŸแŸ‡** แž”แž“แŸ’แžแžŠแŸ†แžŽแžพแžšแž€แžถแžšแžŠแŸ„แž™แž˜แžทแž“แž…แžถแŸ†แž”แžถแž…แŸ‹ mount `/var/run/docker.sock` (แžŠแŸ‚แž›แž•แŸ’แžแž›แŸ‹แžฑแŸ’แž™แž€แžปแž„แžแžบแž“แŸแžš แž“แžผแžœแžŸแžทแž‘แŸ’แž’แžท root แž›แžพ host โ€” แžŸแžผแž˜แž˜แžพแž›แž€แžถแžšแž–แŸ’แžšแž˜แžถแž“แžขแŸ†แž–แžธ profile `cli` แžแžถแž„แž›แžพ) แžŸแžผแž˜แž€แŸ†แžŽแžแŸ‹ `DOCKER_UPDATE_TRIGGER_FILE` แž“แŸ…แž›แžพ แžŸแŸแžœแžถแž€แž˜แŸ’แž˜ OmniRoute แž แžพแž™แžŠแŸ†แžŽแžพแžšแž€แžถแžš watcher แž“แŸ…แž›แžพ hostแŸ– ```yaml services: omniroute: environment: DOCKER_UPDATE_TRIGGER_FILE: /app/data/update/docker-update.request volumes: - ./data:/app/data ``` แž•แŸ’แž›แžผแžœแžแŸ’แžšแžผแžœแžแŸ‚แžŸแŸ’แžแžทแžแž“แŸ…แž€แŸ’แž“แžปแž„ `DATA_DIR` (แžแž˜แŸ’แž›แŸƒแžŠแŸ‚แž›แž˜แžถแž“แž›แž€แŸ’แžแžŽแŸˆ relative แž“แžนแž„แžแŸ’แžšแžผแžœแž”แžถแž“แžŠแŸ„แŸ‡แžŸแŸ’แžšแžถแž™แžŠแŸ„แž™แž•แŸ’แžขแŸ‚แž€แž›แžพแžœแžถ)แŸ” แž•แŸ’แž›แžผแžœแž•แŸ’แžŸแŸแž„แž‘แŸ€แž แž‘แžถแŸ†แž„แžขแžŸแŸ‹แž“แžนแž„แžแŸ’แžšแžผแžœแž”แžถแž“แž”แžŠแžทแžŸแŸแž’แŸ” แž”แž“แŸ’แž‘แžถแž”แŸ‹แž˜แž€ **แžขแžถแž”แŸ‹แžŠแŸแžแžฅแžกแžผแžœแž“แŸแŸ‡** แž“แžนแž„แžŸแžšแžŸแŸแžš `{ "requestedAt": "...", "targetVersion": "X.Y.Z" }` แž‘แŸ…แž€แŸ’แž“แžปแž„ แžฏแž€แžŸแžถแžšแž“แŸ„แŸ‡ แž†แŸ’แž›แžพแž™แžแž”แžŠแŸ„แž™ `202` แž แžพแž™แž•แŸ’แž‘แžถแŸ†แž„แž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแž„แž“แžนแž„แžŸแŸ’แž‘แž„แŸ‹ `/api/system/version` แžšแž แžผแžแžŠแž›แŸ‹แž€แŸ†แžŽแŸ‚แžแŸ’แž˜แžธแžŠแŸ†แžŽแžพแžšแž€แžถแžš แžšแžฝแž…แž•แŸ’แž‘แžปแž€แžกแžพแž„แžœแžทแž‰แŸ” OmniRoute แž˜แžทแž“แžŠแŸ‚แž›แžŠแŸ†แžŽแžพแžšแž€แžถแžš shell แžฌแž–แžถแž€แŸ’แž™แž”แž‰แŸ’แž‡แžถ Docker แž€แŸ’แž“แžปแž„แžšแž”แŸ€แž”แž“แŸแŸ‡แž‘แŸแŸ” แžŠแžผแž…แžŸแž€แž˜แŸ’แž˜แž—แžถแž–แžขแžถแž”แŸ‹แžŠแŸแž แž‘แžถแŸ†แž„แžขแžŸแŸ‹แžŠแŸ‚แžš แžŸแŸ†แžŽแžพแžแŸ’แžšแžผแžœแž”แžถแž“แž‘แž‘แžฝแž›แž™แž€แžแŸ‚แž–แžธ client แž“แŸ…แž›แžพ loopback/LAN แž”แŸ‰แžปแžŽแŸ’แžŽแŸ„แŸ‡แŸ” แžแžแž‘แžทแž“แŸ’แž“แž“แŸแž™แžŠแŸ‚แž›แž”แžถแž“ bind-mount แž•แŸ’แžแž›แŸ‹แžฑแŸ’แž™ host แž“แžผแžœแž•แŸ’แž›แžผแžœแžแŸแžšแžŸแž˜แŸ’แžšแžถแž”แŸ‹แžแŸ’แžšแžฝแžแž–แžทแž“แžทแžแŸ’แž™แŸ” แžฏแž€แžแžถ `systemd` แž‚แŸ†แžšแžผ (แž€แŸ‚แžŸแž˜แŸ’แžšแžฝแž› `/srv/omniroute` แžฑแŸ’แž™แžแŸ’แžšแžผแžœแž“แžนแž„แžแžแžŠแŸ‚แž›แž•แŸ’แž‘แžปแž€แžฏแž€แžŸแžถแžš compose แž“แžทแž„ `data/` แžšแž”แžŸแŸ‹แžขแŸ’แž“แž€)แŸ– ```ini # /etc/systemd/system/omniroute-update.path [Unit] Description=Watch for OmniRoute dashboard update requests [Path] PathExists=/srv/omniroute/data/update/docker-update.request [Install] WantedBy=multi-user.target ``` ```ini # /etc/systemd/system/omniroute-update.service [Unit] Description=Pull and recreate the OmniRoute container [Service] Type=oneshot WorkingDirectory=/srv/omniroute ExecStartPre=/usr/bin/rm -f /srv/omniroute/data/update/docker-update.request ExecStart=/bin/sh -c 'docker compose pull omniroute || (sleep 15 && docker compose pull omniroute)' ExecStart=/usr/bin/docker compose up -d --force-recreate omniroute ``` ```bash sudo systemctl daemon-reload sudo systemctl enable --now omniroute-update.path ``` แžŸแŸแžœแžถแž€แž˜แŸ’แž˜แž›แžปแž”แžŸแŸ†แžŽแžพแž…แŸแž‰แž˜แžปแž“แž–แŸแž› pull แžŠแžผแž…แŸ’แž“แŸแŸ‡ แž€แžถแžšแžŠแŸ†แžŽแžพแžšแž€แžถแžšแžŠแŸ‚แž›แž”แžšแžถแž‡แŸแž™แž“แžนแž„แž˜แžทแž“แž’แŸ’แžœแžพแž˜แŸ’แžแž„แž แžพแž™แž˜แŸ’แžแž„แž‘แŸ€แžแž‘แŸแŸ” แž”แŸ’แžšแžŸแžทแž“แž”แžพแž‚แŸ’แž˜แžถแž“ `DOCKER_UPDATE_TRIGGER_FILE` แž‘แŸ แž•แŸ’แž‘แžถแŸ†แž„แž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแž„แž“แžนแž„แž”แž“แŸ’แžแž”แŸ’แžšแžพแžŠแŸ†แžŽแžพแžšแž€แžถแžšแž–แžถแž€แŸ’แž™แž”แž‰แŸ’แž‡แžถแžŠแŸ„แž™แžŠแŸƒแŸ” ## แž—แžถแž–แžขแžถแž…แž”แŸ’แžšแžพแž”แžถแž“แŸ– SQLite แž›แŸ†แž“แžถแŸ†แžŠแžพแž˜แž‚แžถแŸ†แž‘แŸ’แžšแžแŸ‚ replica แž˜แžฝแž™ OmniRoute แžŸแŸ’แžแž„แŸ‹แžŠแžถแžšแžŸแž˜แŸ’แžšแžถแž”แŸ‹ Docker / Kubernetes แž‚แžบ **Node process แž˜แžฝแž™ + SQLite writer แž˜แžฝแž™**แŸ” แž—แžถแž–แžขแžถแž…แž”แŸ’แžšแžพแž”แžถแž“แžแŸ’แž–แžŸแŸ‹ **แž˜แžทแž“แžแŸ’แžšแžผแžœแž”แžถแž“แž‚แžถแŸ†แž‘แŸ’แžš** แž›แžพ topology แž“แŸแŸ‡แž‘แŸแŸ” | แž€แž˜แŸ’แžšแžทแžแž€แŸ†แžŽแžแŸ‹ | แž•แž›แžœแžทแž”แžถแž€ | | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | writer แžแŸ‚แž˜แžฝแž™ | **แž€แžปแŸ†** แžŠแŸ†แžŽแžพแžšแž€แžถแžš replica แž…แŸ’แžšแžพแž“แžŠแŸ„แž™แž”แŸ’แžšแžพแžฏแž€แžŸแžถแžš SQLite แžŠแžผแž…แž‚แŸ’แž“แžถแŸ” แžœแžถแž“แžนแž„แž’แŸ’แžœแžพแžฑแŸ’แž™ DB แžแžผแž…แŸ” | | แž€แžถแžšแž”แž„แŸ’แž€แžพแžแžกแžพแž„แžœแžทแž‰ / แž€แžถแžšแž…แžถแž”แŸ‹แž•แŸ’แžแžพแž˜แžกแžพแž„แžœแžทแž‰ / แž€แžถแžšแž”แž‰แŸ’แžˆแž”แŸ‹แžŠแŸ„แž™ HEALTHCHECK | **แž€แžถแžšแžŠแžถแž…แŸ‹แžŸแŸแžœแžถแž‘แžถแŸ†แž„แžŸแŸ’แžšแžปแž„** แžŸแž˜แŸ’แžšแžถแž”แŸ‹ SSE แžŠแŸ‚แž›แž€แŸ†แž–แžปแž„แžŠแŸ†แžŽแžพแžšแž€แžถแžš session แžšแž”แžŸแŸ‹แž•แŸ’แž‘แžถแŸ†แž„แž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแž„ แž“แžทแž„ state แž€แŸ’แž“แžปแž„ memoryแŸ” client แžŠแŸ‚แž›แž”แžถแž“แžแž—แŸ’แž‡แžถแž”แŸ‹แž‘แžถแŸ†แž„แžขแžŸแŸ‹แž“แžนแž„แž•แŸ’แžแžถแž…แŸ‹แŸ” แžŸแŸ†แžŽแžพแžแŸ’แž˜แžธแž€แŸ’แž“แžปแž„แžขแŸ†แžกแžปแž„แž–แŸแž›แžŠแŸ‚แž›แž‚แŸ’แž˜แžถแž“ endpoint แž“แžนแž„แž‘แž‘แžฝแž›แž”แžถแž“ **`502 Bad Gateway: Unknown error`** แž–แžธ reverse proxy แž˜แžทแž“แž˜แŸ‚แž“ OmniRoute JSON แž‘แŸ โ€” client แž˜แžทแž“แžขแžถแž…แž”แŸ‚แž„แž…แŸ‚แž€แžœแžถแž–แžธแž€แžถแžšแž”แžšแžถแž‡แŸแž™แžšแž”แžŸแŸ‹ provider แž”แžถแž“แž‘แŸ (#11015)แŸ” | | event loop แžŠแžผแž…แž‚แŸ’แž“แžถแž“แžนแž„ `/healthz` | catalog แžŠแŸ‚แž›แž˜แž˜แžถแž‰แžนแž€ แžฌ compression tick แžขแžถแž…แž–แž“แŸ’แž™แžถแžšแž–แŸแž› probe แž”แžถแž“แŸ” timeout แžแŸ’แž›แžธแž“แžนแž„แž…แžถแž”แŸ‹แž•แŸ’แžแžพแž˜ replica **แžแŸ‚แž˜แžฝแž™แž‚แžแŸ‹** แžกแžพแž„แžœแžทแž‰แŸ” | **แž˜แŸ‰แžถแž‘แŸ’แžšแžธแžŸ probe** (แžŸแžผแž˜แž˜แžพแž›แž•แž„แžŠแŸ‚แžš [แžขแž“แžปแžŸแžถแžŸแž“แŸ probe แžŸแž˜แŸ’แžšแžถแž”แŸ‹ Kubernetes](../ops/MONITORING_GUIDE.md#kubernetes-probe-recommendations))แŸ– | Probe | แž‚แŸ„แž›แžŠแŸ… | แž€แžปแŸ†แž”แŸ’แžšแžพ | | ----------------- | -------------------------------------------------------------- | ---------------------------------------------------- | | Liveness | TCP แž“แŸ…แž›แžพ `PORT` (แžแž˜แŸ’แž›แŸƒแž›แŸ†แž“แžถแŸ†แžŠแžพแž˜ `20128`) แžฌ soft HTTP `/healthz` | `/api/monitoring/health` | | Readiness | HTTP `GET /healthz` | timeout แžแŸ’แž›แžธแž–แŸแž€แžŠแŸ‚แž›แž…แžถแžแŸ‹แž‘แžปแž€ event loop แž˜แž˜แžถแž‰แžนแž€แžแžถแž”แžถแž“แž‚แžถแŸ†แž„ | | แžŸแŸŠแžธแž‡แž˜แŸ’แžšแŸ… / แž˜แž“แžปแžŸแŸ’แžŸ | `/api/monitoring/health` | liveness แžŸแŸ’แžœแŸแž™แž”แŸ’แžšแžœแžแŸ’แžแžทแžšแž”แžŸแŸ‹ kubelet | **แž€แžถแžšแžขแžถแž”แŸ‹แžŠแŸแžแž€แŸ†แžŽแŸ‚แŸ–** แžšแŸ†แž–แžนแž„แžแžถ session แž‘แžถแŸ†แž„แžขแžŸแŸ‹แž“แžนแž„แž•แŸ’แžแžถแž…แŸ‹แŸ” แž”แž„แŸ’แž แžผแžš client แž…แŸแž‰แžŸแžทแž“ แž”แŸ’แžšแžŸแžทแž“แž”แžพแžขแŸ’แž“แž€แžขแžถแž…แž’แŸ’แžœแžพแž”แžถแž“แŸ” แž˜แžทแž“แž˜แžถแž“ rolling update แž›แžพ SQLite แž›แŸ†แž“แžถแŸ†แžŠแžพแž˜แž‘แŸแŸ” Compose `restart: unless-stopped` แžšแžฝแž˜แž‡แžถแž˜แžฝแž™ Docker `HEALTHCHECK` แž€แŸแž“แžนแž„แž‡แŸ†แž“แžฝแžŸ process แžแŸ‚แž˜แžฝแž™แž‚แžแŸ‹แž•แž„แžŠแŸ‚แžš แž“แŸ…แž–แŸแž›แž€แžปแž„แžแžบแž“แŸแžšแžŸแŸ’แžแžทแžแž€แŸ’แž“แžปแž„แžŸแŸ’แžแžถแž“แž—แžถแž– Unhealthy โ€” แž˜แžถแž“แžœแžทแžŸแžถแž›แž—แžถแž–แž•แž›แž”แŸ‰แŸ‡แž–แžถแž›แŸ‹แžŠแžผแž…แž‚แŸ’แž“แžถแŸ” แžƒแŸ’แž›แžถแž€แžผแžŠ Kubernetes แžŸแž˜แŸ’แžšแžถแž”แŸ‹ **replica แžแŸ‚แž˜แžฝแž™** (แžแž˜แŸ’แžšแžผแžœแžฑแŸ’แž™แž”แŸ’แžšแžพ RecreateแŸ” แž€แžปแŸ†แž”แž„แŸ’แž€แžพแž“ `replicas` แžŸแž˜แŸ’แžšแžถแž”แŸ‹แžฏแž€แžŸแžถแžš SQLite แžแŸ‚แž˜แžฝแž™)แŸ– ```yaml spec: replicas: 1 strategy: type: Recreate template: spec: terminationGracePeriodSeconds: 90 containers: - name: omniroute lifecycle: preStop: exec: command: ["/bin/sleep", "15"] readinessProbe: httpGet: path: /healthz port: 20128 periodSeconds: 5 livenessProbe: tcpSocket: port: 20128 periodSeconds: 20 ``` แž€แžถแžšแž–แž“แŸ’แž™แžถแžšแž–แŸแž› `preStop` แžขแž“แžปแž‰แŸ’แž‰แžถแžแžฑแŸ’แž™ kube แžŠแž€ Service endpoints แž…แŸแž‰ แž˜แžปแž“แž–แŸแž› SIGTERM แžŠแžผแž…แŸ’แž“แŸแŸ‡ traffic **แžแŸ’แž˜แžธ** แž“แžนแž„แžˆแž”แŸ‹แž…แžผแž›แž‘แŸ…แž€แžถแž“แŸ‹ process แžŠแŸ‚แž›แž€แŸ†แž–แžปแž„แž”แžทแž‘แŸ” SSE `/v1/responses` แžŠแŸ‚แž›แž€แŸ†แž–แžปแž„แžŠแŸ†แžŽแžพแžšแž€แžถแžš แž“แžนแž„แžแŸ’แžšแžผแžœแž”แžถแž“แž”แž„แŸ’แž แžผแžšแžšแž แžผแžแžŠแž›แŸ‹ `SHUTDOWN_TIMEOUT_MS` (แž›แŸ†แž“แžถแŸ†แžŠแžพแž˜ 30 แžœแžทแž“แžถแž‘แžธ) แžแžถแž˜แžšแž™แŸˆ heavyweight admission leases (#11015)แŸ” Request แžแŸ’แž˜แžธแžŠแŸ‚แž›แž“แŸ…แžแŸ‚แž…แžผแž›แžŠแž›แŸ‹ process แž“แžนแž„แž‘แž‘แžฝแž›แž”แžถแž“ `503` + `Retry-After: 5`แŸ” แž…แž“แŸ’แž›แŸ„แŸ‡แž–แŸแž›แžŠแŸ‚แž›แž‚แŸ’แž˜แžถแž“ endpoint แžšแž”แžŸแŸ‹ Recreate แžšแž แžผแžแžŠแž›แŸ‹ replacement แž˜แžถแž“แžŸแŸ’แžแžถแž“แž—แžถแž– Ready แž“แŸ…แžแŸ‚แž‡แžถแž€แžถแžšแžŠแžถแž…แŸ‹แžŸแŸแžœแžถแž–แŸแž‰แž›แŸแž‰ โ€” แž“แŸ„แŸ‡แž‚แžบแž‡แžถแž›แž€แŸ’แžแžŽแŸˆแžšแž”แžŸแŸ‹ topology SQLite แž˜แžทแž“แž˜แŸ‚แž“แž‡แžถแž€แžถแžšแž€แŸ†แžŽแžแŸ‹ probe แžแžปแžŸแž‘แŸแŸ” Postgres แžแžถแž„แž€แŸ’แžšแŸ… / HA แž”แŸ’แžšแž—แŸแž‘ multi-writer **แž˜แžทแž“แž˜แŸ‚แž“**แž‡แžถแžœแžทแž’แžธแžŸแŸ’แžแž„แŸ‹แžŠแžถแžšแžŠแŸ‚แž›แž˜แžถแž“แžฏแž€แžŸแžถแžšแžŽแŸ‚แž“แžถแŸ†แž‘แŸแŸ” แž”แŸ’แžšแžŸแžทแž“แž”แžพแžขแŸ’แž“แž€แžแŸ’แžšแžผแžœแž€แžถแžš HA แžŸแžผแž˜แžšแž€แŸ’แžŸแžถ replica แžแŸ‚แž˜แžฝแž™ แžฌแžŠแŸ†แžŽแžพแžšแž€แžถแžš topology แžŠแŸ‚แž›แž‚แž˜แŸ’แžšแŸ„แž„แž”แžถแž“แžŸแžถแž€แž›แŸ’แž”แž„ แž“แžทแž„แž…แž„แž€แŸ’แžšแž„แž‡แžถแžฏแž€แžŸแžถแžšแžŠแŸ„แž™แžกแŸ‚แž€แŸ” แž€แžถแžšแž„แžถแžš Postgres/MySQL แžŸแŸ’แžแžทแžแž“แŸ…แž€แŸ’แž“แžปแž„ [#8075](https://github.com/diegosouzapw/OmniRoute/issues/8075)แŸ” แžšแž แžผแžแžŠแž›แŸ‹แžœแžถแžแŸ’แžšแžผแžœแž”แžถแž“แž…แŸแž‰แž•แŸ’แžŸแžถแž™ แžœแžทแž’แžธแžแŸ‚แž˜แžฝแž™แž‚แžแŸ‹แžŠแŸ‚แž›แž”แžถแž“แž‚แžถแŸ†แž‘แŸ’แžšแžŸแž˜แŸ’แžšแžถแž”แŸ‹แž”แž„แŸ’แž€แžพแž“แžŸแž˜แžแŸ’แžแž—แžถแž– `/v1/responses` **แž’แŸ†แŸ—** แž‚แžบแž”แŸ’แžšแžพ process แžฏแž€แžšแžถแž‡แŸ’แž™ N (แž•แŸ’แž“แŸ‚แž€แž”แž“แŸ’แž‘แžถแž”แŸ‹) แž˜แžทแž“แž˜แŸ‚แž“ `replicas > 1` แž“แŸ…แž›แžพ volume แžแŸ‚แž˜แžฝแž™แž‘แŸแŸ” ## แž€แžถแžšแž–แž„แŸ’แžšแžธแž€แž•แŸ’แžŠแŸแž€แŸ– แžŠแŸ†แžŽแžพแžšแž€แžถแžšแžฏแž€แžšแžถแž‡แŸ’แž™ N แžŠแŸ†แžŽแžพแžšแž€แžถแžš Node แž˜แžฝแž™แž‚แžบแž‡แžถ **V8 heap แž˜แžฝแž™**แŸ” แžŸแŸ†แžŽแžพ coding-agent `POST /v1/responses` (RTK + Caveman) แžŠแŸ‚แž›แžแŸ’แžšแžฝแžแž‚แŸ’แž“แžถแž…แŸ†แž“แžฝแž“แž–แžธแžš แž“แžทแž„แž˜แžถแž“แž‘แŸ†แž แŸ†แž”แŸ’แžšแž แŸ‚แž› ~3โ€ฏMiB / ~750k-token แž’แŸ’แžœแžพแžฑแŸ’แž™ heap แž“แŸ„แŸ‡แž”แž‰แŸ’แžˆแž”แŸ‹แž“แŸ…แž”แŸ’แžšแž แŸ‚แž› ~12โ€ฏGi (`FATAL ERROR: Reached heap limit`) แž แžพแž™แžขแžถแž…แž”แž„แŸ’แž€แžฑแŸ’แž™ cgroup แž‘แŸ†แž แŸ† 16โ€ฏGi แžขแžŸแŸ‹แžขแž„แŸ’แž‚แž…แž„แž…แžถแŸ† (OOM)แŸ” แžŸแžผแž˜แž˜แžพแž› [#7849](https://github.com/diegosouzapw/OmniRoute/issues/7849)แŸ” แž€แžถแžšแžœแžถแžŸแŸ‹แžœแŸ‚แž„แž“แŸ„แŸ‡แž‚แžบแž‡แžถแž€แžถแžšแž–แŸ’แžšแž˜แžถแž“แžขแŸ†แž–แžธ **แžแžœแžทแž€แžถแžขแž„แŸ’แž‚แž…แž„แž…แžถแŸ†** แž˜แžทแž“แž˜แŸ‚แž“แž‡แžถแžŠแŸ‚แž“แž€แŸ†แžŽแžแŸ‹แžขแžแžทแž”แžšแž˜แžถแžŠแžถแž…แŸ‹แžแžถแžแžšแž”แžŸแŸ‹แž•แž›แžทแžแž•แž› แžŠแŸ‚แž›แžขแž“แžปแž‰แŸ’แž‰แžถแžแžฑแŸ’แž™แž˜แžถแž“แžŸแŸ†แžŽแžพ `/v1/responses` แžšแž™แŸˆแž–แŸแž›แžœแŸ‚แž„แž–แŸ’แžšแž˜แž‚แŸ’แž“แžถแžแŸ’แžšแžนแž˜แžแŸ‚แž–แžธแžšแž“แŸ„แŸ‡แž‘แŸแŸ” แž€แžถแžšแž‘แž‘แžฝแž›แž™แž€ chat แž’แŸ’แž„แž“แŸ‹แŸ—แžแŸ’แžšแžผแžœแž”แžถแž“แž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแž„แžŠแŸ„แž™แžแžœแžทแž€แžถแž”แŸƒแžŸแž˜แŸ’แžšแžถแž”แŸ‹ ingest แžŠแŸ‚แž›แž”แžถแž“แž€แŸ†แžŽแžแŸ‹แžŠแŸ„แž™แžŸแŸ’แžœแŸแž™แž”แŸ’แžšแžœแžแŸ’แžแžท (`OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES`, `src/shared/middleware/admissionBudget.ts`) แž“แžทแž„แžแŸ’แžšแžผแžœแž”แžถแž“แž€แŸ†แžŽแžแŸ‹แž‘แŸ†แž แŸ†แžŠแŸ„แž™แž•แŸ’แžขแŸ‚แž€แž›แžพแžŠแŸ‚แž“แž€แŸ†แžŽแžแŸ‹ V8/cgroup แžŠแžŠแŸ‚แž›แž“แŸ„แŸ‡ โ€” แž€แžถแžšแž€แŸ†แžŽแžแŸ‹แžแž˜แŸ’แž›แŸƒแžœแžถแžฑแŸ’แž™แžแŸ’แž–แžŸแŸ‹แž‡แžถแž„แž˜แžปแž“ (แžฌแž€แžถแžšแž€แŸ†แžŽแžแŸ‹แžŠแŸ‚แž“แž€แŸ†แžŽแžแŸ‹แž…แŸ†แž“แžฝแž“แžŸแŸ†แžŽแžพแž…แžถแžŸแŸ‹ `OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT`) แž›แžพแžŠแŸ†แžŽแžพแžšแž€แžถแžšแžŠแŸ‚แž›แž”แžถแž“แž€แŸ†แžŽแžแŸ‹แž‘แŸ†แž แŸ†แžšแžฝแž…แž แžพแž™ แž“แžนแž„แž’แŸ’แžœแžพแžฑแŸ’แž™แž€แžถแžšแž”แž‰แŸ’แžˆแž”แŸ‹แž“แŸแŸ‡แž€แžพแžแžกแžพแž„แžœแžทแž‰แŸ” Chat แžแžผแž…แŸ—, `/healthz`, `/v1/models` แž“แžทแž„ MCP **แž˜แžทแž“** แžŸแŸ’แžแžทแžแž“แŸ…แž€แŸ’แž“แžปแž„แžŠแŸ‚แž“แž€แŸ†แžŽแžแŸ‹แž“แŸ„แŸ‡แž‘แŸแŸ” ### แžŠแŸ†แžŽแžพแžšแž€แžถแžšแžแŸ‚แž˜แžฝแž™แŸ– แžŸแŸ†แžŽแžพ `/v1/responses` แžšแž™แŸˆแž–แŸแž›แžœแŸ‚แž„แž›แžพแžŸแž–แžธแž–แžธแžš แžŠแŸ†แžŽแžพแžšแž€แžถแžšแžŠแŸ‚แž›แž˜แžถแž“ **แžŸแžปแžแž—แžถแž–แž›แŸ’แžข** (heap แž‘แžถแž”แž‡แžถแž„ `OMNIROUTE_CHAT_ADMISSION_HEAP_SHED_RATIO` แžŠแŸ‚แž›แžแž˜แŸ’แž›แŸƒแž›แŸ†แž“แžถแŸ†แžŠแžพแž˜แž‚แžบ `0.75`) **แžขแžถแž…** แžŠแŸ†แžŽแžพแžšแž€แžถแžšแžŸแŸ†แžŽแžพ `POST /v1/responses` แžšแž™แŸˆแž–แŸแž›แžœแŸ‚แž„แž–แŸ’แžšแž˜แž‚แŸ’แž“แžถแž›แžพแžŸแž–แžธแž–แžธแžš แž“แŸ…แž–แŸแž›แžŠแŸ‚แž›แžแžœแžทแž€แžถแž”แŸƒ inflight แžŸแž˜แŸ’แžšแžถแž”แŸ‹แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž‘แžถแŸ†แž„แž˜แžผแž› (`OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES` / #10110) แž“แŸ…แž˜แžถแž“แž‘แŸ†แž แŸ†แž‘แŸ†แž“แŸแžšแŸ” Body แžŠแŸ‚แž›แž˜แžถแž“แž‘แŸ†แž แŸ†แžŸแŸ’แž˜แžพ แžฌแž’แŸ†แž‡แžถแž„ `OMNIROUTE_CHAT_LARGE_BODY_BYTES` (แžแž˜แŸ’แž›แŸƒแž›แŸ†แž“แžถแŸ†แžŠแžพแž˜ 256โ€ฏKiB) แž”แŸ’แžšแžพ lease แž’แŸ’แž„แž“แŸ‹แžŠแžผแž…แž‚แŸ’แž“แžถแž“แžนแž„แžŸแŸ†แžŽแžพแžŠแŸ‚แž›แž˜แžถแž“แžšแž…แž“แžถแžŸแž˜แŸ’แž–แŸแž“แŸ’แž’แžŸแŸ’แž˜แžปแž‚แžŸแŸ’แž˜แžถแž‰ แž แžพแž™แž”แŸ’แžšแžพแž•แŸ’แž›แžผแžœแž‚แŸแž… `tryAcquireHealthyHeadroom` แžŠแžผแž…แž‚แŸ’แž“แžถแž–แžธ [#10437](https://github.com/diegosouzapw/OmniRoute/pull/10437) (`OMNIROUTE_CHAT_ADMISSION_HEALTHY_HEADROOM`)แŸ” แž€แžถแžšแž˜แžถแž“ client SSE แžšแž™แŸˆแž–แŸแž›แžœแŸ‚แž„แžšแžถแž”แŸ‹แžŸแžทแž”แž–แŸ’แžšแž˜แž‚แŸ’แž“แžถ (แž‡แžถแž‰แžนแž€แž‰แžถแž”แŸ‹ แž”แŸ’แžšแžแžทแž”แžแŸ’แžแžทแž€แžšแžแŸ’แžšแžผแžœแž€แžถแžš 40โ€“50) แž‚แžบแž‡แžถแž”แž‰แŸ’แž แžถ **แžแžœแžทแž€แžถแžขแž„แŸ’แž‚แž…แž„แž…แžถแŸ†** โ€” แžแŸ’แžšแžผแžœแž€แŸ†แžŽแžแŸ‹แž‘แŸ†แž แŸ† heap + slot แž…แž˜แŸ’แž”แž„/headroom + `OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES` โ€” แž˜แžทแž“แž˜แŸ‚แž“แž‡แžถแžŠแŸ‚แž“แž€แŸ†แžŽแžแŸ‹แž•แž›แžทแžแž•แž›แžŠแžถแž…แŸ‹แžแžถแžแžแžถ ยซแžขแžแžทแž”แžšแž˜แžถ 2ยป แž“แŸ„แŸ‡แž‘แŸแŸ” Heap แžŠแŸ‚แž›แžšแž„แžŸแž˜แŸ’แž–แžถแž’แž“แŸ…แžแŸ‚แž”แžŠแžทแžŸแŸแž’แžŸแŸ†แžŽแžพแžŠแŸ„แž™แž”แŸ’แžšแžพ `503` แžŠแŸ‚แž›แžขแžถแž…แžŸแžถแž€แž›แŸ’แž”แž„แžกแžพแž„แžœแžทแž‰แž”แžถแž“ แžŠแžพแž˜แŸ’แž”แžธแž€แžปแŸ†แžฑแŸ’แž™แž”แž‰แŸ’แž แžถ #7849 แž€แžพแžแžกแžพแž„แžœแžทแž‰แŸ” แžŠแžพแž˜แŸ’แž”แžธ **แž”แž„แŸ’แž€แžพแž“แž…แŸ†แž“แžฝแž“ heap** (V8 old-space แžฏแž€แžšแžถแž‡แŸ’แž™) **แž“แžถแž–แŸแž›แž”แž…แŸ’แž…แžปแž”แŸ’แž”แž“แŸ’แž“**แŸ– | แžขแŸ’แžœแžธแžŠแŸ‚แž›แžแŸ’แžšแžผแžœแž’แŸ’แžœแžพ | แžขแŸ’แžœแžธแžŠแŸ‚แž›แž˜แžทแž“แžแŸ’แžšแžผแžœแž’แŸ’แžœแžพ | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | | แžŠแŸ†แžŽแžพแžšแž€แžถแžš **container/pod แž…แŸ†แž“แžฝแž“ N** แžŠแŸ„แž™แž˜แžฝแž™แŸ—แž˜แžถแž“ `DATA_DIR` / volume **แž•แŸ’แž‘แžถแž›แŸ‹แžแŸ’แž›แžฝแž“** | แž€แŸ†แžŽแžแŸ‹ `replicas > 1` แžฑแŸ’แž™แž”แŸ’แžšแžพแžฏแž€แžŸแžถแžš SQLite แžแŸ‚แž˜แžฝแž™ | | แž€แŸ†แžŽแžแŸ‹แž‘แŸ†แž แŸ† heavy in-flight + healthy-headroom แžŠแŸ„แž™แž•แŸ’แžขแŸ‚แž€แž›แžพแžแžœแžทแž€แžถ heap / inflight-byte; 1โ€“2 แž‚แžบแž‡แžถแžแž˜แŸ’แž›แŸƒแž›แŸ†แž“แžถแŸ†แžŠแžพแž˜แž”แŸ‚แž”แž”แŸ’แžšแžปแž„แž”แŸ’แžšแž™แŸแžแŸ’แž“แžŸแž˜แŸ’แžšแžถแž”แŸ‹ #7849 แž˜แžทแž“แž˜แŸ‚แž“แž‡แžถแžŠแŸ‚แž“แž€แŸ†แžŽแžแŸ‹แžขแžแžทแž”แžšแž˜แžถแžŠแžถแž…แŸ‹แžแžถแžแžšแž”แžŸแŸ‹แž•แž›แžทแžแž•แž›แž‘แŸ | แž•แŸ’แžŠแž›แŸ‹ RAM 8ร— แžฑแŸ’แž™แžŠแŸ†แžŽแžพแžšแž€แžถแžšแžแŸ‚แž˜แžฝแž™ แž แžพแž™แž”แŸ’แžšแžพแžŠแŸ‚แž“แž€แŸ†แžŽแžแŸ‹แž…แŸ†แž“แžฝแž“แžŠแŸ‚แž›แž‚แŸ’แž˜แžถแž“แž–แŸ’แžšแŸ†แžŠแŸ‚แž“ | | แž‡แžถแž‡แž˜แŸ’แžšแžพแžŸแŸ– `QUOTA_STORE_DRIVER=redis` + `QUOTA_STORE_REDIS_URL` แžŸแž˜แŸ’แžšแžถแž”แŸ‹ **แž€แž˜แŸ’แž˜แžœแžทแž’แžธแžšแžถแž”แŸ‹ quota แžŠแŸ‚แž›แž”แŸ’แžšแžพแžšแžฝแž˜แž‚แŸ’แž“แžถ** | แž…แžถแžแŸ‹แž‘แžปแž€ Redis แž‡แžถ SQLite แžŠแŸ‚แž›แž”แŸ’แžšแžพแžšแžฝแž˜แž‚แŸ’แž“แžถ โ€” แžœแžถแž˜แžทแž“แž˜แŸ‚แž“แžŠแžผแž…แŸ’แž“แŸ„แŸ‡แž‘แŸ | | แž…แž˜แŸ’แž›แž„ secret แžšแž”แžŸแŸ‹ provider แž‘แŸ…แž€แŸ’แž“แžปแž„ instance แž“แžธแž˜แžฝแž™แŸ— (แžฌแž‘แž‘แžฝแž›แž™แž€ dashboard แžŠแŸ‚แž›แž”แŸ‚แž„แž…แŸ‚แž€แžŠแžถแž…แŸ‹แžŠแŸ„แž™แžกแŸ‚แž€) | แžšแŸ†แž–แžนแž„แžแžถแž“แžนแž„แž˜แžถแž“ dashboard แžแŸ‚แž˜แžฝแž™ / call-log แžแŸ‚แž˜แžฝแž™แžŸแž˜แŸ’แžšแžถแž”แŸ‹ instance แž‘แžถแŸ†แž„แžขแžŸแŸ‹ | | แžŠแžถแž€แŸ‹ load balancer แžŽแžถแž˜แžฝแž™แž“แŸ…แžแžถแž„แž˜แžปแž; sticky แžแžถแž˜ API key แžฌ session แž‚แžบแž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแžถแž“แŸ‹ | แžแž˜แŸ’แžšแžผแžœแžฑแŸ’แž™แž˜แžถแž“ middleware แž‡แžถแž€แŸ‹แž›แžถแž€แŸ‹แžšแž”แžŸแŸ‹ vendor แžŠแŸ‚แž›แžŠแžนแž„แž–แžธแž‘แŸ†แž แŸ† | แž•แŸ’แž“แŸ‚แž€ hardwareแŸ– แž…แŸ†แž“แžฝแž“แžŸแŸ†แžŽแžพ `/v1/responses` แžšแž™แŸˆแž–แŸแž›แžœแŸ‚แž„แž–แŸ’แžšแž˜แž‚แŸ’แž“แžถแž€แŸ’แž“แžปแž„ instance แž“แžธแž˜แžฝแž™แŸ— แž‚แžบแž‡แžถแž”แž‰แŸ’แž แžถ **แžแžœแžทแž€แžถแžขแž„แŸ’แž‚แž…แž„แž…แžถแŸ†** (heap + inflight-byte / #10110)แŸ” `DATA_DIR` แžฏแž€แžšแžถแž‡แŸ’แž™แž…แŸ†แž“แžฝแž“ `N` แž“แŸ…แžแŸ‚แž”แž„แŸ’แž€แžพแž“ heap แž‡แžถแž…แŸ’แžšแžพแž“แŸ– RAM แžšแž”แžŸแŸ‹ host แžแŸ’แžšแžผแžœแžแŸ‚แžขแžถแž…แž‘แŸ’แžšแž‘แŸ’แžšแž„แŸ‹ `N ร— cgroup` แž˜แžทแž“แž˜แŸ‚แž“ ยซpod 16โ€ฏGi แžแŸ‚แž˜แžฝแž™แžŠแŸ‚แž›แž˜แžถแž“ N=8ยป แž“แŸ„แŸ‡แž‘แŸแŸ” แž€แžปแŸ†แž”แŸ’แžšแžพ `replicas > 1` แž›แžพแžฏแž€แžŸแžถแžš SQLite แžแŸ‚แž˜แžฝแž™แž‡แžถแžŠแžถแž…แŸ‹แžแžถแžแŸ” แž‚แŸ†แžšแžผ Compose (heap แž–แžธแžš แž“แžทแž„ volume แž–แžธแžš โ€” แž˜แžทแž“แž˜แŸ‚แž“ `deploy.replicas: 2`)แŸ– ```yaml services: omniroute-a: image: diegosouzapw/omniroute:3.8.49 environment: DATA_DIR: /app/data OMNIROUTE_MEMORY_MB: "12288" QUOTA_STORE_DRIVER: redis QUOTA_STORE_REDIS_URL: redis://redis:6379 volumes: [omniroute-a-data:/app/data] ports: ["20128:20128"] omniroute-b: image: diegosouzapw/omniroute:3.8.49 environment: DATA_DIR: /app/data OMNIROUTE_MEMORY_MB: "12288" QUOTA_STORE_DRIVER: redis QUOTA_STORE_REDIS_URL: redis://redis:6379 volumes: [omniroute-b-data:/app/data] ports: ["20138:20128"] volumes: omniroute-a-data: omniroute-b-data: ``` แžŠแž„แŸ‹แžŸแŸŠแžธแžแŸแž€แŸ’แž“แžปแž„แžŠแŸ†แžŽแžพแžšแž€แžถแžš (แž•แŸ’แž‘แŸแžšแž€แžถแžšแž„แžถแžš compression แž…แŸแž‰แž–แžธ HTTP isolate) แž˜แžถแž“แž“แŸ…แž€แŸ’แž“แžปแž„ [#11023](https://github.com/diegosouzapw/OmniRoute/issues/11023)แŸ” Cluster แžกแžผแž‡แžธแžแž›แžแŸ‚แž˜แžฝแž™แžŠแŸ‚แž›แž”แŸ’แžšแžพแžŸแŸ’แžแžถแž“แž—แžถแž–แžšแž€แŸ’แžŸแžถแž‘แžปแž€แž™แžผแžšแžขแž„แŸ’แžœแŸ‚แž„แžšแžฝแž˜แž‚แŸ’แž“แžถ แž˜แžถแž“แž“แŸ…แž€แŸ’แž“แžปแž„ [#8075](https://github.com/diegosouzapw/OmniRoute/issues/8075)แŸ” ## แž€แŸ†แž แžปแžŸแžแžถแž˜แžแŸ†แž”แž“แŸ‹แžšแž”แžŸแŸ‹ Gemini แž“แŸ…แž€แŸ’แž“แžปแž„ Docker Google AI Studio / Gemini API แžขแžถแž…แžแŸ’แžšแžกแž”แŸ‹ HTTP 400 แž‡แžถแž˜แžฝแž™ FAILED_PRECONDITION แž“แžทแž„ `User location is not supported for the API use.` แžŸแŸ†แžŽแžพแžŠแŸ‚แž›แž‡แŸ„แž‚แž‡แŸแž™แž“แŸ…แž›แžพ host แž˜แžทแž“แž”แž‰แŸ’แž‡แžถแž€แŸ‹แžแžถ container แž”แŸ’แžšแžพแž•แŸ’แž›แžผแžœแž…แŸแž‰แžŠแžผแž…แž‚แŸ’แž“แžถแž“แŸ„แŸ‡แž‘แŸแŸ” แž›แŸ†แžŠแžถแž”แŸ‹ DNS, แž€แžถแžšแžแž—แŸ’แž‡แžถแž”แŸ‹ IPv4/IPv6, แž•แŸ’แž›แžผแžœ VPN แž“แžทแž„ proxy แžŠแŸ‚แž›แž”แžถแž“แž€แŸ†แžŽแžแŸ‹แžขแžถแž…แžแžปแžŸแž‚แŸ’แž“แžถแŸ” แž–แžทแž“แžทแžแŸ’แž™ [แžแŸ†แž”แž“แŸ‹แžŠแŸ‚แž› Google แž‚แžถแŸ†แž‘แŸ’แžš](https://ai.google.dev/gemini-api/docs/available-regions) แž–แŸ’แžšแž˜แž‘แžถแŸ†แž„แž•แŸ’แž›แžผแžœแžแž—แŸ’แž‡แžถแž”แŸ‹แž‡แžถแž€แŸ‹แžŸแŸ’แžแŸ‚แž„แž•แž„แžŠแŸ‚แžšแŸ” แž€แŸ†แž แžปแžŸแž“แŸแŸ‡แžแŸ‚แž˜แžฝแž™แž˜แžปแžแž˜แžทแž“แžขแžถแž…แž”แž‰แŸ’แž‡แžถแž€แŸ‹แžแžถ API key แž˜แžทแž“แžแŸ’แžšแžนแž˜แžแŸ’แžšแžผแžœแž“แŸ„แŸ‡แž‘แŸแŸ” ### แž•แŸ’แžแž›แŸ‹แžขแžถแž‘แžทแž—แžถแž–แžŠแž›แŸ‹ proxy แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แžถแžšแžแž—แŸ’แž‡แžถแž”แŸ‹แž“แžธแž˜แžฝแž™แŸ— แž”แŸ’แžšแžพ [แž€แžถแžšแž€แŸ†แžŽแžแŸ‹แžšแž…แž“แžถแžŸแž˜แŸ’แž–แŸแž“แŸ’แž’ proxy แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แžถแžšแžแž—แŸ’แž‡แžถแž”แŸ‹แž“แžธแž˜แžฝแž™แŸ—](../ops/PROXY_GUIDE.md#4-level-proxy-system) แžšแž”แžŸแŸ‹ OmniRoute แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แžถแžšแžแž—แŸ’แž‡แžถแž”แŸ‹ Gemini แžŠแŸ‚แž›แžšแž„แž•แž›แž”แŸ‰แŸ‡แž–แžถแž›แŸ‹ แžšแžฝแž…แž’แŸ’แžœแžพ **Test Connection** แž“แžทแž„แžŸแŸ†แžŽแžพแžแžผแž…แž˜แžฝแž™ แž˜แŸ’แžแž„แž‘แŸ€แžแžŠแŸ„แž™แž”แŸ’แžšแžพ model แžŠแžŠแŸ‚แž›แŸ” แžœแžถแžšแž€แŸ’แžŸแžถแž€แžถแžšแž•แŸ’แž›แžถแžŸแŸ‹แž”แŸ’แžแžผแžšแž•แŸ’แž›แžผแžœแžฑแŸ’แž™แž˜แžถแž“แžœแžทแžŸแžถแž›แž—แžถแž–แžแŸ’แžšแžนแž˜แž€แžถแžšแžแž—แŸ’แž‡แžถแž”แŸ‹แž“แŸ„แŸ‡แŸ” แž•แŸ’แž‘แŸ€แž„แž•แŸ’แž‘แžถแžแŸ‹ แžแžถ container แžขแžถแž…แž…แžผแž›แžŠแž›แŸ‹ proxy แž แžพแž™แž€แžถแžšแžแž—แŸ’แž‡แžถแž”แŸ‹แž–แžทแžแž‡แžถแž‡แŸ’แžšแžพแžŸแžšแžพแžŸ แžœแžถแŸ” แž€แžถแžšแž•แŸ’แž›แžถแžŸแŸ‹แž”แŸ’แžแžผแžšแž•แŸ’แž›แžผแžœแž˜แžทแž“แž’แžถแž“แžถแžแžถ upstream แž“แžนแž„แžขแž“แžปแž‰แŸ’แž‰แžถแžแžแžถแž˜แž›แž€แŸ’แžแžแžŽแŸ’แžŒแžแŸ†แž”แž“แŸ‹แž“แŸ„แŸ‡แž‘แŸแŸ” ### แž”แŸ’แžšแŸ€แž”แž’แŸ€แž”แž”แžŽแŸ’แžแžถแž‰แžšแž”แžŸแŸ‹ host แž“แžทแž„ container แžšแž€แŸ’แžŸแžถ key, model แž“แžทแž„แžŸแŸ†แžŽแžพแžฑแŸ’แž™แžŠแžผแž…แž‚แŸ’แž“แžถ แž“แŸ…แž–แŸแž›แž”แŸ’แžšแŸ€แž”แž’แŸ€แž”แž›แž‘แŸ’แž’แž•แž›แžŠแŸ‚แž›แž”แžถแž“แž•แŸ’แž‘แŸ€แž„แž•แŸ’แž‘แžถแžแŸ‹แžขแžแŸ’แžแžŸแž‰แŸ’แž‰แžถแžŽแŸ” แž€แžปแŸ† แž”แžทแž‘แž—แŸ’แž‡แžถแž”แŸ‹แž–แŸแžแŸŒแž˜แžถแž“แžŸแž˜แŸ’แž„แžถแžแŸ‹ แž–แžถแž€แŸ’แž™แžŸแž˜แŸ’แž„แžถแžแŸ‹ proxy แžฌ authorization headers แž–แŸแž‰แž›แŸแž‰แž‘แŸ…แž€แŸ’แž“แžปแž„ issue แžกแžพแž™แŸ” แžŠแŸ†แž”แžผแž„ แž–แžทแž“แžทแžแŸ’แž™แž˜แžพแž›แžแžถแžแžพ OS resolver แž•แŸ’แžแž›แŸ‹ address families แžŽแžถแžแŸ’แž›แŸ‡ แžŠแŸ„แž™แž”แŸ’แžšแžพ command แžŠแžผแž…แž‚แŸ’แž“แžถ แž“แŸ…แž›แžพ host แž“แžทแž„แž“แŸ…แž€แŸ’แž“แžปแž„ containerแŸ– ```bash node -e 'require("node:dns").lookup("generativelanguage.googleapis.com", {all: true}, (error, addresses) => { if (error) { console.error(error.code); process.exitCode = 1; return; } console.log(addresses.map(({family}) => family)); })' docker compose exec omniroute node -e 'require("node:dns").lookup("generativelanguage.googleapis.com", {all: true}, (error, addresses) => { if (error) { console.error(error.code); process.exitCode = 1; return; } console.log(addresses.map(({family}) => family)); })' ``` แž‡แŸ†แž“แžฝแžŸ `omniroute` แžŠแŸ„แž™ service แžŠแŸ‚แž›แžขแŸ’แž“แž€แžŠแŸ†แžŽแžพแžšแž€แžถแžš (แžงแž‘แžถแž แžšแžŽแŸ `omniroute-web`)แŸ” Command แž‘แžถแŸ†แž„แž“แŸแŸ‡ แž”แž„แŸ’แž แžถแž‰ address families แžŠแŸ„แž™แž˜แžทแž“แž˜แžถแž“แž–แŸแžแŸŒแž˜แžถแž“แžŸแž˜แŸ’แž„แžถแžแŸ‹ แžฌ IP addressesแŸ” แžแž˜แŸ’แž›แŸƒ `6` แžŠแŸ‚แž›แž”แžถแž“แžแŸ’แžšแžกแž”แŸ‹แž˜แž€ แž‚แŸ’แžšแžถแž“แŸ‹แžแŸ‚แž”แž„แŸ’แž แžถแž‰แž›แž‘แŸ’แž’แž•แž› IPv6 DNS แž”แŸ‰แžปแžŽแŸ’แžŽแŸ„แŸ‡แŸ– แžœแžถ **แž˜แžทแž“** แž”แž‰แŸ’แž‡แžถแž€แŸ‹แžแžถแž˜แžถแž“แž•แŸ’แž›แžผแžœ IPv6 แžŠแŸ‚แž›แžขแžถแž…แž”แŸ’แžšแžพแž”แžถแž“ แžฌแžขแžถแž…แž…แžผแž›แž”แŸ’แžšแžพ API แž”แžถแž“แž‘แŸแŸ” แž“แŸ…แž€แž“แŸ’แž›แŸ‚แž„แžŠแŸ‚แž›แž”แžถแž“แžŠแŸ†แžกแžพแž„ `curl` แžŸแžผแž˜แž”แŸ’แžšแŸ€แž”แž’แŸ€แž” `curl -4 -I https://generativelanguage.googleapis.com` แž‡แžถแž˜แžฝแž™ `curl -6 -I https://generativelanguage.googleapis.com` แž“แŸ…แž€แŸ’แž“แžปแž„แž”แžšแžทแžŸแŸ’แžแžถแž“แž‘แžถแŸ†แž„แž–แžธแžšแŸ” HTTP response แž”แž‰แŸ’แž‡แžถแž€แŸ‹แž–แžธแž€แžถแžšแžแž—แŸ’แž‡แžถแž”แŸ‹แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แžถแžšแžŸแžถแž€แž›แŸ’แž”แž„แž“แŸ„แŸ‡ แž‘แŸ„แŸ‡แž”แžธแžœแžถแž‡แžถแž€แŸ†แž แžปแžŸแžŠแŸ‚แž›แž˜แžทแž“แž”แžถแž“แž•แŸ’แž‘แŸ€แž„แž•แŸ’แž‘แžถแžแŸ‹ แžขแžแŸ’แžแžŸแž‰แŸ’แž‰แžถแžŽแž€แŸแžŠแŸ„แž™แŸ” แž˜แžถแž“แžแŸ‚แžŸแŸ†แžŽแžพแž‘แŸ…แž€แžถแž“แŸ‹ model แžŠแŸ‚แž›แž”แžถแž“แž•แŸ’แž‘แŸ€แž„แž•แŸ’แž‘แžถแžแŸ‹แžขแžแŸ’แžแžŸแž‰แŸ’แž‰แžถแžŽแž”แŸ‰แžปแžŽแŸ’แžŽแŸ„แŸ‡ แžŠแŸ‚แž›แžขแžถแž…แžŸแžถแž€แž›แŸ’แž”แž„แž›แž€แŸ’แžแžแžŽแŸ’แžŒแžขแž“แžปแž‰แŸ’แž‰แžถแžแžšแž”แžŸแŸ‹ GeminiแŸ” ### แž‡แž˜แŸ’แžšแžพแžŸแž“แŸ…แž€แž˜แŸ’แžšแžทแž hostแŸ– IPv6 แžŠแŸ‚แž›แžŠแŸ†แžŽแžพแžšแž€แžถแžš แž“แžทแž„แž‚แŸ„แž›แž€แžถแžšแžŽแŸ resolver แžขแŸ’แž“แž€แžšแžถแž™แž€แžถแžšแžŽแŸแž“แŸƒ [#12762](https://github.com/diegosouzapw/OmniRoute/issues/12762) แž”แžถแž“แžŸแŸ’แžŠแžถแžš แž€แžถแžšแž…แžผแž›แž”แŸ’แžšแžพแž“แŸ…แž€แŸ’แž“แžปแž„แž”แžšแžทแžŸแŸ’แžแžถแž“แžšแž”แžŸแŸ‹แž–แžฝแž€แž‚แŸ แžŠแŸ„แž™แž”แžพแž€ IPv6 แžšแž”แžŸแŸ‹ container แž“แžทแž„แž•แŸ’แž›แžถแžŸแŸ‹แž”แŸ’แžŠแžผแžš แž€แžถแžšแž‡แŸ’แžšแžพแžŸแžšแžพแžŸแžขแžถแžŸแž™แžŠแŸ’แž‹แžถแž“แžšแž”แžŸแŸ‹ glibcแŸ” แžŸแžผแž˜แž…แžถแžแŸ‹แž‘แžปแž€แžœแžถแž‡แžถแž‡แž˜แŸ’แžšแžพแžŸแž‡แžถแž€แŸ‹แž›แžถแž€แŸ‹แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž”แžšแžทแžŸแŸ’แžแžถแž“แž“แŸ„แŸ‡แŸ” แž”แž‰แŸ’แž‡แžถแž€แŸ‹แžแžถ IPv6 แžšแž”แžŸแŸ‹ host แžŠแŸ†แžŽแžพแžšแž€แžถแžš, egress/routing แžšแž”แžŸแŸ‹ container แž“แžทแž„ firewall rules แžแŸ’แžšแžนแž˜แžแŸ’แžšแžผแžœ แž˜แžปแž“แž–แŸแž›แž€แŸ‚แžŸแž˜แŸ’แžšแžฝแž› preference แžšแž”แžŸแŸ‹ resolverแŸ” แž€แžถแžšแž˜แžถแž“ private ULA address แžแŸ‚แž˜แžฝแž™แž˜แžปแž แž˜แžทแž“แž”แž‰แŸ’แž‡แžถแž€แŸ‹แžแžถแž˜แžถแž“แž€แžถแžšแžแž—แŸ’แž‡แžถแž”แŸ‹ IPv6 แžŸแžถแž’แžถแžšแžŽแŸˆแž‘แŸแŸ” แžŸแž˜แŸ’แžšแžถแž”แŸ‹ service แžŠแŸ‚แž›แž”แžถแž“แž—แŸ’แž‡แžถแž”แŸ‹แž‘แŸ… default network แžšแž”แžŸแŸ‹ Compose แžšแžฝแž…แž แžพแž™ fragment แž“แŸแŸ‡แž”แžพแž€ IPv6 แž“แŸ…แž›แžพ network แž“แŸ„แŸ‡แŸ” แžŸแžผแž˜แžšแž€แŸ’แžŸแžถแž•แŸ’แž“แŸ‚แž€แž•แŸ’แžŸแŸแž„แž‘แŸ€แžแž“แŸƒ service, ports, volumes แž“แžทแž„ configuration แžšแž”แžŸแŸ‹แžขแŸ’แž“แž€แŸ– ```yaml networks: default: enable_ipv6: true ``` แžŸแž˜แŸ’แžšแžถแž”แŸ‹ named network แžŸแžผแž˜แž”แžพแž€แžœแžถแž“แŸ…แž›แžพ network แžŠแŸ‚แž› service แž–แžทแžแž‡แžถแž—แŸ’แž‡แžถแž”แŸ‹แž‘แŸ…แŸ” Docker แžขแžถแž… แž”แŸ‚แž„แž…แŸ‚แž€ ULA subnet แž”แžถแž“แŸ” แž‡แŸ’แžšแžพแžŸแžšแžพแžŸ subnet แž‡แžถแž€แŸ‹แž›แžถแž€แŸ‹แžŠแŸ‚แž›แž˜แžทแž“แž‡แžถแž“แŸ‹แž‚แŸ’แž“แžถ แžแŸ‚แž“แŸ…แž–แŸแž› network แžšแž”แžŸแŸ‹แžขแŸ’แž“แž€ แžแž˜แŸ’แžšแžผแžœแžฑแŸ’แž™แž’แŸ’แžœแžพแžŠแžผแž…แŸ’แž“แŸ„แŸ‡แž”แŸ‰แžปแžŽแŸ’แžŽแŸ„แŸ‡แŸ” แžŸแžผแž˜แž˜แžพแž› [แž”แžŽแŸ’แžแžถแž‰ IPv6 แžšแž”แžŸแŸ‹ Docker](https://docs.docker.com/engine/daemon/ipv6/) แž“แžทแž„ [แž‡แž˜แŸ’แžšแžพแžŸ network แžšแž”แžŸแŸ‹ Compose](https://docs.docker.com/reference/compose-file/networks/#enable_ipv6)แŸ” แž“แŸ…แž›แžพ **image แžŠแŸ‚แž›แž•แŸ’แžขแŸ‚แž€แž›แžพ glibc** แžฏแž€แžŸแžถแžš `/etc/gai.conf` แžขแžถแž…แž•แŸ’แž›แžถแžŸแŸ‹แž”แŸ’แžแžผแžšแž€แžถแžšแž‡แŸ’แžšแžพแžŸแžšแžพแžŸแžขแžถแžŸแž™แžŠแŸ’แž‹แžถแž“แŸ” Dockerfile แžšแž”แžŸแŸ‹ repository แž”แž…แŸ’แž…แžปแž”แŸ’แž”แž“แŸ’แž“แž”แŸ’แžšแžพ DebianแŸ” image แž•แŸ’แž‘แžถแž›แŸ‹แžแŸ’แž›แžฝแž“แžŠแŸ‚แž›แž•แŸ’แžขแŸ‚แž€แž›แžพ musl แž˜แžทแž“แž”แŸ’แžšแžพ mechanism แž“แŸแŸ‡แžšแžฝแž˜แž‚แŸ’แž“แžถแž‘แŸแŸ” แž€แžถแžšแž€แŸ‚แžŸแž˜แŸ’แžšแžฝแž›แžŠแŸ‚แž›แž”แžถแž“แžšแžถแž™แž€แžถแžšแžŽแŸ แž•แŸ’แž›แžถแžŸแŸ‹แž”แŸ’แžแžผแžš ULA label แž–แžธ `label fc00::/7 6` แž‘แŸ… `label fc00::/7 1`แŸ” แž…แžถแž”แŸ‹แž•แŸ’แžแžพแž˜แž–แžธ policy table แž–แŸแž‰แž›แŸแž‰แžšแž”แžŸแŸ‹ image แž แžพแž™แžšแž€แŸ’แžŸแžถแž‘แžปแž€ entry แž•แŸ’แžŸแŸแž„แž‘แŸ€แžแžšแž”แžŸแŸ‹แžœแžถแŸ– แž€แžถแžšแž”แž“แŸ’แžแŸ‚แž˜ `label` แžฌ `precedence` entry แž“แžนแž„แž‡แŸ†แž“แžฝแžŸ default table แž“แŸ„แŸ‡ แžŠแžผแž…แŸ’แž“แŸแŸ‡ file แžŠแŸ‚แž› แž˜แžถแž“แžแŸ‚แž”แž“แŸ’แž‘แžถแžแŸ‹แžŠแŸ‚แž›แž”แžถแž“แž•แŸ’แž›แžถแžŸแŸ‹แž”แŸ’แžแžผแžšแž‚แžบแž˜แžทแž“แž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแžถแž“แŸ‹แž‘แŸแŸ” [แžฏแž€แžŸแžถแžšแž™แŸ„แž„แž“แŸƒแž€แžถแžšแž€แŸ†แžŽแžแŸ‹แžšแž…แž“แžถแžŸแž˜แŸ’แž–แŸแž“แŸ’แž’ glibc](https://github.com/bminor/glibc/blob/master/posix/gai.conf) แž–แž“แŸ’แž™แž›แŸ‹แžขแŸ†แž–แžธแžขแžแŸ’แžแž“แŸแž™แž‘แžถแŸ†แž„แž“แŸ„แŸ‡แŸ” Bind-mount file แžŠแŸ‚แž›แž”แžถแž“แž–แžทแž“แžทแžแŸ’แž™แžšแžฝแž…แž‡แžถ read-only แž“แŸ… `/etc/gai.conf` แž แžพแž™แž”แž„แŸ’แž€แžพแž service แžกแžพแž„แžœแžทแž‰ แžŠแžพแž˜แŸ’แž”แžธแžขแž“แžปแžœแžแŸ’แžแžœแžถแŸ” แžœแžถแž•แŸ’แž›แžถแžŸแŸ‹แž”แŸ’แžแžผแžšแž€แžถแžšแž‡แŸ’แžšแžพแžŸแžšแžพแžŸแžขแžถแžŸแž™แžŠแŸ’แž‹แžถแž“แžšแž”แžŸแŸ‹ OS แžŸแž˜แŸ’แžšแžถแž”แŸ‹ **แž…แžšแžถแž…แžšแž…แŸแž‰แž‘แžถแŸ†แž„แžขแžŸแŸ‹แž“แŸ…แž€แŸ’แž“แžปแž„ container แž“แŸ„แŸ‡**แŸ” แžœแžถแž˜แžทแž“แž”แž„แŸ’แžแŸ†แžฑแŸ’แž™ application แž‘แžถแŸ†แž„แžขแžŸแŸ‹แž‡แŸ’แžšแžพแžŸแžšแžพแžŸ IPv6 แž‘แŸแŸ– แž›แŸ†แžŠแžถแž”แŸ‹ DNS แž“แžทแž„แž€แžถแžšแž‡แŸ’แžšแžพแžŸแžšแžพแžŸ แž€แžถแžšแžแž—แŸ’แž‡แžถแž”แŸ‹แžšแž”แžŸแŸ‹ Node แž€แŸแž˜แžถแž“แžฅแž‘แŸ’แž’แžทแž–แž›แžŠแŸ‚แžšแŸ” แž‡แžถแž–แžทแžŸแŸแžŸ `--dns-result-order=ipv4first` แž•แŸ’แžแž›แŸ‹แžขแžถแž‘แžทแž—แžถแž–แžŠแž›แŸ‹ IPv4 แž แžพแž™ แž˜แžทแž“แž˜แŸ‚แž“แž‡แžถแžŠแŸ†แžŽแŸ„แŸ‡แžŸแŸ’แžšแžถแž™แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แžถแžšแž”แžšแžถแž‡แŸแž™แžŠแŸ‚แž›แž€แžพแžแžกแžพแž„แžแŸ‚แž›แžพ IPv4 แž‘แŸแŸ” แžŸแžผแž˜แž˜แžพแž› [แž›แŸ†แžŠแžถแž”แŸ‹ DNS แžšแž”แžŸแŸ‹ Node](https://nodejs.org/api/dns.html#dnssetdefaultresultorderorder)แŸ” แžŸแžถแž€แž›แŸ’แž”แž„ Gemini แž“แžทแž„ provider แž•แŸ’แžŸแŸแž„แž‘แŸ€แžแžšแž”แžŸแŸ‹แžขแŸ’แž“แž€แž˜แŸ’แžแž„แž‘แŸ€แž แž”แž“แŸ’แž‘แžถแž”แŸ‹แž–แžธแž€แžถแžšแž•แŸ’แž›แžถแžŸแŸ‹แž”แŸ’แžแžผแžšแžŽแžถแž˜แžฝแž™แž“แŸ…แž€แž˜แŸ’แžšแžทแž hostแŸ” แžŠแžพแž˜แŸ’แž”แžธ roll back แžŸแžผแž˜แžŠแž€ custom `gai.conf` mount แž…แŸแž‰ แžŸแŸ’แžŠแžถแžš network configuration แž˜แžปแž“ แž แžพแž™ แž”แž„แŸ’แž€แžพแž service/network แžŠแŸ‚แž›แžšแž„แž•แž›แž”แŸ‰แŸ‡แž–แžถแž›แŸ‹แžกแžพแž„แžœแžทแž‰แž€แŸ’แž“แžปแž„แžขแŸ†แžกแžปแž„ maintenance windowแŸ” แž€แžถแžšแž”แž„แŸ’แž€แžพแž network แžกแžพแž„แžœแžทแž‰ แžขแžถแž…แžšแŸ†แžแžถแž“แžŠแž›แŸ‹ container แž•แŸ’แžŸแŸแž„แž‘แŸ€แžแžŠแŸ‚แž›แž—แŸ’แž‡แžถแž”แŸ‹แž‘แŸ…แžœแžถแŸ” แž€แžปแŸ†แž›แžปแž” persistent data volumeแŸ” ## แž€แŸ†แžŽแžแŸ‹แžŸแž˜แŸ’แž‚แžถแž›แŸ‹แžŸแŸ†แžแžถแž“แŸ‹แŸ— - **แžšแž”แŸ€แž” SQLite WAL:** แž‚แžฝแžšแžขแž“แžปแž‰แŸ’แž‰แžถแžแžฑแŸ’แž™ `docker stop` แžŠแŸ†แžŽแžพแžšแž€แžถแžšแžšแž แžผแžแžŠแž›แŸ‹แž…แž”แŸ‹ แžŠแžพแž˜แŸ’แž”แžธแžฑแŸ’แž™ OmniRoute แžขแžถแž…แž’แŸ’แžœแžพ checkpoint แž€แžถแžšแž•แŸ’แž›แžถแžŸแŸ‹แž”แŸ’แžแžผแžšแž…แžปแž„แž€แŸ’แžšแŸ„แž™แžแŸ’แžšแžกแž”แŸ‹แž‘แŸ…แž€แŸ’แž“แžปแž„ `storage.sqlite`แŸ” แžฏแž€แžŸแžถแžš Compose แžŠแŸ‚แž›แž”แžถแž“แž—แŸ’แž‡แžถแž”แŸ‹แž˜แž€แž‡แžถแž˜แžฝแž™แž”แžถแž“แž€แŸ†แžŽแžแŸ‹แžšแž™แŸˆแž–แŸแž›แžขแž“แžปแž‚แŸ’แžšแŸ„แŸ‡แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แžถแžšแž”แž‰แŸ’แžˆแž”แŸ‹แž…แŸ†แž“แžฝแž“ 40 แžœแžทแž“แžถแž‘แžธแžšแžฝแž…แž แžพแž™แŸ” แž”แŸ’แžšแžŸแžทแž“แž”แžพแžขแŸ’แž“แž€แžŠแŸ†แžŽแžพแžšแž€แžถแžš image แžŠแŸ„แž™แž•แŸ’แž‘แžถแž›แŸ‹ แžŸแžผแž˜แžšแž€แŸ’แžŸแžถ `--stop-timeout 40`แŸ” - **`DISABLE_SQLITE_AUTO_BACKUP`:** แž€แŸ†แžŽแžแŸ‹แž‡แžถ `true` แž”แŸ’แžšแžŸแžทแž“แž”แžพแž€แžถแžšแž”แž˜แŸ’แžšแžปแž„แž‘แžปแž€แžแžถแž˜แž€แžถแž›แž€แŸ†แžŽแžแŸ‹/แž˜แžปแž“แž–แŸแž›แžŸแžšแžŸแŸแžš แžแŸ’แžšแžผแžœแž”แžถแž“แž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแž„แž–แžธแžแžถแž„แž€แŸ’แžšแŸ…แŸ” แž€แžถแžšแž•แŸ’แž›แžถแžŸแŸ‹แž”แŸ’แžแžผแžšแž‘แžทแž“แŸ’แž“แž“แŸแž™แžšแž”แžŸแŸ‹แž˜แžผแž›แžŠแŸ’แž‹แžถแž“แž‘แžทแž“แŸ’แž“แž“แŸแž™แžŠแŸ‚แž›แž˜แžถแž“แžŸแŸ’แžšแžถแž”แŸ‹ แž“แŸ…แžแŸ‚แžแž˜แŸ’แžšแžผแžœแžฑแŸ’แž™แž˜แžถแž“ snapshot แžŸแžปแžœแžแŸ’แžแžทแž—แžถแž–แžŠแŸ‚แž›แžšแž€แŸ’แžŸแžถแž‘แžปแž€แž”แžถแž“แž™แžผแžš แž“แžทแž„แž™แž“แŸ’แžแž€แžถแžšแž€แžถแžšแž–แžถแžšแžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แžถแžšแž•แŸ’แž›แžถแžŸแŸ‹แž”แŸ’แžแžผแžšแž‘แžทแž“แŸ’แž“แž“แŸแž™แž‘แŸ’แžšแž„แŸ‹แž‘แŸ’แžšแžถแž™แž’แŸ†แžŠแŸ„แž™แžกแŸ‚แž€แŸ” - **แž€แžถแžšแžšแž€แŸ’แžŸแžถแž‘แžปแž€แž‘แžทแž“แŸ’แž“แž“แŸแž™แž‡แžถแžขแž…แžทแž“แŸ’แžแŸ’แžšแŸƒแž™แŸ:** แžแŸ’แžšแžผแžœ mount volume แž‘แŸ…แž€แžถแž“แŸ‹ `/app/data` แž‡แžถแž“แžทแž…แŸ’แž… แžŠแžพแž˜แŸ’แž”แžธแžšแž€แŸ’แžŸแžถแž˜แžผแž›แžŠแŸ’แž‹แžถแž“แž‘แžทแž“แŸ’แž“แž“แŸแž™ แžŸแŸ„ แž“แžทแž„แž€แžถแžšแž€แŸ†แžŽแžแŸ‹แžšแž…แž“แžถแžŸแž˜แŸ’แž–แŸแž“แŸ’แž’แžšแž”แžŸแŸ‹แžขแŸ’แž“แž€ แž“แŸ…แž–แŸแž› container แž…แžถแž”แŸ‹แž•แŸ’แžแžพแž˜แžกแžพแž„แžœแžทแž‰แŸ” - **แž€แžถแžšแž€แŸ†แžŽแžแŸ‹แžšแž…แž“แžถแžŸแž˜แŸ’แž–แŸแž“แŸ’แž’แž…แŸ’แžšแž€:** แž€แŸ†แžŽแžแŸ‹แž‡แŸ†แž“แžฝแžŸแžขแžแŸแžšแž”แžšแžทแžŸแŸ’แžแžถแž“ `PORT` แžŠแžพแž˜แŸ’แž”แžธแž•แŸ’แž›แžถแžŸแŸ‹แž”แŸ’แžแžผแžšแž…แŸ’แžšแž€แž›แŸ†แž“แžถแŸ†แžŠแžพแž˜ `20128`แŸ” ## แžŸแžผแž˜แž˜แžพแž›แž•แž„แžŠแŸ‚แžš - [แž˜แž‚แŸ’แž‚แžปแž‘แŸ’แž‘แŸแžŸแž€แŸแžŠแžถแž€แŸ‹แžฑแŸ’แž™แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž›แžพ VM](../ops/VM_DEPLOYMENT_GUIDE.md) โ€” แž€แžถแžšแžšแŸ€แž”แž…แŸ† VM + nginx + Cloudflare - [แž˜แž‚แŸ’แž‚แžปแž‘แŸ’แž‘แŸแžŸแž€แŸแžŠแžถแž€แŸ‹แžฑแŸ’แž™แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž›แžพ Fly.io](../ops/FLY_IO_DEPLOYMENT_GUIDE.md) โ€” แžŠแžถแž€แŸ‹แžฑแŸ’แž™แžŠแŸ†แžŽแžพแžšแž€แžถแžšแž›แžพ Fly.io - [แž€แžถแžšแž€แŸ†แžŽแžแŸ‹แžšแž…แž“แžถแžŸแž˜แŸ’แž–แŸแž“แŸ’แž’แž”แžšแžทแžŸแŸ’แžแžถแž“](../reference/ENVIRONMENT.md) โ€” แžฏแž€แžŸแžถแžšแž™แŸ„แž„ `.env` แž–แŸแž‰แž›แŸแž‰