From d5d5214b818aef5b0d99de5eb3fd1dac7655af42 Mon Sep 17 00:00:00 2001 From: Adam Reif Date: Thu, 26 Mar 2026 13:28:32 -0500 Subject: [PATCH 01/17] feat: add dstack-ingress for custom domain TLS (CPL-152) Add dstack-ingress service to docker-compose.phala.yml for attestation- bound TLS termination inside the TEE. On main branch, deploys with DOMAIN=api.chipotle.litprotocol.com using Let's Encrypt DNS-01 via Route 53. On next branch, dstack-ingress is removed from the deploy compose file (no custom domain). - docker-compose.phala.yml: add dstack-ingress service behind "custom-domain" profile with Route 53 DNS provider config - deploy-phala.yml: add domain output, substitute TLS secrets in deploy step, conditionally strip profiles or remove service block Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/deploy-phala.yml | 23 ++++++++++++++++++++++- docker-compose.phala.yml | 29 +++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy-phala.yml b/.github/workflows/deploy-phala.yml index a547fe48..1b40336f 100644 --- a/.github/workflows/deploy-phala.yml +++ b/.github/workflows/deploy-phala.yml @@ -50,6 +50,7 @@ jobs: instance_type: ${{ steps.set.outputs.instance_type }} gcp_project_id: ${{ steps.set.outputs.gcp_project_id }} node_config: ${{ steps.set.outputs.node_config }} + domain: ${{ steps.set.outputs.domain }} steps: - name: Set deployment target id: set @@ -59,7 +60,8 @@ jobs: echo "instance_type=tdx.large" >> "$GITHUB_OUTPUT" echo "gcp_project_id=chipotle-dev" >> "$GITHUB_OUTPUT" echo "node_config=NodeConfig.main.toml" >> "$GITHUB_OUTPUT" - BASE_URL="https://f8fce543471dc9f5f5643aa217422398c36e5edc-8000.dstack-base-prod5.phala.network" + echo "domain=api.chipotle.litprotocol.com" >> "$GITHUB_OUTPUT" + BASE_URL="https://api.chipotle.litprotocol.com" elif [ "${{ github.ref }}" = "refs/heads/next" ]; then echo "phala_app_name=chipotle-next" >> "$GITHUB_OUTPUT" echo "instance_type=tdx.small" >> "$GITHUB_OUTPUT" @@ -150,13 +152,32 @@ jobs: DIGEST_LIT_API_SERVER=$(cat digest-lit-api-server.txt | tr -d '\n' | sed 's/}[}]*$//') DIGEST_LIT_STATIC=$(cat digest-lit-static.txt | tr -d '\n' | sed 's/}[}]*$//') DIGEST_OTEL_COLLECTOR=$(cat digest-otel-collector.txt | tr -d '\n' | sed 's/}[}]*$//') + DOMAIN="${{ needs.determine-target.outputs.domain }}" sed \ -e "s|\${DOCKER_IMAGE_LIT_ACTIONS}|${{ vars.DOCKER_IMAGE }}-lit-actions@${DIGEST_LIT_ACTIONS}|g" \ -e "s|\${DOCKER_IMAGE_LIT_API_SERVER}|${{ vars.DOCKER_IMAGE }}-lit-api-server@${DIGEST_LIT_API_SERVER}|g" \ -e "s|\${DOCKER_IMAGE_LIT_STATIC}|${{ vars.DOCKER_IMAGE }}-lit-static@${DIGEST_LIT_STATIC}|g" \ -e "s|\${DOCKER_IMAGE_OTEL_COLLECTOR}|${{ vars.DOCKER_IMAGE }}-otel-collector@${DIGEST_OTEL_COLLECTOR}|g" \ -e "s|\${GCP_PROJECT_ID}|${{ needs.determine-target.outputs.gcp_project_id }}|g" \ + -e "s|\${DOMAIN}|${DOMAIN}|g" \ + -e "s|\${CERTBOT_EMAIL}|${{ secrets.CERTBOT_EMAIL }}|g" \ + -e "s|\${AWS_ACCESS_KEY_ID}|${{ secrets.AWS_ACCESS_KEY_ID_ROUTE53 }}|g" \ + -e "s|\${AWS_SECRET_ACCESS_KEY}|${{ secrets.AWS_SECRET_ACCESS_KEY_ROUTE53 }}|g" \ docker-compose.phala.yml > docker-compose.deploy.yml + if [ -n "$DOMAIN" ]; then + # Strip profiles: line so dstack-ingress starts unconditionally + # (phala deploy doesn't support compose profiles) + sed -i '/profiles:/d' docker-compose.deploy.yml + else + # No custom domain — remove entire dstack-ingress service and cert-data volume + awk ' + /^ dstack-ingress:/ { skip=1; next } + skip && /^ [^ ]/ { skip=0 } + skip { next } + /^ cert-data:/ { next } + { print } + ' docker-compose.deploy.yml > docker-compose.deploy.tmp && mv docker-compose.deploy.tmp docker-compose.deploy.yml + fi cat docker-compose.deploy.yml - name: Setup Node.js diff --git a/docker-compose.phala.yml b/docker-compose.phala.yml index abad41b8..4105b7a6 100644 --- a/docker-compose.phala.yml +++ b/docker-compose.phala.yml @@ -14,6 +14,10 @@ # Required secrets (set as encrypted Phala CVM environment variables): # GCP_SERVICE_ACCOUNT_JSON - GCP service account key (raw JSON or base64-encoded) # GCP_PROJECT_ID - GCP project ID (e.g. "my-gcp-project") +# DOMAIN - Custom domain for TLS (e.g. "api.chipotle.litprotocol.com") +# CERTBOT_EMAIL - Email for Let's Encrypt certificate notifications +# AWS_ACCESS_KEY_ID - Route 53 IAM credentials for DNS-01 challenge +# AWS_SECRET_ACCESS_KEY - Route 53 IAM credentials for DNS-01 challenge # RUST_LOG filter shared by lit-actions and lit-api-server. # App code stays at trace; per-module overrides suppress low-value internals: @@ -104,5 +108,30 @@ services: ROCKET_PORT: "8001" restart: unless-stopped + # dstack-ingress — attestation-bound TLS termination inside the TEE. + # Obtains a Let's Encrypt cert for DOMAIN via DNS-01 (Route 53), then + # reverse-proxies HTTPS :443 → lit-api-server :8000. + dstack-ingress: + profiles: ["custom-domain"] + image: dstacktee/dstack-ingress:1.4@sha256:11c0481ca2e3566f514a1c8a2cc69af1e0bb9dab2e4ea49b469c81ec8e7c5c72 + ports: + - "443:443" + environment: + DOMAIN: "${DOMAIN}" + DNS_PROVIDER: "route53" + TARGET_ENDPOINT: "http://lit-api-server:8000" + CERTBOT_EMAIL: "${CERTBOT_EMAIL}" + SET_CAA: "true" + AWS_ACCESS_KEY_ID: "${AWS_ACCESS_KEY_ID}" + AWS_SECRET_ACCESS_KEY: "${AWS_SECRET_ACCESS_KEY}" + volumes: + - /var/run/dstack.sock:/var/run/dstack.sock + - cert-data:/etc/letsencrypt + depends_on: + lit-api-server: + condition: service_started + restart: unless-stopped + volumes: lit-socket: + cert-data: From b122c8013b1d9f5a6577ca4621913c514bd4cad2 Mon Sep 17 00:00:00 2001 From: Adam Reif Date: Thu, 26 Mar 2026 13:40:49 -0500 Subject: [PATCH 02/17] feat: use test.chipotle.litprotocol.com for next branch Reserve api.chipotle.litprotocol.com for main branch deployments. The next branch gets its own custom domain at test.chipotle.litprotocol.com. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/deploy-phala.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy-phala.yml b/.github/workflows/deploy-phala.yml index 1b40336f..24e41b96 100644 --- a/.github/workflows/deploy-phala.yml +++ b/.github/workflows/deploy-phala.yml @@ -67,7 +67,8 @@ jobs: echo "instance_type=tdx.small" >> "$GITHUB_OUTPUT" echo "gcp_project_id=chipotle-next" >> "$GITHUB_OUTPUT" echo "node_config=NodeConfig.next.toml" >> "$GITHUB_OUTPUT" - BASE_URL="https://969a8c14c9e13420705b19c7246aeed27897e7ea-8000.dstack-base-prod5.phala.network" + echo "domain=test.chipotle.litprotocol.com" >> "$GITHUB_OUTPUT" + BASE_URL="https://test.chipotle.litprotocol.com" else echo "Unsupported branch for deployment" exit 1 From bb54b0cb7d41dc83beb534dccbce0504a75934d7 Mon Sep 17 00:00:00 2001 From: Adam Reif Date: Thu, 26 Mar 2026 14:02:01 -0500 Subject: [PATCH 03/17] fix: rename Route 53 secret refs to AWS_*_CERTBOT The GitHub secrets for the certbot Route 53 IAM credentials are named AWS_ACCESS_KEY_ID_CERTBOT and AWS_SECRET_ACCESS_KEY_CERTBOT. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/deploy-phala.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-phala.yml b/.github/workflows/deploy-phala.yml index 24e41b96..96c1a097 100644 --- a/.github/workflows/deploy-phala.yml +++ b/.github/workflows/deploy-phala.yml @@ -162,8 +162,8 @@ jobs: -e "s|\${GCP_PROJECT_ID}|${{ needs.determine-target.outputs.gcp_project_id }}|g" \ -e "s|\${DOMAIN}|${DOMAIN}|g" \ -e "s|\${CERTBOT_EMAIL}|${{ secrets.CERTBOT_EMAIL }}|g" \ - -e "s|\${AWS_ACCESS_KEY_ID}|${{ secrets.AWS_ACCESS_KEY_ID_ROUTE53 }}|g" \ - -e "s|\${AWS_SECRET_ACCESS_KEY}|${{ secrets.AWS_SECRET_ACCESS_KEY_ROUTE53 }}|g" \ + -e "s|\${AWS_ACCESS_KEY_ID}|${{ secrets.AWS_ACCESS_KEY_ID_CERTBOT }}|g" \ + -e "s|\${AWS_SECRET_ACCESS_KEY}|${{ secrets.AWS_SECRET_ACCESS_KEY_CERTBOT }}|g" \ docker-compose.phala.yml > docker-compose.deploy.yml if [ -n "$DOMAIN" ]; then # Strip profiles: line so dstack-ingress starts unconditionally From 01f7aeabc2c869f6560ce383feb5f0bba6d64b4a Mon Sep 17 00:00:00 2001 From: Adam Reif Date: Thu, 26 Mar 2026 14:15:12 -0500 Subject: [PATCH 04/17] refactor: remove compose profiles, strip dstack-ingress when no domain Phala deploy doesn't support compose profiles, so dstack-ingress is now unconditionally defined. The deploy workflow strips the entire service block when DOMAIN is empty. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/deploy-phala.yml | 6 +----- docker-compose.phala.yml | 1 - 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/deploy-phala.yml b/.github/workflows/deploy-phala.yml index 96c1a097..d92418ab 100644 --- a/.github/workflows/deploy-phala.yml +++ b/.github/workflows/deploy-phala.yml @@ -165,11 +165,7 @@ jobs: -e "s|\${AWS_ACCESS_KEY_ID}|${{ secrets.AWS_ACCESS_KEY_ID_CERTBOT }}|g" \ -e "s|\${AWS_SECRET_ACCESS_KEY}|${{ secrets.AWS_SECRET_ACCESS_KEY_CERTBOT }}|g" \ docker-compose.phala.yml > docker-compose.deploy.yml - if [ -n "$DOMAIN" ]; then - # Strip profiles: line so dstack-ingress starts unconditionally - # (phala deploy doesn't support compose profiles) - sed -i '/profiles:/d' docker-compose.deploy.yml - else + if [ -z "$DOMAIN" ]; then # No custom domain — remove entire dstack-ingress service and cert-data volume awk ' /^ dstack-ingress:/ { skip=1; next } diff --git a/docker-compose.phala.yml b/docker-compose.phala.yml index 4105b7a6..aedbf515 100644 --- a/docker-compose.phala.yml +++ b/docker-compose.phala.yml @@ -112,7 +112,6 @@ services: # Obtains a Let's Encrypt cert for DOMAIN via DNS-01 (Route 53), then # reverse-proxies HTTPS :443 → lit-api-server :8000. dstack-ingress: - profiles: ["custom-domain"] image: dstacktee/dstack-ingress:1.4@sha256:11c0481ca2e3566f514a1c8a2cc69af1e0bb9dab2e4ea49b469c81ec8e7c5c72 ports: - "443:443" From eaea3a63f6b7f972447ad6a5d70e50d14dd0d230 Mon Sep 17 00:00:00 2001 From: Adam Reif Date: Thu, 26 Mar 2026 14:16:37 -0500 Subject: [PATCH 05/17] fix: rename secrets to CERTBOT_AWS_ACCESS_KEY_ID prefix convention Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/deploy-phala.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-phala.yml b/.github/workflows/deploy-phala.yml index d92418ab..b5bd34fb 100644 --- a/.github/workflows/deploy-phala.yml +++ b/.github/workflows/deploy-phala.yml @@ -162,8 +162,8 @@ jobs: -e "s|\${GCP_PROJECT_ID}|${{ needs.determine-target.outputs.gcp_project_id }}|g" \ -e "s|\${DOMAIN}|${DOMAIN}|g" \ -e "s|\${CERTBOT_EMAIL}|${{ secrets.CERTBOT_EMAIL }}|g" \ - -e "s|\${AWS_ACCESS_KEY_ID}|${{ secrets.AWS_ACCESS_KEY_ID_CERTBOT }}|g" \ - -e "s|\${AWS_SECRET_ACCESS_KEY}|${{ secrets.AWS_SECRET_ACCESS_KEY_CERTBOT }}|g" \ + -e "s|\${AWS_ACCESS_KEY_ID}|${{ secrets.CERTBOT_AWS_ACCESS_KEY_ID }}|g" \ + -e "s|\${AWS_SECRET_ACCESS_KEY}|${{ secrets.CERTBOT_AWS_SECRET_ACCESS_KEY }}|g" \ docker-compose.phala.yml > docker-compose.deploy.yml if [ -z "$DOMAIN" ]; then # No custom domain — remove entire dstack-ingress service and cert-data volume From 1d43a41f7351f0c2783148063a135bbc308bdf4d Mon Sep 17 00:00:00 2001 From: Adam Reif Date: Thu, 26 Mar 2026 14:22:11 -0500 Subject: [PATCH 06/17] fix: rename AWS credential placeholders to CERTBOT_ prefix Consistent naming end-to-end: compose file placeholders, workflow sed patterns, and GitHub secret references all use CERTBOT_AWS_ACCESS_KEY_ID and CERTBOT_AWS_SECRET_ACCESS_KEY. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/deploy-phala.yml | 4 ++-- docker-compose.phala.yml | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy-phala.yml b/.github/workflows/deploy-phala.yml index b5bd34fb..09ba27f0 100644 --- a/.github/workflows/deploy-phala.yml +++ b/.github/workflows/deploy-phala.yml @@ -162,8 +162,8 @@ jobs: -e "s|\${GCP_PROJECT_ID}|${{ needs.determine-target.outputs.gcp_project_id }}|g" \ -e "s|\${DOMAIN}|${DOMAIN}|g" \ -e "s|\${CERTBOT_EMAIL}|${{ secrets.CERTBOT_EMAIL }}|g" \ - -e "s|\${AWS_ACCESS_KEY_ID}|${{ secrets.CERTBOT_AWS_ACCESS_KEY_ID }}|g" \ - -e "s|\${AWS_SECRET_ACCESS_KEY}|${{ secrets.CERTBOT_AWS_SECRET_ACCESS_KEY }}|g" \ + -e "s|\${CERTBOT_AWS_ACCESS_KEY_ID}|${{ secrets.CERTBOT_AWS_ACCESS_KEY_ID }}|g" \ + -e "s|\${CERTBOT_AWS_SECRET_ACCESS_KEY}|${{ secrets.CERTBOT_AWS_SECRET_ACCESS_KEY }}|g" \ docker-compose.phala.yml > docker-compose.deploy.yml if [ -z "$DOMAIN" ]; then # No custom domain — remove entire dstack-ingress service and cert-data volume diff --git a/docker-compose.phala.yml b/docker-compose.phala.yml index aedbf515..b758dfff 100644 --- a/docker-compose.phala.yml +++ b/docker-compose.phala.yml @@ -16,8 +16,8 @@ # GCP_PROJECT_ID - GCP project ID (e.g. "my-gcp-project") # DOMAIN - Custom domain for TLS (e.g. "api.chipotle.litprotocol.com") # CERTBOT_EMAIL - Email for Let's Encrypt certificate notifications -# AWS_ACCESS_KEY_ID - Route 53 IAM credentials for DNS-01 challenge -# AWS_SECRET_ACCESS_KEY - Route 53 IAM credentials for DNS-01 challenge +# CERTBOT_AWS_ACCESS_KEY_ID - Route 53 IAM credentials for DNS-01 challenge +# CERTBOT_AWS_SECRET_ACCESS_KEY - Route 53 IAM credentials for DNS-01 challenge # RUST_LOG filter shared by lit-actions and lit-api-server. # App code stays at trace; per-module overrides suppress low-value internals: @@ -121,8 +121,8 @@ services: TARGET_ENDPOINT: "http://lit-api-server:8000" CERTBOT_EMAIL: "${CERTBOT_EMAIL}" SET_CAA: "true" - AWS_ACCESS_KEY_ID: "${AWS_ACCESS_KEY_ID}" - AWS_SECRET_ACCESS_KEY: "${AWS_SECRET_ACCESS_KEY}" + AWS_ACCESS_KEY_ID: "${CERTBOT_AWS_ACCESS_KEY_ID}" + AWS_SECRET_ACCESS_KEY: "${CERTBOT_AWS_SECRET_ACCESS_KEY}" volumes: - /var/run/dstack.sock:/var/run/dstack.sock - cert-data:/etc/letsencrypt From f61e23bcb0b33af024a7d3c25a8f9d511b1e7067 Mon Sep 17 00:00:00 2001 From: Adam Reif Date: Thu, 26 Mar 2026 14:23:01 -0500 Subject: [PATCH 07/17] docs: note dstack-ingress expected env var names with Phala docs link Co-Authored-By: Claude Opus 4.6 (1M context) --- docker-compose.phala.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker-compose.phala.yml b/docker-compose.phala.yml index b758dfff..b2f5e663 100644 --- a/docker-compose.phala.yml +++ b/docker-compose.phala.yml @@ -121,6 +121,8 @@ services: TARGET_ENDPOINT: "http://lit-api-server:8000" CERTBOT_EMAIL: "${CERTBOT_EMAIL}" SET_CAA: "true" + # dstack-ingress expects AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY internally. + # https://docs.phala.network/dstack/dstack-ingress#supported-dns-providers AWS_ACCESS_KEY_ID: "${CERTBOT_AWS_ACCESS_KEY_ID}" AWS_SECRET_ACCESS_KEY: "${CERTBOT_AWS_SECRET_ACCESS_KEY}" volumes: From b198a3bbc14e6e787ea6f1d645c93467625a1049 Mon Sep 17 00:00:00 2001 From: Adam Reif Date: Thu, 26 Mar 2026 14:25:11 -0500 Subject: [PATCH 08/17] fix: rename DOMAIN placeholder to CERTBOT_DOMAIN for consistency All dstack-ingress secrets now use CERTBOT_ prefix in the compose file (CERTBOT_DOMAIN, CERTBOT_AWS_ACCESS_KEY_ID, CERTBOT_AWS_SECRET_ACCESS_KEY). The deploy workflow maps them to the values dstack-ingress expects internally. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/deploy-phala.yml | 2 +- docker-compose.phala.yml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/deploy-phala.yml b/.github/workflows/deploy-phala.yml index 09ba27f0..1c5d66df 100644 --- a/.github/workflows/deploy-phala.yml +++ b/.github/workflows/deploy-phala.yml @@ -160,7 +160,7 @@ jobs: -e "s|\${DOCKER_IMAGE_LIT_STATIC}|${{ vars.DOCKER_IMAGE }}-lit-static@${DIGEST_LIT_STATIC}|g" \ -e "s|\${DOCKER_IMAGE_OTEL_COLLECTOR}|${{ vars.DOCKER_IMAGE }}-otel-collector@${DIGEST_OTEL_COLLECTOR}|g" \ -e "s|\${GCP_PROJECT_ID}|${{ needs.determine-target.outputs.gcp_project_id }}|g" \ - -e "s|\${DOMAIN}|${DOMAIN}|g" \ + -e "s|\${CERTBOT_DOMAIN}|${DOMAIN}|g" \ -e "s|\${CERTBOT_EMAIL}|${{ secrets.CERTBOT_EMAIL }}|g" \ -e "s|\${CERTBOT_AWS_ACCESS_KEY_ID}|${{ secrets.CERTBOT_AWS_ACCESS_KEY_ID }}|g" \ -e "s|\${CERTBOT_AWS_SECRET_ACCESS_KEY}|${{ secrets.CERTBOT_AWS_SECRET_ACCESS_KEY }}|g" \ diff --git a/docker-compose.phala.yml b/docker-compose.phala.yml index b2f5e663..0f86a2f8 100644 --- a/docker-compose.phala.yml +++ b/docker-compose.phala.yml @@ -14,7 +14,7 @@ # Required secrets (set as encrypted Phala CVM environment variables): # GCP_SERVICE_ACCOUNT_JSON - GCP service account key (raw JSON or base64-encoded) # GCP_PROJECT_ID - GCP project ID (e.g. "my-gcp-project") -# DOMAIN - Custom domain for TLS (e.g. "api.chipotle.litprotocol.com") +# CERTBOT_DOMAIN - Custom domain for TLS (e.g. "api.chipotle.litprotocol.com") # CERTBOT_EMAIL - Email for Let's Encrypt certificate notifications # CERTBOT_AWS_ACCESS_KEY_ID - Route 53 IAM credentials for DNS-01 challenge # CERTBOT_AWS_SECRET_ACCESS_KEY - Route 53 IAM credentials for DNS-01 challenge @@ -116,13 +116,13 @@ services: ports: - "443:443" environment: - DOMAIN: "${DOMAIN}" + # dstack-ingress expects DOMAIN, AWS_ACCESS_KEY_ID, and AWS_SECRET_ACCESS_KEY internally. + # https://docs.phala.network/dstack/dstack-ingress#supported-dns-providers + DOMAIN: "${CERTBOT_DOMAIN}" DNS_PROVIDER: "route53" TARGET_ENDPOINT: "http://lit-api-server:8000" CERTBOT_EMAIL: "${CERTBOT_EMAIL}" SET_CAA: "true" - # dstack-ingress expects AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY internally. - # https://docs.phala.network/dstack/dstack-ingress#supported-dns-providers AWS_ACCESS_KEY_ID: "${CERTBOT_AWS_ACCESS_KEY_ID}" AWS_SECRET_ACCESS_KEY: "${CERTBOT_AWS_SECRET_ACCESS_KEY}" volumes: From 62bd23059d161e60ffcdb50a6bbf79cf26c83eac Mon Sep 17 00:00:00 2001 From: Adam Reif Date: Thu, 26 Mar 2026 14:27:22 -0500 Subject: [PATCH 09/17] fix: replace dead Phala docs link with working blog post URL Co-Authored-By: Claude Opus 4.6 (1M context) --- docker-compose.phala.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.phala.yml b/docker-compose.phala.yml index 0f86a2f8..d4916ace 100644 --- a/docker-compose.phala.yml +++ b/docker-compose.phala.yml @@ -117,7 +117,7 @@ services: - "443:443" environment: # dstack-ingress expects DOMAIN, AWS_ACCESS_KEY_ID, and AWS_SECRET_ACCESS_KEY internally. - # https://docs.phala.network/dstack/dstack-ingress#supported-dns-providers + # https://phala.com/posts/zero-trust-https-how-to-setup-custom-domains-on-phala-cloud DOMAIN: "${CERTBOT_DOMAIN}" DNS_PROVIDER: "route53" TARGET_ENDPOINT: "http://lit-api-server:8000" From 609c6c8235b13abf391379b32f81c060a8b66c8a Mon Sep 17 00:00:00 2001 From: Adam Reif Date: Thu, 26 Mar 2026 14:43:51 -0500 Subject: [PATCH 10/17] fix: link to dstack-ingress DNS_PROVIDERS.md for Route 53 docs The previous link pointed to a Cloudflare-focused blog post. The actual Route 53 env var documentation lives in the Dstack-TEE examples repo. Co-Authored-By: Claude Opus 4.6 (1M context) --- docker-compose.phala.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker-compose.phala.yml b/docker-compose.phala.yml index d4916ace..8ecec3d7 100644 --- a/docker-compose.phala.yml +++ b/docker-compose.phala.yml @@ -117,7 +117,8 @@ services: - "443:443" environment: # dstack-ingress expects DOMAIN, AWS_ACCESS_KEY_ID, and AWS_SECRET_ACCESS_KEY internally. - # https://phala.com/posts/zero-trust-https-how-to-setup-custom-domains-on-phala-cloud + # Route 53 provider docs (env vars, optional role assumption): + # https://github.com/Dstack-TEE/dstack-examples/blob/main/custom-domain/dstack-ingress/DNS_PROVIDERS.md DOMAIN: "${CERTBOT_DOMAIN}" DNS_PROVIDER: "route53" TARGET_ENDPOINT: "http://lit-api-server:8000" From 9c890cca864f01b2977654a53c3edd2fdfd97f1a Mon Sep 17 00:00:00 2001 From: Adam Reif Date: Thu, 26 Mar 2026 14:49:58 -0500 Subject: [PATCH 11/17] docs: show optional AWS_ROLE_ARN/AWS_REGION for Route 53 role assumption Commented out since the IAM user has direct Route 53 permissions. Co-Authored-By: Claude Opus 4.6 (1M context) --- docker-compose.phala.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docker-compose.phala.yml b/docker-compose.phala.yml index 8ecec3d7..e0830ad7 100644 --- a/docker-compose.phala.yml +++ b/docker-compose.phala.yml @@ -126,6 +126,9 @@ services: SET_CAA: "true" AWS_ACCESS_KEY_ID: "${CERTBOT_AWS_ACCESS_KEY_ID}" AWS_SECRET_ACCESS_KEY: "${CERTBOT_AWS_SECRET_ACCESS_KEY}" + # Optional: for STS role assumption instead of direct IAM keys + # AWS_ROLE_ARN: "${CERTBOT_AWS_ROLE_ARN}" + # AWS_REGION: "${CERTBOT_AWS_REGION}" volumes: - /var/run/dstack.sock:/var/run/dstack.sock - cert-data:/etc/letsencrypt From 5fe1d1092e8952b1b5f0ace5aea4172bbd6aa6dc Mon Sep 17 00:00:00 2001 From: Adam Reif Date: Thu, 26 Mar 2026 14:51:17 -0500 Subject: [PATCH 12/17] fix: add missing GATEWAY_DOMAIN for dstack-ingress Required common variable per dstack-ingress docs. Co-Authored-By: Claude Opus 4.6 (1M context) --- docker-compose.phala.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.phala.yml b/docker-compose.phala.yml index e0830ad7..5b5ed025 100644 --- a/docker-compose.phala.yml +++ b/docker-compose.phala.yml @@ -120,6 +120,7 @@ services: # Route 53 provider docs (env vars, optional role assumption): # https://github.com/Dstack-TEE/dstack-examples/blob/main/custom-domain/dstack-ingress/DNS_PROVIDERS.md DOMAIN: "${CERTBOT_DOMAIN}" + GATEWAY_DOMAIN: "dstack-base-prod5.phala.network" DNS_PROVIDER: "route53" TARGET_ENDPOINT: "http://lit-api-server:8000" CERTBOT_EMAIL: "${CERTBOT_EMAIL}" From 5afa3eafe4b0c5817d7b00663e128dbd58b5a97b Mon Sep 17 00:00:00 2001 From: Adam Reif Date: Thu, 26 Mar 2026 15:47:33 -0500 Subject: [PATCH 13/17] fix: restore underscore prefix in GATEWAY_DOMAIN GATEWAY_DOMAIN should be _.dstack-base-prod5.phala.network per dstack-ingress docs. Co-Authored-By: Claude Opus 4.6 (1M context) --- docker-compose.phala.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.phala.yml b/docker-compose.phala.yml index 5b5ed025..5fb732bf 100644 --- a/docker-compose.phala.yml +++ b/docker-compose.phala.yml @@ -120,7 +120,7 @@ services: # Route 53 provider docs (env vars, optional role assumption): # https://github.com/Dstack-TEE/dstack-examples/blob/main/custom-domain/dstack-ingress/DNS_PROVIDERS.md DOMAIN: "${CERTBOT_DOMAIN}" - GATEWAY_DOMAIN: "dstack-base-prod5.phala.network" + GATEWAY_DOMAIN: "_.dstack-base-prod5.phala.network" DNS_PROVIDER: "route53" TARGET_ENDPOINT: "http://lit-api-server:8000" CERTBOT_EMAIL: "${CERTBOT_EMAIL}" From 8019956648a90238197092ff0d8ed761fa25e01a Mon Sep 17 00:00:00 2001 From: Adam Reif Date: Thu, 26 Mar 2026 16:00:34 -0500 Subject: [PATCH 14/17] fix: CERTBOT_AWS_ACCESS_KEY_ID is a var, not a secret Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/deploy-phala.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-phala.yml b/.github/workflows/deploy-phala.yml index c9b82162..9fedac97 100644 --- a/.github/workflows/deploy-phala.yml +++ b/.github/workflows/deploy-phala.yml @@ -156,7 +156,7 @@ jobs: -e "s|\${GCP_PROJECT_ID}|${{ needs.determine-target.outputs.gcp_project_id }}|g" \ -e "s|\${CERTBOT_DOMAIN}|${DOMAIN}|g" \ -e "s|\${CERTBOT_EMAIL}|${{ secrets.CERTBOT_EMAIL }}|g" \ - -e "s|\${CERTBOT_AWS_ACCESS_KEY_ID}|${{ secrets.CERTBOT_AWS_ACCESS_KEY_ID }}|g" \ + -e "s|\${CERTBOT_AWS_ACCESS_KEY_ID}|${{ vars.CERTBOT_AWS_ACCESS_KEY_ID }}|g" \ -e "s|\${CERTBOT_AWS_SECRET_ACCESS_KEY}|${{ secrets.CERTBOT_AWS_SECRET_ACCESS_KEY }}|g" \ docker-compose.phala.yml > docker-compose.deploy.yml if [ -z "$DOMAIN" ]; then From a8f0dee5273e252cd759293439ebb1b2c4b7e511 Mon Sep 17 00:00:00 2001 From: Adam Reif Date: Thu, 26 Mar 2026 16:03:05 -0500 Subject: [PATCH 15/17] =?UTF-8?q?refactor:=20remove=20optional=20domain=20?= =?UTF-8?q?logic=20=E2=80=94=20custom=20domain=20is=20mandatory?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/deploy-phala.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.github/workflows/deploy-phala.yml b/.github/workflows/deploy-phala.yml index 9fedac97..c5c7e74a 100644 --- a/.github/workflows/deploy-phala.yml +++ b/.github/workflows/deploy-phala.yml @@ -159,16 +159,6 @@ jobs: -e "s|\${CERTBOT_AWS_ACCESS_KEY_ID}|${{ vars.CERTBOT_AWS_ACCESS_KEY_ID }}|g" \ -e "s|\${CERTBOT_AWS_SECRET_ACCESS_KEY}|${{ secrets.CERTBOT_AWS_SECRET_ACCESS_KEY }}|g" \ docker-compose.phala.yml > docker-compose.deploy.yml - if [ -z "$DOMAIN" ]; then - # No custom domain — remove entire dstack-ingress service and cert-data volume - awk ' - /^ dstack-ingress:/ { skip=1; next } - skip && /^ [^ ]/ { skip=0 } - skip { next } - /^ cert-data:/ { next } - { print } - ' docker-compose.deploy.yml > docker-compose.deploy.tmp && mv docker-compose.deploy.tmp docker-compose.deploy.yml - fi cat docker-compose.deploy.yml - name: Setup Node.js From 0b23a51d52db7edc3f94c5476f71c6222ca5e35b Mon Sep 17 00:00:00 2001 From: Adam Reif Date: Thu, 26 Mar 2026 16:05:17 -0500 Subject: [PATCH 16/17] fix: hardcode CERTBOT_EMAIL to admin@litprotocol.com MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not sensitive — it's public in the ACME registration anyway. Remove the secret reference and sed substitution. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/deploy-phala.yml | 1 - docker-compose.phala.yml | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/deploy-phala.yml b/.github/workflows/deploy-phala.yml index c5c7e74a..69a5ba0c 100644 --- a/.github/workflows/deploy-phala.yml +++ b/.github/workflows/deploy-phala.yml @@ -155,7 +155,6 @@ jobs: -e "s|\${DOCKER_IMAGE_OTEL_COLLECTOR}|${{ vars.DOCKER_IMAGE }}-otel-collector@${DIGEST_OTEL_COLLECTOR}|g" \ -e "s|\${GCP_PROJECT_ID}|${{ needs.determine-target.outputs.gcp_project_id }}|g" \ -e "s|\${CERTBOT_DOMAIN}|${DOMAIN}|g" \ - -e "s|\${CERTBOT_EMAIL}|${{ secrets.CERTBOT_EMAIL }}|g" \ -e "s|\${CERTBOT_AWS_ACCESS_KEY_ID}|${{ vars.CERTBOT_AWS_ACCESS_KEY_ID }}|g" \ -e "s|\${CERTBOT_AWS_SECRET_ACCESS_KEY}|${{ secrets.CERTBOT_AWS_SECRET_ACCESS_KEY }}|g" \ docker-compose.phala.yml > docker-compose.deploy.yml diff --git a/docker-compose.phala.yml b/docker-compose.phala.yml index 8deec0b2..707f9079 100644 --- a/docker-compose.phala.yml +++ b/docker-compose.phala.yml @@ -14,7 +14,6 @@ # GCP_SERVICE_ACCOUNT_JSON - GCP service account key (raw JSON or base64-encoded) # GCP_PROJECT_ID - GCP project ID (e.g. "my-gcp-project") # CERTBOT_DOMAIN - Custom domain for TLS (e.g. "api.chipotle.litprotocol.com") -# CERTBOT_EMAIL - Email for Let's Encrypt certificate notifications # CERTBOT_AWS_ACCESS_KEY_ID - Route 53 IAM credentials for DNS-01 challenge # CERTBOT_AWS_SECRET_ACCESS_KEY - Route 53 IAM credentials for DNS-01 challenge @@ -111,7 +110,7 @@ services: GATEWAY_DOMAIN: "_.dstack-base-prod5.phala.network" DNS_PROVIDER: "route53" TARGET_ENDPOINT: "http://lit-api-server:8000" - CERTBOT_EMAIL: "${CERTBOT_EMAIL}" + CERTBOT_EMAIL: "admin@litprotocol.com" SET_CAA: "true" AWS_ACCESS_KEY_ID: "${CERTBOT_AWS_ACCESS_KEY_ID}" AWS_SECRET_ACCESS_KEY: "${CERTBOT_AWS_SECRET_ACCESS_KEY}" From d1db34a46f3d891b8d8b3e90329af40c127a51f0 Mon Sep 17 00:00:00 2001 From: Adam Reif Date: Thu, 26 Mar 2026 16:17:33 -0500 Subject: [PATCH 17/17] refactor: derive base_url and api_root_url from domain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set DOMAIN as a shell variable per branch, then derive all URL outputs from it — removes redundant hardcoded URLs. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/deploy-phala.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy-phala.yml b/.github/workflows/deploy-phala.yml index 69a5ba0c..aa37617d 100644 --- a/.github/workflows/deploy-phala.yml +++ b/.github/workflows/deploy-phala.yml @@ -59,21 +59,20 @@ jobs: echo "instance_type=tdx.large" >> "$GITHUB_OUTPUT" echo "gcp_project_id=chipotle-dev" >> "$GITHUB_OUTPUT" echo "node_config=NodeConfig.main.toml" >> "$GITHUB_OUTPUT" - echo "domain=api.chipotle.litprotocol.com" >> "$GITHUB_OUTPUT" - BASE_URL="https://api.chipotle.litprotocol.com" + DOMAIN="api.chipotle.litprotocol.com" elif [ "${{ github.ref }}" = "refs/heads/next" ]; then echo "phala_app_name=chipotle-next" >> "$GITHUB_OUTPUT" echo "instance_type=tdx.small" >> "$GITHUB_OUTPUT" echo "gcp_project_id=chipotle-next" >> "$GITHUB_OUTPUT" echo "node_config=NodeConfig.next.toml" >> "$GITHUB_OUTPUT" - echo "domain=test.chipotle.litprotocol.com" >> "$GITHUB_OUTPUT" - BASE_URL="https://test.chipotle.litprotocol.com" + DOMAIN="test.chipotle.litprotocol.com" else echo "Unsupported branch for deployment" exit 1 fi - echo "base_url=$BASE_URL" >> "$GITHUB_OUTPUT" - echo "api_root_url=${BASE_URL}/core/v1" >> "$GITHUB_OUTPUT" + echo "domain=${DOMAIN}" >> "$GITHUB_OUTPUT" + echo "base_url=https://${DOMAIN}" >> "$GITHUB_OUTPUT" + echo "api_root_url=https://${DOMAIN}/core/v1" >> "$GITHUB_OUTPUT" build: needs: [determine-target]