Configure a public domain and TLS for Nora
Step-by-step guide to exposing Nora on a public domain with HTTP or Let’s Encrypt TLS, including nginx config, CORS, and NextAuth URL setup.By default, Nora listens on
localhost:8080 and is only reachable from the machine it runs on. To make your deployment accessible over the internet — whether for a staging environment, a production rollout, or a PaaS offering — you need to update several environment variables, create an nginx configuration file for your domain, and optionally provision a TLS certificate. This page walks through each step.
Deployment mode comparison
Set up public-domain access with HTTP
1
Update your .env file
Open your
.env file and change the access and URL variables to match your public domain. Replace app.example.com with your actual domain.CORS_ORIGINS accepts a comma-separated list. If your domain is reachable on multiple origins (for example, with and without www), include all of them:2
Create the nginx configuration file
Copy the public-domain nginx template from the Open This file is volume-mounted into the nginx container at startup using the
infra/ directory to produce nginx.public.conf in your project root:nginx.public.conf and replace the placeholder server name with your domain:NGINX_CONFIG_FILE value you set above.3
Start the stack
Pre-validate the generated file, bring the stack up, and recreate nginx so its single-file
bind mount is guaranteed to use the current file inode:Nora is now accessible at
http://app.example.com (port 80 must be open on your host firewall and the DNS A record must point to your server’s public IP).Add TLS with Let’s Encrypt
1
Ensure DNS is resolving
Before running the TLS setup script, confirm your domain’s DNS A record points to your server’s public IP address. Let’s Encrypt performs a domain ownership check that requires the domain to resolve correctly.
2
Run the TLS setup script
The Replace
infra/setup-tls.sh script requests a Let’s Encrypt certificate and writes a TLS-ready nginx.public.conf. Nora’s tracked TLS compose layer is infra/docker-compose.public-tls.yml; the setup script also writes a local docker-compose.override.yml convenience file so plain docker compose up uses the same TLS/prod settings.app.example.com with your domain and admin@example.com with an address that should receive Let’s Encrypt expiry notices.The script produces:- An updated
nginx.public.confwithssl_certificateandssl_certificate_keydirectives - A local
docker-compose.override.ymlconvenience file generated frominfra/docker-compose.public-tls.yml
3
Update .env for HTTPS
Update
NEXTAUTH_URL and CORS_ORIGINS to use https://:4
Activate the TLS config
The helper stops the old nginx process before writing the TLS config. Pre-validate the new
file, start the stack, and recreate nginx so the generated file is mounted from its current
inode. For a standard single-file Compose run, Docker Compose auto-loads the generated
If you are using explicit Compose overlays, include the tracked TLS layer directly:Nora is now available at
docker-compose.override.yml:https://app.example.com with a valid Let’s Encrypt certificate.Certificate renewal
Let’s Encrypt certificates expire after 90 days.infra/setup-tls.sh installs a daily 3 AM cron
entry that runs Certbot renewal, validates the live nginx configuration, and then sends nginx a
graceful reload signal so renewed certificate files take effect without replacing the edge
container.

