Back to Blog
Tutorial10 min read2026-08-13

Deploying Angular with a Custom Domain and Automatic SSL

Deploy an Angular SPA to a CDN, point your domain with a CNAME, and get automatic Let's Encrypt SSL — DNS setup, certificate provisioning, and HTTPS enforcement.

Ajay Kumar
Ajay Kumar
Founder & DevOps, PandaStack

Angular apps built with the CLI compile to static HTML, CSS, and JavaScript that can be served from a CDN with no Node process running. The default deployment gives you a subdomain like angular-app-abc123.pandastack.app, which works for testing but looks unprofessional in production. Real apps need a custom domain, and HTTPS is mandatory for any site handling user input or authentication.

PandaStack automates the entire process: add your domain in the project settings, point a CNAME record at the target, wait for DNS to propagate, and the platform provisions a Let's Encrypt certificate automatically. The certificate renews before expiration, so there is no manual work after the initial setup. The only thing that can break this is misconfigured DNS, which is easy to debug.

Build the Angular app for production

Angular's dev server (ng serve) is for local development and cannot be deployed. The production build is ng build, which outputs static files to dist/your-app-name/browser/ by default.

Run the build locally to confirm the output directory:

ng build --configuration production
ls dist/angular-app/browser

You should see index.html, main.*.js, styles.*.css, and other hashed assets. This is what gets deployed to the CDN.

The build output directory changed in Angular 17+. Older versions output to dist/your-app-name/; newer versions output to dist/your-app-name/browser/. Check angular.json under projects.your-app-name.architect.build.options.outputPath to confirm the exact path.

Deploy the Angular app as a static site

Create the project via the API or dashboard. If using the API:

curl -X POST https://api.pandastack.io/v1/projects \
  -H "Authorization: Bearer $PANDASTACK_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "slug": "static",
    "name": "angular-app",
    "repositoryName": "yourname/angular-app",
    "branch": "main",
    "autoDeploy": true,
    "buildCommand": "npm run build -- --configuration production",
    "outputDir": "dist/angular-app/browser"
  }'

The platform clones the repo, runs npm install, builds the app, and uploads the static files to CDN storage. The site is live at https://angular-app-abc123.pandastack.app.

If the build fails with "Could not find a production build," the outputDir is wrong. Check angular.json and update the outputDir parameter to match.

Add a custom domain in the project settings

In the dashboard, navigate to your project → Settings → Domains. Click Add Domain and enter your domain or subdomain:

  • app.example.com (subdomain)
  • example.com (apex domain)

The platform generates a CNAME target like cname.pandastack.app and displays it in the UI. Do not click Save yet — you need to configure DNS first.

Point a CNAME record at the PandaStack target

Log in to your DNS provider (Cloudflare, Namecheap, Route 53, etc.) and add a CNAME record:

  • Type: CNAME
  • Name: app (for app.example.com) or @ (for apex domain)
  • Target: cname.pandastack.app (the value from the dashboard)
  • TTL: 300 (5 minutes for faster propagation during setup)

If you are using an apex domain (example.com with no subdomain), your DNS provider must support CNAME flattening or ALIAS records. Cloudflare, DNSimple, and most modern providers do. Legacy providers that require an A record for the apex will not work because the underlying CDN IP addresses can change.

For Cloudflare users: disable the orange cloud (set DNS-only mode) during initial setup. Once the certificate provisions, you can re-enable it if you want Cloudflare's WAF and caching on top of PandaStack's CDN.

Wait for DNS propagation and certificate provisioning

After adding the CNAME record, wait 5–30 minutes for DNS to propagate. Check propagation with:

dig app.example.com

or use an online tool like [WhatsMyDNS](https://www.whatsmydns.net/). The CNAME should resolve to cname.pandastack.app.

Once DNS resolves, the platform detects the domain, provisions a Let's Encrypt certificate via ACME HTTP-01 challenge, and installs it. The site becomes accessible at https://app.example.com.

If the certificate does not provision after 30 minutes:

  1. 1Verify the CNAME resolves correctly
  2. 2Check that no firewall or proxy is blocking the ACME challenge on port 80
  3. 3If using Cloudflare, ensure the orange cloud is off (DNS-only mode)

Enforce HTTPS by redirecting HTTP requests

The platform serves both HTTP and HTTPS by default. Most apps should redirect HTTP → HTTPS to enforce encryption. This is configured automatically for custom domains: requests to http://app.example.com redirect to https://app.example.com.

The auto-generated subdomain (angular-app-abc123.pandastack.app) also enforces HTTPS, so all traffic is encrypted regardless of which domain the user visits.

Handle Angular routing with client-side fallback

Angular SPAs use client-side routing: when the user navigates from /home to /about, the router updates the URL without a server request. This works perfectly when the user starts at the root URL and clicks through the app, but breaks when they bookmark /about and visit it directly.

The server receives a request for /about, looks for a file named about, finds nothing, and returns a 404. The Angular router never gets a chance to run because the HTML never loads.

PandaStack's static hosting solves this automatically: any request that does not match a file serves index.html, which boots the Angular app. The router reads the URL, matches it to a route, and renders the correct component. This is the standard SPA fallback behavior and requires no configuration.

Update DNS TTL after the domain is live

During setup, you set the CNAME TTL to 300 seconds (5 minutes) for fast iteration. Once the domain is live and the certificate is provisioned, increase the TTL to 3600 (1 hour) or 86400 (1 day). This reduces DNS query volume and improves performance.

Add multiple domains to the same app

If you want both www.example.com and example.com to serve the app, add both as custom domains and point both to the CNAME target:

  • www.example.com → CNAME cname.pandastack.app
  • example.com → ALIAS or CNAME (if supported) → cname.pandastack.app

The platform provisions separate certificates for each domain. You can designate one as the primary domain and redirect the other to it, or serve the app from both.

Redeploy when Angular routes or build config changes

Adding or renaming routes does not require DNS changes or certificate updates. The build output changes, but the domain and SSL setup remain the same. Push the commit, and the platform redeploys the new version.

If you change the build output directory in angular.json, update the outputDir parameter in your project settings to match. Otherwise, the platform uploads the wrong directory and the site breaks.

Monitor certificate expiration and renewal

Let's Encrypt certificates are valid for 90 days. The platform automatically renews them 30 days before expiration, so there is no manual intervention required. If renewal fails (usually due to DNS misconfiguration or the CNAME being removed), you will receive an email notification.

Check certificate status:

openssl s_client -connect app.example.com:443 -servername app.example.com < /dev/null 2>/dev/null | openssl x509 -noout -dates

You should see a notAfter date at least 60 days in the future. If the certificate expires soon and has not renewed, check the domain configuration and DNS records.

References

  • [Angular deployment documentation](https://angular.dev/tools/cli/deployment)
  • [Let's Encrypt documentation](https://letsencrypt.org/docs/)
  • [PandaStack custom domains guide](https://docs.pandastack.io/projects/)

Ready to deploy?

Start free on PandaStack.

Start free on PandaStack

More in Tutorial

Browse all Tutorial articles →

See also