Skip to content

Commit 1ad10e6

Browse files
committed
docs: add nginx-omni
Signed-off-by: Amarachi Iheanacho <amarachi.iheanacho@siderolabs.com>
1 parent d03481c commit 1ad10e6

File tree

1 file changed

+215
-123
lines changed

1 file changed

+215
-123
lines changed
Lines changed: 215 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -1,133 +1,225 @@
11
---
2-
title: Expose Omni with Nginx (HTTPS)
3-
description: Configure Nginx as an HTTPS reverse proxy for Omni
2+
title: "Expose Omni with Nginx (HTTPS)"
3+
description: "Configure Nginx as an HTTPS reverse proxy for on-premises Omni deployments."
44
---
55

6-
### Omni deployment configuration
6+
This guide assumes Omni is deployed following the [Run Omni On-Prem](./run-omni-on-prem) guide. However, the flags used in the **Deploy Omni** section are modified as shown in **Step 1** so that Nginx handles all public traffic.
7+
8+
In this setup, Nginx runs in front of Omni and routes traffic to three public endpoints:
9+
10+
| Endpoint | Purpose |
11+
| --- | --- |
12+
| `https://$OMNI_DOMAIN_NAME` | Omni UI and main API |
13+
| `https://api.$OMNI_DOMAIN_NAME` | SideroLink machine API |
14+
| `https://kube.$OMNI_DOMAIN_NAME` | Kubernetes proxy |
15+
16+
Omni itself listens only on localhost, while Nginx handles TLS termination and all external traffic.
17+
18+
## Prerequisites
19+
20+
Before proceeding, ensure the following:
21+
22+
- Install Nginx on the machine serving public traffic
23+
- Open ports 80 and 443 on the Nginx machine
24+
- Create the following DNS A records and point them to the public IP address of the Nginx machine:
25+
- `<omni-domain-name>`
26+
- `api.<omni-domain-name>`
27+
- `kube.<omni-domain-name>`
28+
29+
Replace `<omni-domain-name>` with your Omni domain name (for example, `omni.example.com`) in the DNS records above and throughout this guide.
30+
31+
**If Nginx and Omni run on the same machine**, no additional network configuration is required. The `127.0.0.1` addresses in the Nginx configuration proxy traffic to Omni over localhost.
32+
33+
**If Nginx and Omni run on separate machines:**
34+
- The Omni machine must be reachable from the Nginx machine over the internal network.
35+
- Open ports 8080, 8090, and 8100 on the Omni machine
36+
- Replace `127.0.0.1` in the Nginx configuration file with the internal IP address of the Omni machine
37+
38+
## Step 1: Start Omni with the Nginx Flags
39+
40+
Follow the [Run Omni On-Prem](./run-omni-on-prem) guide to deploy Omni on-prem.
41+
Before starting the Omni instance using either `docker run` or `docker compose`, complete the following steps.
42+
43+
1. Verify that the required environment variables from the on-prem guide are set in your shell:
44+
45+
```bash
46+
echo $OMNI_DOMAIN_NAME
47+
echo $OMNI_ACCOUNT_UUID
48+
```
49+
50+
2. If any are variables are missing, export them now:
51+
52+
```bash
53+
export OMNI_DOMAIN_NAME=<omni-domain> # e.g omni.example.com
54+
export OMNI_ACCOUNT_UUID=<account-id> # your Omni account ID
55+
```
56+
57+
3. Start Omni using the following flags. Remember to include the authentication flags required by your authentication provider. For more details, see the [configure authentication guide](./run-omni-on-prem#configure-authentication):
58+
59+
```bash
60+
--name=$OMNI_NAME \
61+
--private-key-source=file:///omni.asc \
62+
--bind-addr=127.0.0.1:8080 \
63+
--advertised-api-url=https://$OMNI_DOMAIN_NAME/ \
64+
--siderolink-api-bind-addr=127.0.0.1:8090 \
65+
--siderolink-api-advertised-url=https://api.$OMNI_DOMAIN_NAME:443 \
66+
--k8s-proxy-bind-addr=127.0.0.1:8100 \
67+
--advertised-kubernetes-proxy-url=https://kube.$OMNI_DOMAIN_NAME/ \
68+
--account-id=$OMNI_ACCOUNT_UUID
69+
# Also add the authentication flags according to your setup
70+
```
71+
72+
<Info>Authentication flags are not included here. Add the appropriate flags for your auth provider as described in the [authentication configuration guide](./run-omni-on-prem#configure-authentication). </Info>
73+
74+
**Example:** Starting an Omni instance might look similar to the following:
75+
76+
```bash
77+
docker run \
78+
--net=host \
79+
--cap-add=NET_ADMIN \
80+
--device /dev/net/tun \
81+
-v $PWD/etcd:/_out/etcd \
82+
-v $PWD/omni.asc:/omni.asc \
83+
ghcr.io/siderolabs/omni:<tag> \
84+
--name=$OMNI_NAME \
85+
--private-key-source=file:///omni.asc \
86+
--bind-addr=127.0.0.1:8080 \
87+
--advertised-api-url=https://$OMNI_DOMAIN_NAME/ \
88+
--siderolink-api-bind-addr=127.0.0.1:8090 \
89+
--siderolink-api-advertised-url=https://api.$OMNI_DOMAIN_NAME:443 \
90+
--k8s-proxy-bind-addr=127.0.0.1:8100 \
91+
--advertised-kubernetes-proxy-url=https://kube.$OMNI_DOMAIN_NAME/ \
92+
--account-id=$OMNI_ACCOUNT_UUID \
93+
--auth-auth0-enabled=true \
94+
--auth-auth0-domain=<Auth0 domain> \
95+
--auth-auth0-client-id=<Auth0 client ID> \
96+
--initial-users=<email address>
97+
```
98+
## Step 2: Provision TLS Certificates
99+
100+
Use `acme` or `certbot` to generate TLS certificates for all three subdomains. **Step 3** expects the certificates at the following paths. If your certificates are stored elsewhere, update the paths in the Nginx config accordingly.
101+
102+
| Subdomain | Certificate path |
103+
|---|---|
104+
| `$OMNI_DOMAIN_NAME` | `/var/lib/acme/omni/` |
105+
| `api.$OMNI_DOMAIN_NAME` | `/var/lib/acme/omni_api/` |
106+
| `kube.$OMNI_DOMAIN_NAME` | `/var/lib/acme/omni_kube/` |
107+
108+
## Step 3: Apply the Nginx Configuration
109+
110+
Run the following command to write the Nginx config:
111+
112+
```sh
113+
cat <<EOF > /etc/nginx/nginx.conf
114+
http {
115+
proxy_redirect off;
116+
proxy_http_version 1.1;
117+
proxy_connect_timeout 60s;
118+
# Omni requires long timeouts for long-lived connections
119+
proxy_send_timeout 1h;
120+
proxy_read_timeout 1h;
121+
122+
# Used for WebSocket proxying
123+
map \$http_upgrade \$connection_upgrade {
124+
default upgrade;
125+
'' close;
126+
}
127+
128+
# Redirect HTTP to HTTPS
129+
server {
130+
listen 0.0.0.0:80;
131+
listen [::0]:80;
132+
server_name $OMNI_DOMAIN_NAME;
133+
location / {
134+
return 301 https://\$host\$request_uri;
135+
}
136+
}
137+
138+
map \$http_content_type \$is_grpc {
139+
default 0;
140+
"application/grpc" 1;
141+
}
142+
143+
# Main Omni API — routes gRPC and HTTP traffic
144+
server {
145+
listen 0.0.0.0:443 http2 ssl;
146+
listen [::0]:443 http2 ssl;
147+
server_name $OMNI_DOMAIN_NAME;
148+
ssl_certificate /var/lib/acme/omni/fullchain.pem;
149+
ssl_certificate_key /var/lib/acme/omni/key.pem;
150+
ssl_trusted_certificate /var/lib/acme/omni/chain.pem;
151+
152+
location / {
153+
error_page 418 = @grpc;
154+
error_page 419 = @http;
155+
if (\$is_grpc) {
156+
return 418;
157+
}
158+
return 419;
159+
}
160+
161+
location @grpc {
162+
# Long timeouts required for long-lived gRPC stream connections
163+
grpc_read_timeout 1h;
164+
grpc_send_timeout 1h;
165+
grpc_pass grpc://127.0.0.1:8080;
166+
}
167+
168+
location @http {
169+
proxy_pass http://127.0.0.1:8080;
170+
proxy_set_header Upgrade \$http_upgrade;
171+
proxy_set_header Connection \$connection_upgrade;
172+
}
173+
}
174+
175+
# SideroLink (Machine) API
176+
server {
177+
listen 0.0.0.0:443 http2 ssl;
178+
listen [::0]:443 http2 ssl;
179+
server_name api.$OMNI_DOMAIN_NAME;
180+
ssl_certificate /var/lib/acme/omni_api/fullchain.pem;
181+
ssl_certificate_key /var/lib/acme/omni_api/key.pem;
182+
ssl_trusted_certificate /var/lib/acme/omni_api/chain.pem;
183+
184+
location / {
185+
# Long timeouts required for long-lived gRPC stream connections
186+
grpc_read_timeout 1h;
187+
grpc_send_timeout 1h;
188+
grpc_pass grpc://127.0.0.1:8090;
189+
}
190+
}
191+
192+
# Kubernetes Proxy API
193+
server {
194+
listen 0.0.0.0:443 http2 ssl;
195+
listen [::0]:443 http2 ssl;
196+
server_name kube.$OMNI_DOMAIN_NAME;
197+
ssl_certificate /var/lib/acme/omni_kube/fullchain.pem;
198+
ssl_certificate_key /var/lib/acme/omni_kube/key.pem;
199+
ssl_trusted_certificate /var/lib/acme/omni_kube/chain.pem;
200+
201+
location / {
202+
proxy_pass http://127.0.0.1:8100;
203+
proxy_set_header Upgrade \$http_upgrade;
204+
proxy_set_header Connection \$connection_upgrade;
205+
}
206+
}
207+
}
208+
EOF
209+
```
7210

8-
You need to deploy an omni instance the [how to deploy omni on prem guide](./run-omni-on-prem.mdx), with the following flags set:
211+
Then reload Nginx:
9212

10213
```bash
11-
--name=$OMNI_NAME
12-
--private-key-source=file:///omni.asc
13-
--bind-addr=127.0.0.1:8080
14-
--advertised-api-url=https://$OMNI_DOMAIN/
15-
--siderolink-api-bind-addr=127.0.0.1:8090
16-
--siderolink-api-advertised-url=https://api.$OMNI_DOMAIN:443
17-
--k8s-proxy-bind-addr=127.0.0.1:8100
18-
--advertised-kubernetes-proxy-url=https://kube.$OMNI_DOMAIN/
19-
--account-id=$OMNI_UUID
20-
## Also add the authentication flags according to your setup
214+
nginx -t && systemctl reload nginx
21215
```
22216

23-
### Certificates
24-
25-
You can use acme or certbot to generate certificates for your domain. In the following nginx config, the are stored in `/var/lib/acme/omni/` and `/var/lib/acme/omni_api/` and `/var/lib/acme/omni_kube/`. Make sure to change the paths to your own or to output the certificates to those paths.
26-
27-
### Nginx configuration
28-
29-
Use the following configuration to expose omni with nginx. Make sure to change the domain name (`$OMNI_DOMAIN`) to your own domain and to update the certificate paths if applicable.
30-
31-
```nginx
32-
http {
33-
proxy_redirect off;
34-
proxy_http_version 1.1;
35-
36-
proxy_connect_timeout 60s;
37-
38-
# Omni needs long timeouts for the long-lived connections
39-
proxy_send_timeout 1h;
40-
proxy_read_timeout 1h;
41-
42-
# $connection_upgrade is used for websocket proxying
43-
map $http_upgrade $connection_upgrade {
44-
default upgrade;
45-
'' close;
46-
}
47-
48-
# Omni HTTPS redirection
49-
server {
50-
listen 0.0.0.0:80;
51-
listen [::0]:80;
52-
server_name $OMNI_DOMAIN;
53-
location / {
54-
return 301 https://$host$request_uri;
55-
}
56-
}
57-
58-
map $http_content_type $is_grpc {
59-
default 0;
60-
"application/grpc" 1;
61-
}
62-
63-
# Omni main API
64-
server {
65-
listen 0.0.0.0:443 http2 ssl;
66-
listen [::0]:443 http2 ssl;
67-
server_name $OMNI_DOMAIN;
68-
ssl_certificate /var/lib/acme/omni/fullchain.pem;
69-
ssl_certificate_key /var/lib/acme/omni/key.pem;
70-
ssl_trusted_certificate /var/lib/acme/omni/chain.pem;
71-
location / {
72-
error_page 418 = @grpc;
73-
error_page 419 = @http;
74-
75-
if ($is_grpc) {
76-
return 418;
77-
}
78-
79-
return 419;
80-
}
81-
82-
# Omni main GRPC API
83-
location @grpc {
84-
# Omni needs long timeouts for the long-lived GRPC stream connections
85-
grpc_read_timeout 1h;
86-
grpc_send_timeout 1h;
87-
grpc_pass grpc://127.0.0.1:8080;
88-
}
89-
90-
# Omni main HTTP API
91-
location @http {
92-
proxy_pass http://127.0.0.1:8080;
93-
proxy_set_header Upgrade $http_upgrade;
94-
proxy_set_header Connection $connection_upgrade;
95-
}
96-
}
97-
98-
# Omni SideroLink (a.k.a. Machine) API
99-
server {
100-
listen 0.0.0.0:443 http2 ssl;
101-
listen [::0]:443 http2 ssl;
102-
server_name api.$OMNI_DOMAIN;
103-
ssl_certificate /var/lib/acme/omni_api/fullchain.pem;
104-
ssl_certificate_key /var/lib/acme/omni_api/key.pem;
105-
ssl_trusted_certificate /var/lib/acme/omni_api/chain.pem;
106-
location / {
107-
# Omni needs long timeouts for the long-lived GRPC stream connections
108-
grpc_read_timeout 1h;
109-
grpc_send_timeout 1h;
110-
grpc_pass grpc://127.0.0.1:8090;
111-
}
112-
}
113-
114-
# Omni Kube API
115-
server {
116-
listen 0.0.0.0:443 http2 ssl;
117-
listen [::0]:443 http2 ssl;
118-
server_name kube.$OMNI_DOMAIN;
119-
ssl_certificate /var/lib/acme/omni_kube/fullchain.pem;
120-
ssl_certificate_key /var/lib/acme/omni_kube/key.pem;
121-
ssl_trusted_certificate /var/lib/acme/omni_kube/chain.pem;
122-
location / {
123-
proxy_pass http://127.0.0.1:8100;
124-
proxy_set_header Upgrade $http_upgrade;
125-
proxy_set_header Connection $connection_upgrade;
126-
}
127-
}
128-
}
129-
```
217+
## Endpoints
130218

131-
## How to use
219+
Once Nginx is running, your Omni instance is accessible at:
132220

133-
The omni instance will be available at `https://$OMNI_DOMAIN/`, the API at `https://api.$OMNI_DOMAIN/` and the kubernetes proxy at `https://kube.$OMNI_DOMAIN/`.
221+
| Service | URL |
222+
|---|---|
223+
| Omni UI & API | `https://$OMNI_DOMAIN_NAME/` |
224+
| SideroLink (Machine) API | `https://api.$OMNI_DOMAIN_NAME/` |
225+
| Kubernetes Proxy | `https://kube.$OMNI_DOMAIN_NAME/` |

0 commit comments

Comments
 (0)