Skip to main content

Attachments

An attachment connects your app to a managed database, another app, or a files (object storage) service over a private SDN. The platform peers the networks, opens the appropriate firewall, and injects connection details as environment variables. Up to five attachments per app, counting databases, apps, and files services together.

Attach at creation

Pass a list of service UUIDs in attached_service_ids:

curl -u "$USER:$PASS" -X POST https://api.foundrydb.com/app-services \
-H "Content-Type: application/json" \
-d '{
"name": "my-api",
"plan_name": "tier-2",
"zone": "se-sto1",
"app_config": {
"image_ref": "ghcr.io/acme/api:1.0.0",
"container_port": 8080
},
"attached_service_ids": ["<postgres-uuid>", "<opensearch-uuid>"]
}'

All attachment targets must be Running, owned by the same account, and located in the same peering region as the app.

Attach to a running app

curl -u "$USER:$PASS" -X POST \
https://api.foundrydb.com/app-services/{id}/attachments \
-H "Content-Type: application/json" \
-d '{ "attached_service_id": "<postgres-uuid>" }'

This triggers the re-wiring (network peering and firewall updates) and a zero-downtime blue/green redeploy so the injected environment variables are updated. The app moves through PendingModification and returns to Running. Rejected if the app is not Running, the target is already attached, the five-attachment cap is reached, or the target is in a different region.

Detach from a running app

Use the attachment id from the app's attachments list:

curl -u "$USER:$PASS" -X DELETE \
https://api.foundrydb.com/app-services/{id}/attachments/{attachmentId}

The platform reverts the firewall opening, tears down the network peering, and rolls a zero-downtime redeploy to remove the injected environment variables.

Database attachments

When you attach a managed database, the platform:

  1. Peers the app's private SDN to the database's private network.
  2. Opens the database firewall to the app's subnet (for PostgreSQL, also adds a pg_hba.conf entry).
  3. Injects connection details as environment variables into the container.

The injected variables follow this scheme, where <NAME> is the uppercased database service name:

VariableValue
MDB_<NAME>_HOSTThe database primary's private SDN address.
MDB_<NAME>_PORTThe database port.
MDB_<NAME>_USERThe application database user.
MDB_<NAME>_PASSWORDThe application database password.
MDB_<NAME>_DATABASEThe default database name.
DATABASE_URLA ready-to-use connection string. Injected only when exactly one database is attached.

DATABASE_URL is injected when exactly one database is attached. Attaching a second database removes it; detaching back down to one restores it.

Example: attach PostgreSQL and read the injected variables

# Inside the container, after a PostgreSQL attachment
echo $MDB_ORDERS_HOST # 10.13.x.y (private SDN address)
echo $MDB_ORDERS_PORT # 5432
echo $MDB_ORDERS_USER # app_user
echo $MDB_ORDERS_DATABASE # defaultdb
echo $DATABASE_URL # postgres://app_user:...@10.13.x.y:5432/defaultdb (single attachment only)

The host is always the primary's private SDN address. Traffic between the app and the database never leaves the platform network. After a database failover, the platform detects the new primary and automatically redeploys the app to re-inject the updated address within about a minute.

App-to-app attachments (east-west)

An attachment target can be another app, not just a database. This lets one app reach another over the private SDN with no public exposure and no credentials to manage.

curl -u "$USER:$PASS" -X POST \
https://api.foundrydb.com/app-services/{storefront-id}/attachments \
-H "Content-Type: application/json" \
-d '{ "attached_service_id": "<payments-api-id>" }'

For an app target, the platform injects:

VariableValue
MDB_<NAME>_HOSTThe target app's private SDN address.
MDB_<NAME>_PORTThe target app's container port.
MDB_<NAME>_URLhttp://<host>:<port>, ready to call.

No username, password, database name, or DATABASE_URL is injected for an app target. The trust boundary is the SDN itself.

Traffic from the source app reaches the target on its container port over plain HTTP inside the private network. It never traverses the public internet and never touches the target's public HTTPS ingress.

# Inside the storefront container
curl "$MDB_PAYMENTS_URL/charges" \
-H "Content-Type: application/json" \
-d '{ "amount": 4200, "currency": "eur" }'

App-to-app rules

  • The target app must listen on a dedicated container port. Ports 80 and 443 are reserved for the public HTTPS ingress; an attach to an app on those ports is rejected.
  • An app cannot attach to itself.
  • Apps deployed with app-to-app support open their internal listener automatically. An older app may need a one-time redeploy to open it.
  • The five-attachment cap counts databases and apps together.

Attachment status

After attaching, the attachments array on GET /app-services/{id} shows the status of each attachment:

StatusMeaning
pendingWiring not yet started.
peeringNetwork peering in progress.
firewallFirewall rules being applied.
activeWiring complete; environment variables are injected.
failedWiring failed. The error_message field has details.