Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions samples/self-improving-mastra/.env.aws
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
# Non-secret Compose interpolation values selected by cli for aws provider.
# Non-secret Compose interpolation values loaded for the AWS provider.
CHAT_MODEL=zai.glm-5
PUBLISH_ENABLED=true
PUBLISH_POLICY=arn:aws:iam::aws:policy/AdministratorAccess
PUBLISH_PROVIDER=aws
PUBLISH_STACK=aws
5 changes: 1 addition & 4 deletions samples/self-improving-mastra/.env.gcp
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
# Non-secret Compose interpolation values selected by cli for gcp provider.
# Non-secret Compose interpolation values loaded for the GCP provider.
CHAT_MODEL=gemini-2.5-flash
PUBLISH_ENABLED=true
PUBLISH_POLICY=roles/owner
PUBLISH_PROVIDER=gcp
PUBLISH_STACK=gcp
22 changes: 13 additions & 9 deletions samples/self-improving-mastra/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ recover the app even if a bad edit crashes the Next.js dev server.

## Prerequisites

1. Download the [Defang CLI](https://github.com/DefangLabs/defang).
1. Use a [Defang CLI](https://github.com/DefangLabs/defang) build that exposes
the resolved `DEFANG_PROVIDER` and `DEFANG_STACK` Compose variables (added by
[DefangLabs/defang#2189](https://github.com/DefangLabs/defang/pull/2189));
v3.12.0 does not include this support.
2. Authenticate with a cloud account that has managed LLMs: a GCP project with
Vertex AI, or an AWS account with Bedrock model access.
3. For local development, install Docker Desktop with
Expand Down Expand Up @@ -99,10 +102,10 @@ The `dev` service deliberately runs as one always-on instance so its working
tree survives idle periods. The `app` service remains a stateless production
build.

Cloud deployments share the one `compose.yaml`. The committed `aws` and `gcp`
stack files select different non-secret interpolation files:
Cloud deployments share the one `compose.yaml`. After resolving the provider,
Defang automatically loads its non-secret interpolation file:

| Stack | Environment file | Publish permission |
| Provider | Environment file | Publish permission |
| --- | --- | --- |
| `aws` | `.env.aws` | `AdministratorAccess` |
| `gcp` | `.env.gcp` | `roles/owner` |
Expand Down Expand Up @@ -136,9 +139,9 @@ defang compose up --stack aws
```

> [!NOTE]
> Each stack's env file sets `PUBLISH_STACK` to itself. The in-container
> **Publish** button therefore reuses the original cloud and env file without
> copying or renaming configuration.
> Defang supplies the resolved provider and stack to the `dev` service. The
> in-container **Publish** button therefore reuses the original deployment
> context, including the matching provider env file.

## Publishing (self-redeploy)

Expand All @@ -161,8 +164,9 @@ mutates its own deployment.
one per publish, each referencing the database rows it addressed) rides
along in the build context, so the next dev container continues the same
lineage.
- `PUBLISH_STACK` comes from the selected `.env.<cloud>` file; publishing is
disabled in local development.
- `PUBLISH_PROVIDER` and `PUBLISH_STACK` come from Defang's resolved deployment
context; the standalone local-development Compose file leaves publishing
disabled.

## Run history and revert

Expand Down
10 changes: 5 additions & 5 deletions samples/self-improving-mastra/agent/src/publish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ const exec = promisify(execFile);
* — the human login ceremony IS the deploy authorization.
*
* Cloud credentials are ambient: the AWS task role or GCP VM service account
* receives the grant selected by the cloud-specific env file. The selected
* `.defang/<stack>` file supplies provider/region and chooses that same env
* file again when this container redeploys itself.
* receives the grant loaded from the provider-specific env file. Defang's
* resolved deployment context supplies the provider and stack, so the CLI
* loads the matching env file again when this container redeploys itself.
*/

const STATE_DIR = "/run/defang-publish";
Expand Down Expand Up @@ -88,7 +88,7 @@ async function publishEnv(): Promise<NodeJS.ProcessEnv> {
const provider = process.env.PUBLISH_PROVIDER;
const stack = process.env.PUBLISH_STACK;
if (!provider || !stack) {
throw new Error("PUBLISH_PROVIDER and PUBLISH_STACK must be set by the selected stack env file");
throw new Error("PUBLISH_PROVIDER and PUBLISH_STACK must be set from Defang deployment context");
}

const env: NodeJS.ProcessEnv = {
Expand Down Expand Up @@ -244,7 +244,7 @@ export async function confirmDeploy(): Promise<PublishState> {

const stack = process.env.PUBLISH_STACK;
if (!stack) {
fail("PUBLISH_STACK is not set by the selected stack env file");
fail("PUBLISH_STACK is not set from Defang deployment context");
return state;
}
deployProc = spawn("defang", ["compose", "up", "--detach", "--stack", stack], {
Expand Down
10 changes: 5 additions & 5 deletions samples/self-improving-mastra/compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ services:
# if the main app is down and their login session has expired.
ADMIN_TOKEN:
# Enable the admin-triggered self-redeploy. Fabric auth is a per-publish
# interactive `defang login` (no stored token). The stack-specific env
# file supplies the same stack/provider choice for self-redeploys.
PUBLISH_ENABLED: "${PUBLISH_ENABLED:-false}"
PUBLISH_PROVIDER: "${PUBLISH_PROVIDER:-disabled}"
PUBLISH_STACK: "${PUBLISH_STACK:-disabled}"
# interactive `defang login` (no stored token). Defang supplies the
# resolved provider and stack so self-redeploys target the same place.
PUBLISH_ENABLED: "true"
PUBLISH_PROVIDER: "${DEFANG_PROVIDER}"
PUBLISH_STACK: "${DEFANG_STACK}"
# CHAT_URL, CHAT_MODEL, and OPENAI_API_KEY (the gateway's master key) are
# injected automatically by the `models:` binding below; the coding agent
# reads them in agent/src/model.ts.
Expand Down
Loading