Skip to main content

Network Access: Domain or IP

Nginx runs on the host and publishes the stack. Follow Option A if you chose the domain block in .env, or Option B if you chose the bare-IP block.

warning

Nginx reads /etc/nginx/nginx.conf. The files in the repository's nginx/ folder are templates: editing them has no effect until they are copied to /etc/nginx/nginx.conf and Nginx is reloaded.

Install Nginx​

sudo apt update
sudo apt install -y nginx
sudo systemctl status nginx

Option A: Domain with HTTPS​

Step 1: Create the DNS Records​

In the DNS provider that manages the customer's domain (Cloudflare, GoDaddy, Route53, etc.), create two A records:

TypeNameValue
Aonprem.customer-domain.comSERVER_IP
Adefault.customer-org-name.customer-domain.comSERVER_IP

The second name must match DOMAIN_URL in .env.

Step 2: Verify DNS Resolution​

dig +short onprem.customer-domain.com @1.1.1.1
dig +short default.customer-org-name.customer-domain.com @1.1.1.1

Both must return the server's IP before you request certificates.

Step 3: Open the Firewall​

sudo ufw allow 22
sudo ufw allow 80
sudo ufw allow 443
sudo ufw enable
sudo ufw status
warning

Allow port 22 before enabling the firewall, or you will lock yourself out of SSH. Port 80 must be open for Certbot's domain validation.

Step 4: Obtain SSL Certificates​

sudo apt install -y certbot python3-certbot-nginx
sudo certbot certonly --nginx -d onprem.customer-domain.com
sudo certbot certonly --nginx -d default.customer-org-name.customer-domain.com

A wildcard certificate for *.customer-domain.com does not cover the tenant name, because it is two labels deep - it needs its own certificate.

Step 5: Install the Nginx Configuration​

The template uses the placeholders example.com and <org>. Copy it into place with the customer's domain and organization name substituted - this also updates the CORS origins at the top of the file:

sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
sed -e 's/<org>/customer-org-name/g' -e 's/example\.com/customer-domain.com/g' nginx/nginx.conf | sudo tee /etc/nginx/nginx.conf > /dev/null
sudo rm -f /etc/nginx/sites-enabled/default
note

The domain configuration refuses requests made to the bare IP address (return 444). Browse to the domain name.

Step 6: Test and Reload Nginx​

sudo nginx -t && sudo systemctl reload nginx

Open https://onprem.customer-domain.com - the sign-in page should load.

Option B: Bare IP over HTTP​

Use this when the server is reached by IP address only, for example on a private network over VPN. No DNS records or certificates are needed.

Step 1: Open the Firewall​

sudo ufw allow 22
sudo ufw allow 80
sudo ufw enable

Step 2: Install the Nginx Configuration​

nginx-ip.conf works for any IP address without editing - it allows any http://<ipv4> origin.

sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
sudo cp nginx/nginx-ip.conf /etc/nginx/nginx.conf
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t && sudo systemctl reload nginx
note

Ubuntu's Nginx package enables a default site that also listens on port 80 as the default server. The AuthNull configuration defines its own, and Nginx allows only one per port, so nginx -t fails with a "duplicate default server" error until that site is removed. sites-enabled/default is a link; the original stays in /etc/nginx/sites-available/.

Step 3: Verify​

  1. Open http://SERVER_IP/org/signup. The organization sign-up page should load - this confirms Nginx is serving the Admin UI.
  2. Create the organization there, as described in Organization and Tenant Setup. The tenant only exists after this step.
  3. Open http://SERVER_IP/tenant/login. You are redirected to the sign-in page, and its address should contain domainUrl=default.customer-org-name.SERVER_IP - the tenant from DOMAIN_URL, not the bare IP address.
note

nginx-ip.conf includes a temporary patch (the location ~ ^/static/js/main... block) that makes the Admin UI send DOMAIN_URL instead of the browser's IP. Without it, the sign-in link carries domainUrl=SERVER_IP and the backend cannot find the organization. Leave it in place; it becomes a no-op once the Admin UI image includes the fix.

Restrict the Published Ports​

The compose file publishes every container port on all of the server's interfaces, including PostgreSQL (5432), Redis (6379), Cassandra (9042), and the internal services (2882, 6066, 9255, 9291). Docker writes its own firewall rules ahead of ufw, so these ports stay reachable from the network even with the firewall above enabled.

Nginx reaches the containers through 127.0.0.1, so with Nginx in front, bind each mapping in docker-compose.yml to the loopback address - for example change "5432:5432" to "127.0.0.1:5432:5432" - then apply it:

docker compose up -d

Only ports 80 and 443 then remain public. Leave 2882 reachable from any gateway host that calls authn-service directly, such as a ProxySQL server installed on another machine.

Next Steps​

Continue to Organization and Tenant Setup to register your organization.