Skip to main content

Custom Domain

Deploy Menace Voice with custom domain names and SSL certificates
5 min read

Deploy Menace Voice with your own custom domain name for a professional production setup. By now, you should be able to create and test a voice agent by following the previous guide to setup the platform on a remote server using Docker

Tip

You don't need to own a domain just to remove the browser warning. If your server has a public IP, the remote setup already issues a free, auto-renewing Let's Encrypt certificate via sslip.io (e.g. https://203-0-113-10.sslip.io) — no DNS configuration required. Follow this Custom Domain guide only when you want your own domain name (e.g. voice.yourcompany.com).

What is Custom Domain Deployment?#

Custom domain deployment allows you to run Menace Voice with a personalized domain name (like voice.yourcompany.com) instead of using IP addresses. This setup includes:

  • Custom Domain: Access your application via a memorable domain name
  • Automatic SSL: Proper SSL certificates from Let's Encrypt or similar providers
  • Professional Setup: Production-ready configuration for business use
  • Easy Sharing: Share a clean URL with your team and customers

Prerequisites#

Before starting, ensure you have:

  • A domain name you own (e.g., yourcompany.com)
  • Access to your domain's DNS settings (usually through your domain registrar)
  • Menace Voice already running on your server via the remote deployment guide
  • Your server's public IP address

Step 1: Configure DNS Records#

You need to create a DNS record that points your domain to your server's IP address.

Add an A Record#

Log in to your domain registrar or DNS provider and add an A record:

SettingValue
TypeA
Name/Hostvoice (or @ for root domain)
Value/Points toYour server's IP address (e.g., 203.0.113.50)
TTL300 (or default)
Note

DNS changes can take anywhere from a few minutes to 48 hours to propagate, though most changes take effect within 5-30 minutes. You can check if your DNS has propagated using tools like dnschecker.org.

Verify DNS Propagation#

Before proceeding, verify that your domain points to your server:

You should see your server's IP address in the response.

Once your DNS is configured, run the automated setup script that handles the rest.

Note

You must be at the same place where you had run setup_remote.sh from. The directory should contain dograh/ with the artifacts that got created when setup_remote.sh was run.

Note

You must not move the dograh/ directory to a different location after running setup_custom_domain.sh, since we set up auto certificate renewal script as certbot renewal hook pointing to the dograh/ directory.

The script will prompt you for:

  • Your domain name
  • An email address for Let's Encrypt notifications

It will automatically:

  • Verify DNS configuration
  • Install Certbot
  • Generate Let's Encrypt SSL certificates
  • Update the canonical public host/base URL settings in .env
  • Validate the runtime config that dograh-init will render from .env
  • Configure automatic certificate renewal
  • Restart Menace Voice services through the validated startup wrapper

Once complete, your application will be available at https://voice.yourcompany.com.

Note

If you prefer to set things up manually, continue with the steps below.


Manual Setup#

If you prefer to configure everything manually, follow these steps instead of using the automated script.

Install Certbot#

Certbot is the official Let's Encrypt client that automates SSL certificate generation.

Ubuntu/Debian:

Amazon Linux/RHEL:

Point .env at your domain#

Update .env so the canonical remote settings use your domain — dograh-init reads these to render nginx's server_name. Replace voice.yourcompany.com with your actual domain throughout:

Start services so nginx can answer the ACME challenge#

Bring the stack up (or recreate it) through the validated wrapper. nginx serves the Let's Encrypt HTTP-01 challenge from certs/.well-known/acme-challenge/ on port 80, so the stack must be running during issuance — there's no need to stop it:

Generate the SSL certificate (webroot)#

Issue the certificate using the webroot challenge served by the running nginx:

Certbot will:

  1. Write a challenge file under certs/.well-known/acme-challenge/
  2. Have Let's Encrypt fetch it over HTTP (port 80) to verify you control the domain
  3. Store the certificate in /etc/letsencrypt/live/voice.yourcompany.com/
Note

You'll be prompted for an email address (for renewal notices) and to agree to the terms of service. Because nginx keeps serving traffic throughout, issuance and renewal happen with no downtime — unlike the older --standalone flow, which had to stop the stack to free port 80.

Copy the certificate and load it#

Copy the issued certificate into the certs/ directory nginx reads, then restart nginx to load it:

Access Your Application#

Your application is now available at:

You should see a valid SSL certificate (green padlock) in your browser.

Set Up Certificate Renewal#

Let's Encrypt certificates expire after 90 days. Set up automatic renewal.

Create a renewal hook script that copies the new certificates:

Add the following content (replace paths as needed):

Make the script executable:

Test that renewal works:

Troubleshooting#

Certificate Generation Fails#

If Certbot fails to generate certificates:

  1. Port 80 blocked: Ensure port 80 is open in your firewall and reachable from the internet. With the webroot flow nginx must be running and serving the challenge on port 80 (don't stop the stack)
  2. DNS not propagated: Wait for DNS changes to propagate and verify with nslookup
  3. Rate limits: Let's Encrypt has rate limits. If you've exceeded them, wait before retrying

SSL Certificate Errors in Browser#

If you see SSL errors after setup:

  1. Verify the certificates were copied correctly: ls -la dograh/certs/
  2. Run ./remote_up.sh --preflight-only in dograh/ to verify the dograh-init runtime render matches .env
  3. Restart the nginx container: sudo docker compose --profile remote restart nginx

WebRTC Connection Issues#

If voice calls don't connect after domain setup:

  1. Ensure TCP/UDP ports 3478, 5349, and UDP 49152-49200 are still open
  2. Check that PUBLIC_HOST / PUBLIC_BASE_URL in .env match your domain, then re-run ./remote_up.sh