Add managed Postgres, MySQL, or Redis
Add a managed database to a project from the dashboard and link it into a container so the connection URL is injected automatically.
Add a database
Managed databases live inside your project and are reachable only over internal DNS. They are never exposed publicly. You create one in the dashboard, then link it to a container so the platform injects the connection URL (with credentials) into that container for you. You never see, copy, or set the password by hand.
The engines are fixed and managed: Postgres 16, MySQL 8.4, Redis 8.
Dashboard flow
DATABASE_URL (Postgres/MySQL) or REDIS_URL (Redis) into that container and re-rolls it automatically.1. Create the database
In the create dialog you set:
- Project: the database joins this project and is reachable only by services in it.
- Engine: PostgreSQL, MySQL, or Redis. The dialog shows the matching options:
- PostgreSQL: version
16. Connects on port5432asDATABASE_URL. - MySQL: version
8.4. Connects on port3306asDATABASE_URL. - Redis: connects on port
6379asREDIS_URL. A persistence toggle (on by default; off for a pure-cache instance) and an eviction policy (maxmemory_policy, defaultallkeys-lru).
- PostgreSQL: version
- Name: a friendly name; the dialog shows the slug it deploys as.
- Resources: reserved CPU, memory, and storage (bounded, see below).
resources are bounded: cpu_milli 250-4000 (steps of 250), memory_mb
256-8192 (steps of 128), storage_gb 1-100. Out-of-range values are rejected.
Each database runs as a single internal instance; replicas are not configurable.
2. Connect it to a container
You can connect from either side, and both do the same thing:
- On the container page, open Connected services → Connect a database and pick a database in the same project.
- On the database page, open Link to container and pick a container.
The database is the provider, the container is the consumer. The platform injects the connection variables into the container through a Kubernetes Secret reference and re-rolls it automatically. The credentials stay in the Secret. They never appear in plaintext env or in any API response, and you never set them by hand.
The connection is durable: it is re-applied on every change, whether env edits, scaling, autoscaling, or an image deploy (including from GitHub Actions), so a linked app stays connected across redeploys.
What gets injected (per framework)
The platform injects a standard set of variables, so the right name is already present for your stack:
| Engine | Read this | Also injected |
|---|---|---|
| Postgres | DATABASE_URL | PGHOST PGPORT PGDATABASE PGUSER PGPASSWORD; SPRING_DATASOURCE_URL / _USERNAME / _PASSWORD |
| MySQL | DATABASE_URL | DB_HOST DB_PORT DB_NAME DB_USER DB_PASSWORD; SPRING_DATASOURCE_* |
| Redis | REDIS_URL | REDIS_HOST REDIS_PORT REDIS_PASSWORD |
Node, Python, Go, Rails, and Django read DATABASE_URL; Java/Spring reads
SPRING_DATASOURCE_URL. The container's Connected services card shows the
exact variable names and a copy-paste snippet for your language, plus an
Unlink action.
A managed database is only connectable to a backend container. Frontend
bundles (VITE_* / REACT_APP_*) are built ahead of time and must never carry a
database credential, so a database link is not offered for them.
3. Read the variable in your app
Once connected, your container rolls with the variables present. Read them the
normal way from the environment (for example os.environ["DATABASE_URL"] or
process.env.REDIS_URL).
Advanced: the API path
The same create and link flow is available over the API for automation and
scripting. Authenticate every call with your account token in the
Authorization: Bearer header, and get the PROJECT_ID from your project in the
dashboard.
Create the database
Send the friendly name, the reserved resources, and (for Postgres/MySQL) a
version. The platform slugifies the name, generates the credentials, and
returns the new service's id and its internal connection host:
# Add managed Postgres to a project
curl -X POST https://api.alawadi.cloud/v1/projects/$PROJECT_ID/postgres \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "app-db",
"version": "16",
"resources": { "cpu_milli": 500, "memory_mb": 512, "storage_gb": 5 }
}'Swap the path segment for mysql or redis to create those engines instead:
postgres:versionis16. Connects on port5432asDATABASE_URL.mysql:versionis8.4. Connects on port3306asDATABASE_URL.redis: version is fixed; omit it. Connects on port6379asREDIS_URL. Optionally send"persistence": falsefor a pure-cache instance, or"maxmemory_policy"(one ofnoeviction,allkeys-lru,allkeys-lfu,allkeys-random,volatile-lru,volatile-lfu,volatile-random,volatile-ttl; defaultallkeys-lru) to set the eviction policy.
resources is required and bounded: cpu_milli 250-4000 (steps of 250),
memory_mb 256-8192 (steps of 128), storage_gb 1-100. Out-of-range values
return BAD_RESOURCES; an unsupported version returns BAD_VERSION, and a bad
Redis policy returns BAD_MAXMEMORY_POLICY.
The 201 response wraps the new service and a connection block. The service
id is what you link with, and the connection shows the internal host your app
would use:
{
"service": {
"id": "11111111-1111-1111-1111-111111111111",
"name": "app-db",
"type": "postgres",
"status": "provisioning"
},
"connection": {
"host": "app-db-rw.<namespace>.svc.cluster.local:5432",
"port": "5432",
"env_var": "DATABASE_URL",
"requires_auth": "true",
"instructions": "Link this Postgres to a container to auto-inject DATABASE_URL (with credentials) into it."
}
}The connection block is also returned by GET /v1/containers/{containerID} for
any database, so you can read the host and connection variable back later.
Link it into a container
Pass the service IDs (the id field from each service, not its name) of the
consumer container and the database as the provider, plus the link_type that
matches the provider engine (postgres, mysql, or redis):
# Link the database into your web container
curl -X POST https://api.alawadi.cloud/v1/projects/$PROJECT_ID/service-links \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"consumer_service_id": "'"$WEB_CONTAINER_ID"'",
"provider_service_id": "'"$DB_SERVICE_ID"'",
"link_type": "postgres"
}'consumer_service_id, provider_service_id, and link_type are all required.
The link_type is postgres, mysql, or redis, matching the provider engine
(Postgres/MySQL inject DATABASE_URL; Redis injects REDIS_URL). The consumer
must be a generic container in the same project. The 201 response returns
the link, including the injected_env map.
To confirm a link exists, list them:
curl https://api.alawadi.cloud/v1/projects/$PROJECT_ID/service-links \
-H "Authorization: Bearer $TOKEN"See Managed Postgres, MySQL, and Redis for the connection model and host formats.
Connect an app to object storage
Wire a deployed container to an S3 bucket with environment variables and the AWS SDK, for JavaScript (v3) and Python (boto3).
Deploy a Marketplace app in one click
Pick a curated community app like WordPress or n8n and deploy it in one click — the platform creates and links its managed database, attaches storage, and brings it up on a public URL.