# How to Manage Databases in App Platform App Platform is a fully managed Platform-as-a-Service (PaaS) that deploys applications from Git repositories or container images. It automatically builds, deploys, and scales components while handling all underlying infrastructure. App Platform offers two types of databases: - **Dev databases**, which are intended for development use. Dev databases come in one size and are optimized for lightweight workloads. They use a default PostgreSQL database that is provisioned for you, and database creation permissions are not included. - **Managed databases**, which are instances of [DigitalOcean Managed Databases](https://docs.digitalocean.com/products/databases/index.html.md) that you can use in App Platform. We recommend managed databases for production use. Managed databases support multiple database engines. They also offer advanced features such as standby nodes, vertical scaling, read-only nodes for additional throughput, and multiple trusted sources both internal and external to DigitalOcean services. You can add a dev or managed database to your app at any time. You can also upgrade a dev database to a managed database. ## Add a Database to an Existing App You can add a database during your app’s initial creation or add one later using the DigitalOcean Control Panel. You can also add a database to an app by defining it in your app’s spec file and then submitting the new spec using either the API, CLI, DigitalOcean Control Panel, or the app’s source repo. **Note**: Dev databases are located in the same region as your app and cannot be migrated to another region. If you migrate your app to a different region, the app won’t be able to access the associated dev database anymore. If you need to migrate your app and dev database, we recommend either backing up the contents of the database and restoring it after the app’s migration, or using a [DigitalOcean Managed Database](https://docs.digitalocean.com/products/databases/index.html.md) instead. You can migrate managed databases independently of apps to different regions as needed. Go to the [DigitalOcean Control Panel](https://cloud.digitalocean.com), click **Create**, then select **Databases** from the dropdown menu. Choose from the available options, then click **Create Database Cluster**. The database you create appears in the **Database Clusters** list when you add a database in App Platform. This section describes how to add a database to an existing app using different methods. ### Add a Database to an App Using Automation You can add a database to an app using the CLI’s app update command or the API’s app update endpoint. To add a database, update the [app spec](https://docs.digitalocean.com/products/app-platform/reference/app-spec/index.html.md) with the database’s specifications and submit the spec using the following command or endpoint. ## How to Add a Database to an App Using the DigitalOcean CLI 1. [Install `doctl`](https://docs.digitalocean.com/reference/doctl/how-to/install/index.html.md), the official DigitalOcean CLI. 2. [Create a personal access token](https://docs.digitalocean.com/reference/api/create-personal-access-token/index.html.md) and save it for use with `doctl`. 3. Use the token to grant `doctl` access to your DigitalOcean account. ```shell doctl auth init ``` 4. Finally, run `doctl apps update`. Basic usage looks like this, but you can [read the usage docs](https://docs.digitalocean.com/reference/doctl/reference/apps/update/index.html.md) for more details: ```shell doctl apps update [flags] ``` The following example updates an app with the ID `f81d4fae-7dec-11d0-a765-00a0c91e6bf6` using an app spec located in a directory called `/src/your-app.yaml`. Additionally, the command returns the updated app’s ID, ingress information, and creation date: ```shell doctl apps update f81d4fae-7dec-11d0-a765-00a0c91e6bf6 --spec src/your-app.yaml --format ID,DefaultIngress,Created ``` ## How to Add a Database to an App Using the DigitalOcean API 1. [Create a personal access token](https://docs.digitalocean.com/reference/api/create-personal-access-token/index.html.md) and save it for use with the API. 2. Send a PUT request to [`https://api.digitalocean.com/v2/apps/{id}`](https://docs.digitalocean.com/reference/api/digitalocean//index.html.md#operation/apps_update). ### cURL Using cURL: ```shell curl -X PUT \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ "https://api.digitalocean.com/v2/apps/{id}" \ -d '{"alerts":[{"rule":"DEPLOYMENT_FAILED"},{"rule":"DOMAIN_FAILED"}],"domains":[{"domain":"example.com","type":"PRIMARY","zone":"example.com"}],"envs":[{"key":"API_KEY","scope":"RUN_AND_BUILD_TIME","type":"SECRET","value":"EV[1:zqiRIeaaYK/NqctZDYzy6t0pTrtRDez8:wqGpZRrsKN5nPhWQrS479cfBiXT0WQ==]"}],"features":["buildpack-stack=ubuntu-22"],"ingress":{},"name":"example-app","region":"nyc","services":[{"autoscaling":{"max_instance_count":4,"metrics":{"cpu":{"percent":70}},"min_instance_count":2},"git":{"branch":"main","repo_clone_url":"https://github.com/digitalocean/sample-nodejs.git"},"internal_ports":[8080],"log_destinations":[{"name":"your_log_consumer_name","open_search":{"endpoint":"logs.example.com:12345","basic_auth":{"user":"doadmin","password":"1234567890abcdef"},"index_name":"example-index","cluster_name":"example-cluster"}}],"name":"sample-nodejs","run_command":"yarn start","source_dir":"/"}]}' ``` ### Python Using [PyDo](https://github.com/digitalocean/pydo), the official DigitalOcean API client for Python: ```python import os from pydo import Client client = Client(token=os.environ.get("DIGITALOCEAN_TOKEN")) req = { "spec": { "name": "web-app-01", "region": "nyc", "domains": [ { "domain": "app.example.com", "type": "DEFAULT", "wildcard": True, "zone": "example.com", "minimum_tls_version": "1.3", } ], "services": [], "static_sites": [ { "cors": { "allow_origins": [ {"exact": "https://www.example.com"}, {"regex": "^.*example.com"}, ], "allow_methods": [ "GET", "OPTIONS", "POST", "PUT", "PATCH", "DELETE", ], "allow_headers": ["Content-Type", "X-Custom-Header"], "expose_headers": ["Content-Encoding", "X-Custom-Header"], "max_age": "5h30m", "allow_credentials": False, }, "routes": [{"path": "/api", "preserve_path_prefix": True}], } ], "jobs": [ { "name": "api", "gitlab": { "branch": "main", "deploy_on_push": True, "repo": "digitalocean/sample-golang", }, "image": { "registry": "registry.hub.docker.com", "registry_type": "DOCR", "repository": "origin/master", "tag": "latest", }, "dockerfile_path": "path/to/Dockerfile", "build_command": "npm run build", "run_command": "bin/api", "source_dir": "path/to/dir", "envs": [ { "key": "BASE_URL", "scope": "BUILD_TIME", "type": "GENERAL", "value": "http://example.com", } ], "environment_slug": "node-js", "log_destinations": { "name": "my_log_destination", "papertrail": { "endpoint": "https://mypapertrailendpoint.com" }, "datadog": { "endpoint": "https://mydatadogendpoint.com", "api_key": "abcdefghijklmnopqrstuvwxyz0123456789", }, "logtail": { "token": "abcdefghijklmnopqrstuvwxyz0123456789" }, "open_search": { "endpoint": "https://myopensearchendpoint.com:9300" "index_name": "logs" "basic_auth": { "user": "doadmin", "password": "password" } }, }, "instance_count": 2, "instance_size_slug": "apps-s-1vcpu-0.5gb", "kind": "PRE_DEPLOY", } ], "workers": [ { "name": "api", "gitlab": { "branch": "main", "deploy_on_push": True, "repo": "digitalocean/sample-golang", }, "image": { "registry": "registry.hub.docker.com", "registry_type": "DOCR", "repository": "origin/master", "tag": "latest", }, "dockerfile_path": "path/to/Dockerfile", "build_command": "npm run build", "run_command": "bin/api", "source_dir": "path/to/dir", "envs": [ { "key": "BASE_URL", "scope": "BUILD_TIME", "type": "GENERAL", "value": "http://example.com", } ], "environment_slug": "node-js", "log_destinations": { "name": "my_log_destination", "papertrail": { "endpoint": "https://mypapertrailendpoint.com" }, "datadog": { "endpoint": "https://mydatadogendpoint.com", "api_key": "abcdefghijklmnopqrstuvwxyz0123456789", }, "logtail": { "token": "abcdefghijklmnopqrstuvwxyz0123456789" }, "open_search": { "endpoint": "https://myopensearchendpoint.com:9300" "index_name": "logs" "basic_auth": { "user": "doadmin", "password": "password" } }, }, "instance_count": 2, "instance_size_slug": "apps-s-1vcpu-0.5gb", } ], "functions": [ { "cors": { "allow_origins": [ {"exact": "https://www.example.com"}, {"regex": "^.*example.com"}, ], "allow_methods": [ "GET", "OPTIONS", "POST", "PUT", "PATCH", "DELETE", ], "allow_headers": ["Content-Type", "X-Custom-Header"], "expose_headers": ["Content-Encoding", "X-Custom-Header"], "max_age": "5h30m", "allow_credentials": False, }, "routes": [{"path": "/api", "preserve_path_prefix": True}], "name": "api", "source_dir": "path/to/dir", "alerts": [ { "rule": "CPU_UTILIZATION", "disabled": False, "operator": "GREATER_THAN", "value": 2.32, "window": "FIVE_MINUTES", } ], "envs": [ { "key": "BASE_URL", "scope": "BUILD_TIME", "type": "GENERAL", "value": "http://example.com", } ], "gitlab": { "branch": "main", "deploy_on_push": True, "repo": "digitalocean/sample-golang", }, "log_destinations": { "name": "my_log_destination", "papertrail": { "endpoint": "https://mypapertrailendpoint.com" }, "datadog": { "endpoint": "https://mydatadogendpoint.com", "api_key": "abcdefghijklmnopqrstuvwxyz0123456789", }, "logtail": { "token": "abcdefghijklmnopqrstuvwxyz0123456789" }, "open_search": { "endpoint": "https://myopensearchendpoint.com:9300" "index_name": "logs" "basic_auth": { "user": "doadmin", "password": "password" } }, }, } ], "databases": [ { "cluster_name": "cluster_name", "db_name": "my_db", "db_user": "superuser", "engine": "PG", "name": "prod-db", "production": True, "version": "12", } ], “vpc”: { “id”: “c22d8f48-4bc4-49f5-8ca0-58e7164427ac”, } } update_resp = client.apps.update(id="bb245ba", body=req) ``` ### Add a Database to an App Using the Control Panel Go to the [**Apps** page](https://cloud.digitalocean.com/apps) and select your app. Click **Add components**, then choose **Create or attach database**. ![The Add components dropdown menu showing the Create or attach database option highlighted.](https://docs.digitalocean.com/screenshots/app-platform/add-component-create-attach-DB.e92a42eb1f8f3134fb6f57d7a5dc6ae7c6cbb8541fef02cd85c5340e39645c73.png) Choose one of the following options: - **Create a new dev database**: Select a version and enter a name for the database, then click **Create Database**. Your app is automatically added as a trusted source, creating a secure connection that accepts traffic only from the app. - **Attach existing DigitalOcean database**: Select a cluster from the **Database Cluster** dropdown menu, then click **Attach Database**. - If trusted sources are enabled for the cluster, your app is automatically added as a trusted source. - If trusted sources are disabled, select **Add app as a trusted source** to allow the app to connect securely. ![The Create or attach a database screen showing the Attach existing DigitalOcean database option selected.](https://docs.digitalocean.com/screenshots/app-platform/attach-do-db.e02f4600c11a2692288d0bbf47128b11ace0b2f9e05d9215e695f95915074797.png) Alternatively, you can add an app to a database as a trusted source. Go to the [Databases page](https://cloud.digitalocean.com/databases) and select a database. Click the **Network Access** tab, then click **Add Trusted Sources**. In the **Add Trusted Sources** window, choose **Quick select Droplets, Kubernetes clusters, Apps, and tags**, then select your app. Click **Add Trusted Sources** to finish. **Note**: Enabling an app as a trusted source blocks any other connections. To allow additional connections, explicitly add them to the trusted sources list as described in the [Managed Databases documentation](https://docs.digitalocean.com/products/databases/index.html.md). ### Add a Dev Database Using the App Spec You can also add a database by specifying the database details directly in the [app’s spec file](https://docs.digitalocean.com/products/app-platform/reference/app-spec/index.html.md) and [submitting the updated spec](https://docs.digitalocean.com/products/app-platform/how-to/update-app-spec/index.html.md) via the control panel or uploading it to your app’s source repo. To add a database using the app’s spec, add the following object to the root of the spec and update the values as necessary: `app.yaml` ```yaml databases: - engine: PG name: db-example version: "16" ``` Using the spec, you can specify the database’s name and version. You cannot specify the version in the Control Panel. The currently available PostgreSQL versions are `13`, `14`, `15`, and `16`. ## Connect to a Dev Database To view your dev database’s connection string, go to the [**Apps** page](https://cloud.digitalocean.com/apps), select your app, then click the **Settings** tab. Select your database from the components at the top, then scroll to the **Connection Details** section. ![Connection details section of the Settings page.](https://docs.digitalocean.com/screenshots/app-platform/components-database-detail.88681662da7246b709e4eb13771a7b6541b38d88ef3b2d7bccf88e3b802d5ba0.png) Click the dropdown menu showing **Connection Parameters** and select **Connection String**. The full connection string for your database appears as: ``` postgresql://${db.USERNAME}:${db.PASSWORD}@${db.HOSTNAME}:${db.PORT}/${db.DATABASE} ``` The connection string is available at runtime through the `DATABASE_URL` environment variable, which combines the individual connection parameters (`db.USERNAME`, `db.PASSWORD`, `db.HOSTNAME`, and so on) into a single value. The prefix (for example, `db`) is the database’s component name, that is, the name you gave it when adding the database or the name in the app spec. You can view the `DATABASE_URL` environment variable in the **Environment Variables** section of the **Settings** page for service or worker components. ## Upgrade a Dev Database to a Managed Database You can upgrade your dev database to a [DigitalOcean Managed Database](https://docs.digitalocean.com/products/databases/postgresql/index.html.md) at any time. When you upgrade your database, we migrate the existing data to a new managed database. To upgrade your dev database, go to the [**Apps** page](https://cloud.digitalocean.com/apps), select your app, then click the **Settings** tab. Select your dev database from the components at the top, then scroll to the **Database Type & Scale** section and click **Convert to a Managed Database**. In the **Node Plan** dropdown menu, choose the size of the machines to run your database. You can click the **Standby Nodes** dropdown menu and select one or two standby nodes that stay synchronized and provide failover during downtime. When finished, click **Convert Database**. ## Upgrade Dev Database Version You can upgrade your dev database to a different version of PostgreSQL. App Platform supports PostgreSQL `13`, `14`, `15`, and `16`. To use the commands in these instructions, you need a [DigitalOcean API token](https://docs.digitalocean.com/reference/api/create-personal-access-token/index.html.md), with App Platform `read` and `write` scopes, saved as an environment variable named `DIGITALOCEAN_TOKEN` in your terminal. To upgrade a dev database, go to the [**Apps** page](https://cloud.digitalocean.com/apps), select your app, then click the **Settings** tab. On the **Settings** page, select the database you want to upgrade, then click the copy button beside the database’s UUID. ![Database UUID in the control panel](https://docs.digitalocean.com/screenshots/app-platform/app-db-uuid.1cfaa505b4b9739512193bc8173354847f41ebc51f7b60931ec3838f2f1d8340.png) Once you have copied the UUID, use the following `curl` command to first install any updates for your database, replacing the `` value with the UUID you copied from the control panel. This is a best practice to ensure a smooth upgrade: ```shell curl -X PUT \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ "https://api.digitalocean.com/v2/databases//install_update" ``` The update may take a few minutes to complete. Once the update is complete, use the following `curl` command to upgrade your database to a different version, replacing the `` value with the PostgreSQL version you want to upgrade to, and the `` value with the database’s UUID. ```shell curl -X PUT \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ -d '{"version":""}' \ "https://api.digitalocean.com/v2/databases//upgrade" ``` The upgrade may take several minutes to complete. If you receive the error `Cannot make changes while the service is undergoing maintenance`, the updates may still be installing and you can try upgrading again later. To verify that the upgrade was successful, go to your app’s **Settings** page and click **Edit** in the **App Spec** section. The database’s version is specified in the `databases` object. For example: `your-app.yaml` ```yaml databases: - engine: PG name: your-database version: "16" ``` If you want a database that offers more customization and a managed experience, we recommend [upgrading your dev database to a managed database](#upgrade-dev-database-to-managed-database). ## Integrate an Existing Kafka Database (Private Preview) You can create and integrate DigitalOcean Managed Kafka Databases with your App Platform app, but they require an additional step to configure the app’s ability to connect to the database. App Platform does not currently support connections to Kafka databases that have trusted sources enabled. You must [disable trusted sources](https://docs.digitalocean.com/products/app-platform/how-to/manage-databases/index.html.md#disable-trusted-sources) on the Kafka database before it can be integrated with an App Platform app. App Platform provides [bindable environment variables](https://docs.digitalocean.com/products/app-platform/how-to/use-environment-variables/index.html.md#using-bindable-variables-within-environment-variables) that automatically provide connection details for your Kafka database. To integrate an existing Kafka database, follow the [steps to add the database to your app](#add-a-database-to-an-app-using-the-control-panel), then add the following environment variable key value pairs to your app, replacing `your-kafka-instance-name` with your database’s component name (the name in your app spec’s `databases` array, or the name shown for the database in the app in the control panel): | Example Key | Value Format | Description | |---|---|---| | KAFKA\_BROKER | ${your-kafka-instance-name.HOSTNAME}:${your-kafka-instance-name.PORT} | The hostname and port of the database’s Kafka brokers | | KAFKA\_USERNAME | ${your-kafka-instance-name.USERNAME} | The username for authenticating with the Kafka database | | KAFKA\_PASSWORD | ${your-kafka-instance-name.PASSWORD} | The password for authenticating with the Kafka database | | KAFKA\_CA\_CERT | ${your-kafka-instance-name.CA\_CERT} | The CA certificate for TLS authentication with the Kafka database | You can pass these environment variables to the Kafka client in your app’s code to securely connect to the Kafka database. ## Disable Trusted Sources App Platform does not support connecting to managed databases with trusted sources enabled during the app’s build process. To allow your app to connect to the database during development, disable trusted sources on the database. To disable trusted sources, go to the [**Apps** page](https://cloud.digitalocean.com/apps), select your app, then click the **Settings** tab. On the **Settings** page, select your database from the components at the top, then scroll to the **Trusted Sources** section and click **Edit**. Clear the **Add app as a trusted source** checkbox, then click **Save**. ## Destroy a Database Go to the [**Apps** page](https://cloud.digitalocean.com/apps), select your app, then click the **Settings** tab. Select the database you want to destroy. At the bottom of the page, click **Destroy Database**. Enter the database’s name to confirm, then click **Destroy**.