Phala Network Docs
  • Home
    • 👾Phala Network Docs
  • Overview
    • ⚖️Phala Network
      • 💎Phala Cloud
      • 🥷Dstack
      • 🔐GPU TEE
    • 💎PHA Token
      • 🪙Introduction
      • 👐Delegation
        • Delegate to StakePool
        • What is Vault
        • What is Share
        • WrappedBalances & W-PHA
        • Examples of Delegation
        • Use Phala App to Delegate
        • Estimate Your Reward
      • 🗳️Governance
        • Governance Mechanism
        • Join the Council
        • Voting for Councillors
        • Apply for Project Funding
        • Phala Treasury
        • Phala Governance
        • Setting Up an Account Identity
  • Phala Cloud
    • 🚀Getting Started
      • Sign-up for Cloud Account
      • Start from Cloud UI
      • Start from Cloud CLI
      • Start from Template
    • 🟧Launch an Eliza Agent
    • 📦Create CVM
      • Create CVM with Docker Compose
      • Create CVM with Private Docker Image
      • Set Secure Environment Variables
      • Access Your Applications
      • Setting Up Custom Domain
      • Debug Your Application
      • Deployment Cheat Sheet
    • ⚙️CVM Management
      • Upgrade Application
      • Resize Resources
      • Check Logs
      • Private Log Viewer
    • 🔄Deploy Docker App in TEE
      • Expose Service Port
      • Generate RA Report
      • Access Database
      • Create Crypto Wallet
    • 🛳️Setup a CI/CD Pipeline
    • 🛠️Phala Cloud CLI Reference
      • phala
        • auth
        • cvms
        • docker
        • simulator
    • Production Checklist
    • ❓FAQs
    • 🔍Troubleshooting
    • 📖Glossary
    • 📋References
    • 🔒Use Cases
      • TEE with AI
      • TEE with FHE and MPC
      • TEE with ZK and ZKrollup
  • Dstack
    • Overview
    • Getting Started
    • Hardware Requirements
    • Design Documents
      • Decentralized Root-of-Trust
      • Key Management Protocol
      • Zero Trust HTTPs (TLS)
    • Acknowledgement
  • LLM in GPU TEE
    • 👩‍💻Host LLM in GPU TEE
    • 🔐GPU TEE Inference API
    • 🏎️GPU TEE Benchmark
  • Tech Specs
    • ⛓️Blockchain
      • Blockchain Entities
      • Cluster of Workers
      • Secret Key Hierarchy
  • References
    • 🔐Setting Up a Wallet on Phala
      • Acquiring PHA
    • 🌉SubBridge
      • Cross-chain Transfer
      • Supported Assets
      • Asset Integration Guide
      • Technical Details
    • 👷Community Builders
    • 🤹Hackathon Guides
      • ETHGlobal Singapore
      • ETHGlobal San Francisco
      • ETHGlobal Bangkok
    • 🤯Advanced Topics
      • Cross Chain Solutions
      • System Contract and Drivers
      • Run Local Testnet
      • SideVM
    • 🆘Support
      • Available Phala Chains
      • Resource Limits
      • Transaction Costs
      • Compatibility Matrix
      • Block Explorers
      • Faucet
    • ⁉️FAQ
  • Compute Providers
    • 🙃Basic Info
      • Introduction
      • Gemini Tokenomics (Worker Rewards)
      • Budget balancer
      • Staking Mechanism
      • Requirements in Phala
      • Confidence Level & SGX Function
      • Rent Hardware
      • Error Summary
    • 🦿Run Workers on Phala
      • Solo Worker Deployment
      • PRBv3 Deployment
      • Using PRBv3 UI
      • PRB Worker Deployment
      • Switch Workers from Solo to PRB Mode
      • Headers-cache deployment
      • Archive node deployment
    • 🛡️Gatekeeper
      • Collator
      • Gatekeeper
  • Web Directory
    • Discord
    • GitHub
    • Twitter
    • YouTube
    • Forum
    • Medium
    • Telegram
  • Legacy
    • Information
    • ⚒️Phala SDK
    • 👨‍🚀Builders Program
    • 🥷AI Agent Contract
      • WapoJS Functions
      • Phala Agent Gateway
  • AI Agent Contract (Legacy)
    • 👩‍💻Getting Started
      • Build Your First AI Agent Contract
      • Build An Agent to Transact Onchain
      • Build Your AI Agent Contract with OpenAI
      • Build Your AI Agent Contract with LangChain
      • Integrate with 3rd Party API with HTTP Request
      • Run a Local Testnet With Docker
      • AI Agent Contract Templates
    • 🧙‍♂️Examples
      • Create a Weather Agent w/ Function Calling
    • ⛓️Supported Chains
    • FAQ
  • Agent Wars (Legacy)
    • 📜Introduction
    • 💸Tokenomics
    • ▶️Getting Started
      • Wallet Setup & Get PHA
      • Buy and Sell Keys
    • 🧑‍🏫Tutorial
Powered by GitBook
LogoLogo

Participate

  • Compute Providers
  • Node
  • Community
  • About Us

Resources

  • Technical Whitepaper
  • Token Economics
  • Docs
  • GitHub

More

  • Testnet
  • Explorer
  • Careers
  • Responsible Disclosure

COPYRIGHT © 2024 PHALA.LTD ALL RIGHTS RESERVED. May Phala be with you!

On this page
  • Prerequisites
  • Create Cloudflare API Token
  • Deployment
  • Knowledge
  • Domain Attestation and Verification
  • CAA Record Verification
  • TLS Certificate Transparency

Was this helpful?

Edit on GitHub
  1. Phala Cloud
  2. Create CVM

Setting Up Custom Domain

For users that want to bring their own domain for their CVM.

PreviousAccess Your ApplicationsNextDebug Your Application

Last updated 13 days ago

Was this helpful?

If you prefer video content, check the YouTube tutorial here.

Prerequisites

  • Have access to the Cloudflare account with API token

Create Cloudflare API Token

If you have not generated an API Token for your custom domain management then follow these steps:

Create API Token

In your dashboard, select the domain you'd like to use and find the option to Get Your API Token

Select the Create Token button as shown below

The next page will have several templates. Select the template to Edit zone DNS as shown below

Next select your domain in the Zone Resources section then click Continue to summary button as shown below

Congrats! You've now created your API Token to use for your environment variable.

Deployment

For this deployment example, we will be an nginx application where the dstack-ingress container that will forward traffic the TARGET_ENDPOINT that points to the nginx application with an exposed port 80 . It is important to know that this can change based on how your docker app's compose file is configured.

Why TARGET_ENDPOINT Matters
  • Tells the proxy where to send traffic When a request arrives at https://your-custom-domain, dstack-ingress decrypts TLS and then forwards the HTTP payload to exactly the URL in TARGET_ENDPOINT.

    https://pastebin.example.com  →  dstack-ingress  →  http://app:80
  • Decouples host networking from container internals Your app can stay on port 80 (or 3000, or the exposed port of your app), and you never have to re-map messy host ports. The ingress simply forwards traffic to “app:80” over the Docker bridge network.

  • Enables dynamic, multi-service gateways If you later add more services behind the same ingress (e.g. api-service:4000), you only need to change their corresponding TARGET_ENDPOINT or add routing rules—no firewall or host-port juggling required.

In the following example, we will show a more complex configuration for an ElizaOS Deployment where the docker app has a Postgresql + pgvector container that serves as a DB for the ElizaOS eliza container. The SERVER_PORT is expected to be port 3000 in this example where the dstack-ingress will forward traffic through the DOMAIN environment variable.

version: '3.8'
services:
  postgres:
    image: ankane/pgvector:latest
    environment:
        - POSTGRES_PASSWORD=postgres
        - POSTGRES_USER=postgres
        - POSTGRES_DB=eliza
        - PGDATA=/var/lib/postgresql/data/pgdata
    volumes:
        - postgres-data:/var/lib/postgresql/data
    ports:
        - "127.0.0.1:5432:5432"
    healthcheck:
        test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
        interval: 5s
        timeout: 5s
        retries: 5
    restart: always
    networks:
      - eliza-network

  eliza:
    image: hashwarlock/elizaos:beta0
    command: sh -c "bun run start"
    volumes:
      - /var/run/tappd.sock:/var/run/tappd.sock
    environment:
      - OPENAI_API_KEY=${OPENAI_API_KEY}
      - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
      - SERVER_PORT=${SERVER_PORT}
      - POSTGRES_URL=postgres://postgres:postgres@postgres:5432/eliza
    depends_on:
      postgres:
        condition: service_healthy
    restart: always
    networks:
      - eliza-network

  dstack-ingress:
    image: kvin/dstack-ingress@sha256:2cc3bc50d71faa4d313084237b0f5d1d25963024f2484c7a6414aed075883cdd
    ports:
      - "443:443"
    environment:
      - DOMAIN=${DOMAIN}
      - GATEWAY_DOMAIN=${GATEWAY_DOMAIN}
      - CERTBOT_EMAIL=${CERTBOT_EMAIL}
      - CLOUDFLARE_API_TOKEN=${CLOUDFLARE_API_TOKEN}
      - SET_CAA=true
      - TARGET_ENDPOINT=http://eliza:3000
    volumes:
      - /var/run/tappd.sock:/var/run/tappd.sock
      - cert-data:/etc/letsencrypt
    restart: unless-stopped
    networks:
      - eliza-network

networks:
  eliza-network:
    driver: bridge

volumes:
  postgres-data:
  cert-data:

Now on to the deployment. Go to you Phala Cloud Dashboard and deploy a new CVM. Select docker-compose.yml option for deployment then take the past the docker compose file below into the Advanced tab of the CVM configration page.

services:
  dstack-ingress:
    image: kvin/dstack-ingress@sha256:2cc3bc50d71faa4d313084237b0f5d1d25963024f2484c7a6414aed075883cdd
    ports:
      - "443:443"
    environment:
      - CLOUDFLARE_API_TOKEN=${CLOUDFLARE_API_TOKEN}
      - DOMAIN=${DOMAIN}
      - GATEWAY_DOMAIN=${GATEWAY_DOMAIN}
      - CERTBOT_EMAIL=${CERTBOT_EMAIL}
      - SET_CAA=true
      - TARGET_ENDPOINT=http://app:80
    volumes:
      - /var/run/tappd.sock:/var/run/tappd.sock
      - cert-data:/etc/letsencrypt
    restart: unless-stopped
  app:
    image: nginx  # Replace with your application image
    restart: unless-stopped
volumes:
  cert-data:  # Persistent volume for certificates

Explanation of environment variables:

  • CLOUDFLARE_API_TOKEN: Your Cloudflare API token

  • DOMAIN: Your custom domain (i.e. your-domain.com )

  • GATEWAY_DOMAIN: The dstack gateway domain. (e.g. _.dstack-prod5.phala.network for Phala Cloud prod5 server)

  • CERTBOT_EMAIL: Your email address used for Let's Encrypt email notifications

  • TARGET_ENDPOINT: Where the ingress should forward all incoming traffic—i.e. the upstream service application:port. In this case, we point to the nginx app on port 80.

  • SET_CAA: Set to true to enable CAA record setup

Now copy and paste the docker-compose.yaml code above into the Advanced Tab similar to the screnshot below.

Next you need to grab your Cloudflare API Token for your domain, and fill in your environment variables. For this example, deploy to prod5 ( domain:dstack-prod5.phala.network).

Congratulations! You've successfully deployed your CVM with a custom domain. Your application is now secured with Zero Trust HTTPS, thanks to the seamless integration of Cloudflare DNS and Let's Encrypt. If you are interested in the verification of this process check the Domain Attestation and Verification.

Knowledge

Now you have the knowledge base on the custom domain deployment with a basic nginx dstack application. The features you have used to enable your custom domain are defined below:

  • Automatic SSL certificate provisioning and renewal via Let's Encrypt

  • Cloudflare DNS configuration for CNAME, TXT, and CAA records

  • Nginx reverse proxy to route traffic to your application

  • Certificate evidence generation for verification

Read The Full Explanation

The dstack-ingress system provides a seamless way to set up custom domains for dstack applications with automatic SSL certificate management. Here's how it works:

  1. Initial Setup:

    • When first deployed, the container automatically obtains SSL certificates from Let's Encrypt using DNS validation

    • It configures Cloudflare DNS by creating necessary CNAME, TXT, and optional CAA records

    • Nginx is configured to use the obtained certificates and proxy requests to your application

  2. DNS Configuration:

    • A CNAME record is created to point your custom domain to the dstack gateway domain

    • A TXT record is added with application identification information to help dstack-gateway to route traffic to your application

    • If enabled, CAA records are set to restrict which Certificate Authorities can issue certificates for your domain

  3. Certificate Management:

    • Select the Create Token button as shown below

    • SSL certificates are automatically obtained during initial setup

    • A scheduled task runs twice daily to check for certificate renewal

    • When certificates are renewed, Nginx is automatically reloaded to use the new certificates

  4. Evidence Generation:

    • The system generates evidence files for verification purposes

    • These include the ACME account information and certificate data

    • Evidence files are accessible through a dedicated endpoint

Domain Attestation and Verification

The dstack-ingress system provides mechanisms to verify and attest that your custom domain endpoint is secure and properly configured. This comprehensive verification approach ensures the integrity and authenticity of your application.

Evidence Collection

When certificates are issued or renewed, the system automatically generates a set of cryptographically linked evidence files:

  1. Access Evidence Files:

    • Evidence files are accessible at https://your-domain.com/evidences/

    • Key files include acme-account.json, cert.pem, sha256sum.txt, and quote.json

  2. Verification Chain:

    • quote.json contains a TDX quote with the SHA-256 digest of sha256sum.txt embedded in the report_data field

    • sha256sum.txt contains cryptographic checksums of both acme-account.json and cert.pem

    • When the TDX quote is verified, it cryptographically proves the integrity of the entire evidence chain

  3. Certificate Authentication:

    • acme-account.json contains the ACME account credentials used to request certificates

    • When combined with the CAA DNS record, this provides evidence that certificates can only be requested from within this specific TEE application

    • cert.pem is the Let's Encrypt certificate currently serving your custom domain

CAA Record Verification

If you've enabled CAA records (SET_CAA=true), you can verify that only authorized Certificate Authorities can issue certificates for your domain:

dig CAA your-domain.com

The output will display CAA records that restrict certificate issuance exclusively to Let's Encrypt with your specific account URI, providing an additional layer of security.

TLS Certificate Transparency

All Let's Encrypt certificates are logged in public Certificate Transparency (CT) logs, enabling independent verification:

CT Log Verification:

  • Confirm that the certificates match those issued by the dstack-ingress system

  • This public logging ensures that all certificates are visible and can be monitored for unauthorized issuance

Host your domain on

Go to your Cloudflare Dashboard

Create API Token

Select a Template

Finalize API Token Creation

For more details, checkout the for the dstack-ingress dstack examples.

Click Create button and your CVM will deploy in a couple minutes with the custom domain. Here is an example of a custom domain deployed to

You can check the example of the deployment at .

Visit and search for your domain

📦
1️⃣
2️⃣
3️⃣
4️⃣
Cloudflare
github repository
phala.incipient.ltd.
phala.incipient.ltd/evidences/
crt.sh