Skip to content

feat: add dstack-ingress for custom domain TLS (CPL-152)#181

Merged
Garandor merged 18 commits intonextfrom
cpl-152/custom-domain-compose-deploy
Mar 26, 2026
Merged

feat: add dstack-ingress for custom domain TLS (CPL-152)#181
Garandor merged 18 commits intonextfrom
cpl-152/custom-domain-compose-deploy

Conversation

@Garandor
Copy link
Copy Markdown
Contributor

@Garandor Garandor commented Mar 26, 2026

Summary

Adds dstack-ingress service to docker-compose.phala.yml for attestation-bound TLS termination inside the TEE, and wires it into the deploy workflow with per-branch custom domains.

Changes

docker-compose.phala.yml

  • Added dstack-ingress service (pinned image with @sha256: digest) for Route 53 DNS-01 TLS
  • All required dstack-ingress env vars: DOMAIN, GATEWAY_DOMAIN (_.dstack-base-prod5.phala.network), DNS_PROVIDER, TARGET_ENDPOINT, CERTBOT_EMAIL, SET_CAA
  • CERTBOT_EMAIL hardcoded to admin@litprotocol.com (public in ACME registration, not sensitive)
  • Route 53 credentials: AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY sourced from CERTBOT_-prefixed env vars
  • Optional AWS_ROLE_ARN / AWS_REGION documented as comments (not needed with direct IAM permissions)
  • cert-data volume for Let's Encrypt certificate persistence
  • Comments link to dstack-ingress DNS_PROVIDERS.md for Route 53 reference
  • lit-static stays removed (moved to Cloudflare Pages in CPL-33)

.github/workflows/deploy-phala.yml

  • Custom domain is mandatory for all branches — no optional stripping logic
  • mainapi.chipotle.litprotocol.com, nexttest.chipotle.litprotocol.com
  • base_url and api_root_url derived from domain (no redundant hardcoded URLs)
  • Deploy step substitutes CERTBOT_DOMAIN, CERTBOT_AWS_ACCESS_KEY_ID (var), CERTBOT_AWS_SECRET_ACCESS_KEY (secret) into compose file

Required GitHub configuration

  • Variable: CERTBOT_AWS_ACCESS_KEY_ID — Route 53 IAM access key
  • Secret: CERTBOT_AWS_SECRET_ACCESS_KEY — Route 53 IAM secret key

Dependencies

  • CPL-150: Route 53 zone + NS delegation (done)
  • CPL-151: IAM credentials + GitHub secrets (required before first deploy)

Test plan

  • docker-compose.phala.yml validates with docker compose config
  • Merged with next — conflicts resolved cleanly
  • CI passes on this PR
  • After CPL-151, deploy to next and verify https://test.chipotle.litprotocol.com/health returns 200
  • Deploy to main and verify https://api.chipotle.litprotocol.com/health returns 200

🤖 Generated with Claude Code

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) <noreply@anthropic.com>
@linear
Copy link
Copy Markdown

linear bot commented Mar 26, 2026

CPL-152 Update docker-compose + deploy workflow for Phase 0

Code changes to deploy dstack-ingress with api.chipotle.litprotocol.com

Builds on PR #153 (feature/cpl-118-add-dstack-ingress-to-docker-composephalayml).

docker-compose.phala.yml

  • Change DOMAIN: \"${NODE_DOMAIN}\"DOMAIN: \"${DOMAIN}\"
  • Remove ALIAS_DOMAIN env var (not needed for Phase 0)
  • Update header comment: list DOMAIN instead of NODE_DOMAIN, remove ALIAS_DOMAIN

deploy-phala.yml

determine-target — add domain output:

  • main: domain=api.chipotle.litprotocol.com
  • next: no custom domain

deploy job — sed substitutions:

-e \"s|\\${DOMAIN}|$DOMAIN|g\"
-e \"s|\\${CERTBOT_EMAIL}|$CERTBOT_EMAIL|g\"
-e \"s|\\${AWS_ACCESS_KEY_ID}|$AWS_ACCESS_KEY_ID|g\"
-e \"s|\\${AWS_SECRET_ACCESS_KEY}|$AWS_SECRET_ACCESS_KEY|g\"
-e '/profiles:/d'

Strip profiles: line so dstack-ingress starts unconditionally (phala deploy doesn't support compose profiles).

Blocked on

  • CPL-151 (IAM credentials + GitHub secrets)"

Garandor and others added 9 commits March 26, 2026 13:40
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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) <noreply@anthropic.com>
Garandor and others added 8 commits March 26, 2026 14:49
Commented out since the IAM user has direct Route 53 permissions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Required common variable per dstack-ingress docs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
GATEWAY_DOMAIN should be _.dstack-base-prod5.phala.network per dstack-ingress docs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…gress

next branch removed lit-static (moved to Cloudflare Pages in CPL-33).
Our branch added dstack-ingress. Resolution: accept lit-static removal
from next, keep dstack-ingress addition from our branch.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
@Garandor Garandor merged commit cd141f4 into next Mar 26, 2026
2 checks passed
Garandor added a commit that referenced this pull request Mar 27, 2026
* 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) <noreply@anthropic.com>

* 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) <noreply@anthropic.com>

* 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) <noreply@anthropic.com>

* 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) <noreply@anthropic.com>

* fix: rename secrets to CERTBOT_AWS_ACCESS_KEY_ID prefix convention

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 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) <noreply@anthropic.com>

* docs: note dstack-ingress expected env var names with Phala docs link

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 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) <noreply@anthropic.com>

* fix: replace dead Phala docs link with working blog post URL

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 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) <noreply@anthropic.com>

* 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) <noreply@anthropic.com>

* fix: add missing GATEWAY_DOMAIN for dstack-ingress

Required common variable per dstack-ingress docs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 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) <noreply@anthropic.com>

* fix: CERTBOT_AWS_ACCESS_KEY_ID is a var, not a secret

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: remove optional domain logic — custom domain is mandatory

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: hardcode CERTBOT_EMAIL to admin@litprotocol.com

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) <noreply@anthropic.com>

* refactor: derive base_url and api_root_url from domain

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) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant