Outbound proxy
Give an app an optional Xray sidecar so selected outbound HTTP(S) calls leave the cluster through your VLESS or VMess server.
Use this when the app must reach the public internet through a proxy you already operate — not as a cluster-wide network policy, and not as a transparent intercept for every packet. Custom container apps and Airbyte support this setting.
How it works
Application
↓ HTTP_PROXY / HTTPS_PROXY (when injection is on)
127.0.0.1:8080
↓
Xray sidecar (same instance)
↓ VLESS or VMess
External proxy server
↓
Internet
The sidecar shares the instance network namespace. Kubernetes in-cluster names stay reachable: NO_PROXY excludes localhost, 127.0.0.1, .svc, .svc.cluster.local, and .cluster.local unless you already set NO_PROXY yourself.
Xooshe generates the Xray config from the parsed connection. You do not paste raw Xray JSON.
On Airbyte, the sidecar is added to the server, worker, cron, and workload-launcher instances — not Temporal or the bootloader hook. Connector sync jobs are separate pods; Xooshe also requests the sidecar on those jobs. If a job starts without it, that connector will not see 127.0.0.1:8080. In-cluster PostgreSQL and object storage stay excluded via NO_PROXY.
Enable a proxy
- Open the app → general configuration.
- Edit Outbound proxy.
- Turn Enable proxy on.
- Paste a
vless://orvmess://share link. - Click Parse / Validate. Confirm the non-secret summary (protocol, server, port, transport, security).
- Keep All external traffic unless you only want to store the connection without using it (Direct).
- Leave Inject HTTP_PROXY / HTTPS_PROXY on if the app honors those variables. Turn it off if you will point the app at
127.0.0.1:8080yourself. - Save. Instances recreate so the sidecar and (if enabled) environment variables apply.
Your role needs change on general app settings.
Disable a proxy
- Open Outbound proxy.
- Turn Enable proxy off and save.
The next deploy removes the sidecar, the proxy Secret, injected HTTP_PROXY / HTTPS_PROXY / NO_PROXY, and the proxy volume. Stored credentials stay in Xooshe so you can turn the proxy back on without pasting the URI again.
Security
- Credentials (UUID, Reality public key, short id) are secrets. Normal API reads and the dashboard show only the public summary.
- The generated Xray document is a Kubernetes Secret, not a ConfigMap.
- Access logs are off. Xray logs at
warningand must not include URIs or credentials. - Behavior is fail-closed: if the sidecar is down, apps that use
127.0.0.1:8080cannot fall back to a direct internet path through that proxy setting. - One app's proxy never applies to another app.
- HTTP_PROXY / HTTPS_PROXY do not cover every runtime. Go, Java, and some HTTP clients ignore them unless configured. Injection is the first supported mechanism, not a transparent proxy. iptables / TProxy is not implemented.
Traffic modes
| Mode | What happens |
|---|---|
| All external traffic | Sidecar runs. Non-private destinations go through VLESS/VMess. Private / cluster DNS stays direct. |
| Direct | Connection can stay stored. Sidecar is not deployed. |
| Selective (later) | Route only some domains through the proxy. Not available yet. |
User-set HTTP_PROXY / HTTPS_PROXY / NO_PROXY always win over Xooshe injection.
If it fails
Sidecar not starting. Open Logs, pick the xooshe-proxy container. A bad URI usually fails at Parse / Validate before deploy. After deploy, a listen failure on 8080 means the process did not start — check the pinned Xray image can be pulled.
Invalid configuration. Re-parse the URI. Supported combinations: VLESS or VMess with TCP, WebSocket, or gRPC; security none, TLS, or Reality (VLESS only). Reality needs SNI and a public key.
App cannot reach an external service. Confirm the app honors HTTP_PROXY / HTTPS_PROXY, or point it at http://127.0.0.1:8080. Check NO_PROXY is not excluding the destination you meant to proxy.
Connection refused on 8080. The sidecar is not ready. Wait for the instance to become ready, or inspect xooshe-proxy logs.
TLS / Reality errors. Server name, fingerprint, and Reality public key must match the remote server. Xooshe does not display those secrets after save — paste the URI again to replace them.
App bypasses the proxy. The runtime is ignoring proxy environment variables. Disable injection and configure the app explicitly, or treat transparent proxying as a future capability.
You’re done when
- Outbound proxy shows the public summary (no UUID).
- The instance includes an
xooshe-proxycontainer when the mode is All external traffic. - Disabling the proxy removes that container on the next deploy.