# exe.dev additions to Omnara's compose.yaml (https://exe.dev/deploy/omnara). # Omnara refuses model endpoints on private addresses unless they are on # loopback, and the exe.dev LLM gateway (llm.int.exe.xyz) is on one. So a # small nginx relay joins the api and worker containers' network namespaces # and forwards http://127.0.0.1:8090 to https://llm.int.exe.xyz. No model # provider key is stored anywhere: exe.dev adds it on the way out. # Likewise, exe-mail.py takes Omnara's SMTP mail on 127.0.0.1:2525 in the # api container and sends it through exe.dev's email gateway. # It also keeps the data services off the VM's ports (they stay on the # Compose network) and gives them a restart policy, so the stack comes back # after a VM restart. configs: exe-mail: file: ./exe-mail.py exe-llm-relay: content: | server { listen 127.0.0.1:8090; location / { proxy_pass https://llm.int.exe.xyz; proxy_ssl_server_name on; proxy_set_header Host llm.int.exe.xyz; proxy_set_header Authorization ""; proxy_set_header X-Api-Key ""; proxy_http_version 1.1; proxy_buffering off; proxy_request_buffering off; proxy_read_timeout 1h; proxy_send_timeout 1h; } } x-llm-relay: &llm-relay profiles: ["app"] image: nginxinc/nginx-unprivileged:1.29.5-alpine configs: - source: exe-llm-relay target: /etc/nginx/conf.d/default.conf # Docker can start a sidecar before the container whose network it joins # (after a VM restart, say), leaving it with only a loopback interface. # Exit when there is no default route, and the restart policy rejoins. entrypoint: ["/bin/sh", "-c"] command: - | nginx -g 'daemon off;' & while sleep 5; do grep -qE '^[^[:space:]]+[[:space:]]+00000000' /proc/net/route || exit 1 done restart: unless-stopped services: redis: ports: !reset [] restart: unless-stopped postgres: ports: !reset [] restart: unless-stopped rustfs: ports: !reset [] restart: unless-stopped api-llm: <<: *llm-relay network_mode: service:api worker-llm: <<: *llm-relay network_mode: service:worker api-mail: profiles: ["app"] image: python:3.13-alpine network_mode: service:api configs: - source: exe-mail target: /exe-mail.py # The same watchdog as the relays'. entrypoint: ["/bin/sh", "-c"] command: - | python3 -u /exe-mail.py & while sleep 5; do grep -qE '^[^[:space:]]+[[:space:]]+00000000' /proc/net/route || exit 1 done restart: unless-stopped