Map App Platform services, workers, jobs, managed databases and Spaces to AWS, move the data, and cut over DNS, with Encore provisioning the AWS side from code or with ECS and Terraform by hand.
DigitalOcean App Platform describes an app in one spec: services that take HTTP traffic, workers, jobs that run before or after a deploy or on a schedule, and attached Managed Databases, with Spaces for files. Teams move to AWS for compliance, for an enterprise customer that requires it, for AWS credits, or for services App Platform does not offer. The move is mostly translation, since each component has an AWS counterpart, plus a data migration for Postgres and Spaces.
This guide maps an App Platform app to AWS component by component, covers the data move and DNS cutover, and shows two ways to build the AWS side: declare the resources in application code with Encore, or rebuild them with ECS and Terraform by hand.
The app spec is the inventory of everything that has to move, so export it before changing anything:
Each section of the spec maps to AWS like this:
Scheduled jobs in the spec carry a time_zone, while Encore cron schedules run in UTC, so convert each schedule when you move it. Bindable variables such as the App Platform database URL placeholder disappear, because the connection details on AWS come from the new database.
Encore combines an open source infrastructure SDK with a platform that provisions and deploys into your own AWS or GCP account. For TypeScript and Go it is a backend framework with built-in infrastructure: the database, buckets, workers and scheduled jobs from the app spec are declared in the code that uses them, and Encore provisions the matching AWS resources on deploy.
Run in your terminal to get started locally.
The database, the Spaces bucket, the worker and the scheduled job from a typical spec become declarations in one service:
// app/resources.ts
import { CronJob } from "encore.dev/cron";
import { api } from "encore.dev/api";
import { Subscription, Topic } from "encore.dev/pubsub";
import { SQLDatabase } from "encore.dev/storage/sqldb";
import { Bucket } from "encore.dev/storage/objects";
// Replaces the App Platform managed Postgres cluster. RDS on AWS.
export const db = new SQLDatabase("app", { migrations: "./migrations" });
// Replaces a Spaces bucket. S3 on AWS.
export const uploads = new Bucket("uploads", { versioned: false });
// Replaces a worker component that polled for work. SNS and SQS on AWS.
interface EmailJob {
userId: string;
template: string;
}
export const emails = new Topic<EmailJob>("emails", { deliveryGuarantee: "at-least-once" });
const _ = new Subscription(emails, "send-email", {
handler: async (job) => {
// send the email
},
});
// Replaces a scheduled task. Run by the Encore platform, in UTC.
export const cleanup = api({}, async (): Promise<void> => {
await db.exec`DELETE FROM sessions WHERE expires_at < now()`;
});
const nightly = new CronJob("cleanup", { title: "Delete expired sessions", schedule: "0 3 * * *", endpoint: cleanup });
The PRE_DEPLOY migration job is replaced by the migrations directory on the database, which Encore applies on every deploy. Secret variables from the spec move to secrets set with encore secret set --type prod. Non-secret variables have no direct equivalent, so values that are the same everywhere become constants in code. encore run starts Postgres locally, along with the queue and a local bucket, so the app runs on a laptop before anything is deployed.
Connect your AWS account in the Encore dashboard under Integrations > Connect Cloud, as described in Connect your cloud account, create an environment on AWS and run git push encore. Encore provisions a VPC, Fargate behind an Application Load Balancer, RDS for PostgreSQL, the S3 bucket, an SNS topic and SQS queue with a dead-letter queue for the subscription, and Secrets Manager entries, and it provisions an IAM role for the service, as listed in the AWS infrastructure docs, and cron jobs run from the Encore platform with no extra AWS resources. The App Platform app keeps serving traffic while the AWS environment comes up.
The PaaS migration guide covers the same mapping for other platforms.
Best fit: teams whose App Platform spec is mostly application resources (services, workers, Postgres, Spaces and scheduled jobs) and who want those declared in the same TypeScript or Go code on AWS.
Without Encore, each spec section becomes Terraform or CDK, starting with services as ECS services on Fargate behind an Application Load Balancer, built from the same Dockerfile and pushed to ECR. Workers are ECS services without a load balancer that poll SQS, which means adding a queue to code that previously polled a database or Redis. PRE_DEPLOY jobs become a one-off ECS task that the pipeline runs before updating the service, and SCHEDULED jobs become EventBridge Scheduler schedules that start an ECS task. Managed Postgres becomes RDS in private subnets, Spaces becomes an S3 bucket with a policy for each task role, and secrets go to Secrets Manager referenced from the task definitions. Budget for the VPC, NAT gateways, security groups and IAM roles that App Platform handled implicitly.
Best fit: teams with an infrastructure engineer and an existing Terraform codebase who want every AWS setting in their own modules.
If the managed database has trusted sources configured, add the IP of the machine doing the transfer, then dump over TLS. The host, port, database and user are under the database's Connection Details, on port 25060. Put the password in a mode 600 .pgpass file (hostname:port:database:username:password) so pg_dump and pg_restore never receive it as an argument, and create the dump with a private umask:
With Encore, the target is either the database Encore created, where you restore data only into the schema your migrations built, using encore db conn-uri app --env=prod --admin for the connection string, or an RDS instance you restored yourself and attach with Import Existing Database. Check the major version and extensions first, and run ANALYZE after the restore.
Spaces is S3-compatible, so rclone can copy between them with two remotes, one with the Spaces endpoint such as fra1.digitaloceanspaces.com and one for S3:
Code that built URLs from the Spaces CDN hostname needs the new bucket's URL, or signed URLs from the bucket API.
If an infrastructure team already owns AWS modules, map each spec section into ECS, RDS, S3 and EventBridge Scheduler with Terraform or CDK. If most of the spec is application resources you want declared next to the code that uses them, with the same setup on a laptop, Encore provisions those in your AWS account from TypeScript or Go.
Export the app spec with doctl apps spec get to list every component and environment variable, map services to containers on Fargate, workers to queue consumers, jobs to cron or deploy-time migrations, Managed Postgres to RDS and Spaces to S3. Deploy the app on AWS next to the running App Platform app, copy the data, then switch DNS once the new environment is verified.
Declare the database, buckets, Pub/Sub topics and cron jobs the app spec used in TypeScript or Go with Encore, connect your AWS account in the Encore dashboard and push. Encore provisions Fargate, RDS, S3, SNS and SQS and Secrets Manager in your account, then you restore the Postgres dump, sync Spaces to the S3 bucket and move the custom domain.
Spaces speaks the S3 API, so rclone sync or aws s3 sync with --endpoint-url pointing at the Spaces region endpoint copies the objects. Run a full sync ahead of time and a second incremental sync during the cutover, and update any code that builds Spaces CDN URLs.
A step in the deploy pipeline that runs migrations before the new version takes traffic, such as a one-off ECS task started by CI with the new image. If the task fails, the pipeline stops before the service is updated, which matches how a failing PRE_DEPLOY job blocks an App Platform deploy.
Deploy to your cloud on AWS and Google Cloud
without managing infrastructure
Encore lets developers and agents define application infrastructure directly in code, then automatically provisions it from local development to production in your AWS or GCP account.