Docs

Discover how Phala's AI Agent Contract offers the essential tools to develop and profit from intelligent applications.

Explore Now

Zero Trust HTTPS: How to Setup Custom Domains on Phala Cloud

2025-04-21

Overview

Running a CVM on Phala Cloud gives you hardware‑enforced confidentiality out of the box, but the default service URL (<app‑id>.prod5-dstack.phala.network) isn’t exactly brandable. Luckily, Phala’s dstack‑ingress setup lets you attach your own domain, provision a trusted TLS certificate through Let’s Encrypt, and even produce cryptographic evidence that the certificate lives inside a TEE — all in just a few minutes.

Below we’ll cover prerequisites, show a production‑ready docker‑compose.yml, walk through deploying on Phala Cloud, and explain the attestation files that prove your endpoint is running inside a genuine TEE.


1. How dstack‑ingress works

  1. DNS automation – A tiny side‑car container talks to Cloudflare’s API, creating the CNAME, TXT (routing hint), and CAA records needed for DNS‑01 validation.
  1. Let’s Encrypt via DNS‑01 – With those records in place, Certbot requests a certificate without ever exposing ports 80/443 on the raw CVM
  1. Nginx reverse proxy – The same container terminates TLS and forwards plain HTTP to your app on TARGET_ENDPOINT.
  1. Evidence generation – Each time a cert is issued or renewed the container writes cert.pem, acme‑account.json, a sha256sum.txt, and an Intel TDX quote (quote.json) that ties the SHA‑256 digest into the quote’s report_data field.
  1. Certificate Transparency – All issued certs are logged in public CT logs, so anyone can audit issuance via tools like crt.sh.

2. Prerequisites

WhatWhy
A registered domain managed by Cloudflaredstack‑ingress currently automates only Cloudflare DNS
Cloudflare API Token with Edit zone DNS scopeAllows the container to add CNAME/TXT/CAA records safely, limiting blast radius compared to the legacy Global API Key
Phala Cloud account with creditsTo launch the CVM
Email for Let’s EncryptUsed by Certbot for renewal notices

3. Create the Cloudflare API token

  1. Cloudflare Dashboard → My Profile → API Tokens → Create Token.
  1. Pick the “Edit zone DNS” template, restrict it to just your zone, and finish.
  1. Copy the token and save it as CLOUDFLARE_API_TOKEN.

4. Deploy on Phala Cloud

services:
  dstack-ingress:
    image: kvin/dstack-ingress@sha256:8dfc3536d1bd0be0cb938140aeff77532d35514ae580d8bec87d3d5a26a21470  # pre‑built
    ports:
      - "443:443"
    environment:
      - CLOUDFLARE_API_TOKEN=${CLOUDFLARE_API_TOKEN}
      - DOMAIN=${DOMAIN}                       # e.g. api.example.com
      - GATEWAY_DOMAIN=_.dstack-prod5.phala.network
      - CERTBOT_EMAIL=${CERTBOT_EMAIL}
      - TARGET_ENDPOINT=http://app:80
      - SET_CAA=true
    volumes:
      - cert-data:/etc/letsencrypt
      - /var/run/tappd.sock:/var/run/tappd.sock
    restart: unless-stopped

  app:
    image: nginx   # swap in your own image
    restart: unless-stopped

volumes:
  cert-data:

Phala’s Advanced tab accepts this verbatim when you choose docker‑compose.yml during CVM creation.

  1. New CVM → Compose file → Advanced, paste the YAML above, and select a prodX region.
  1. Fill in the environment variables (DOMAIN, CLOUDFLARE_API_TOKEN, etc.). Note that the GATEWAY_DOMAIN should in the format of _.prodX-dstack.phala.network based on which region you have chosen in the previous step.
  1. Click Create and watch the dstack-ingress Docker logs: within ~2 minutes Certbot shows Congratulations! Your certificate and chain have been saved.

🎉 Congratulations! Now you have your customized domain deployed. Here is an example of a custom domain deployed to “phala.incipient.ltd”.

Behind the scenes, dstack‑ingress:

  • Adds a CNAME from api.example.com.dstack-prod5.phala.network so traffic routes through Phala’s secure gateway
  • Publishes a TXT record that the gateway reads to identify your CVM instance.
  • Publishes CAA records limiting issuance to letsencrypt.org, reducing the risk of rogue CAs.
  • Routes the traffic from your customized domain to the deployed TEE instance.

5. Verifying attestation evidence

Visit https://your-custom-domain.com/evidences/ and download:

FilePurpose
cert.pemCurrent leaf certificate
acme-account.jsonACME account key used to request cert
sha256sum.txtHashes of cert.pem & acme-account.json
quote.jsonIntel TDX quote embedding SHA‑256 of sha256sum.txt in report_data

Because the quote is signed by Intel’s TDX Attestation Key and bound to the hash chain above, anyone can cryptographically prove the certificate was generated inside this very enclave. You can check the example of the deployment at phala.incipient.ltd/evidences/.


6. Inspect CAA & CT logs (optional)

CAA is a DNS record that prevents anyone else except the TEE itself to issue TLS certificate to your customized domain. It ensures that the TLS connection to the domain always terminates inside the TEE. So nobody can fake a TEE.

dig +short CAA api.example.com   # should list only letsencrypt.org

If you see an entry like 0 issue "letsencrypt.org", you’re good.

To monitor certificate issuance, plug your domain into crt.sh or any CT monitor. Every renewal will show up within minutes, giving you an extra audit trail.


7. Automatic renewals & housekeeping

  • Certbot runs twice daily and reloads Nginx when certs hit the 30‑day renewal window.
  • Because everything is stored in the cert-data volume, redeploying or resizing the CVM preserves certificates and evidence.
  • If you ever migrate to a different prod region, just update GATEWAY_DOMAIN, redeploy, and the script will re‑issue the cert for the new CNAME.

8. Troubleshooting tips

Error in dstack-ingress Docker logsLikely cause
SERVFAIL on _acme‑challenge TXT lookupToken lacks Edit zone DNS or record hasn’t propagated yet (Cloudflare global TTL ≈ 60 s)
Certbot errors about “unauthorized”CAA forbids Let’s Encrypt or TXT record not visible from Let’s Encrypt resolver
Custom domain loads but shows Cloudflare SSL, not Let’s EncryptCloudflare “Flexible” SSL overrides upstream ‑ switch to **Full (strict)**

9. Where to go next

  • Phala Cloud CLI – script the entire flow with phala cvms create --compose docker-compose.yml --env ....

Your application now runs behind a vanity URL, serves modern HTTPS, and ships its own enclave‑backed audit trail—perfect for security‑minded customers and enterprise procurement checklists alike.

About Phala

Phala Network is a decentralized cloud that offers secure and scalable computing for Web3.

With Phat Contracts, an innovative programming model enabling trustless off-chain computation, developers can create new Web3 use cases.

Get the latest Phala Content Straight To Your Inbox.