From the team behind aidrop.it — one workspace to build, host, and keep changing your code.

Move a VPS-hosted app by reproducing its runtime, proving one complete workflow on the new host, and planning the data handover before changing DNS. Keep the old server available until the new deployment passes its checks. A working homepage proves very little if uploads, scheduled tasks, or database writes still depend on the VPS.

This walkthrough uses a planned maintenance window for an app with a database. It does not promise uninterrupted service. Start with the existing-app takeover checklist if the repository differs from what the server actually runs.

1. Inventory everything the VPS does

Inventory the running server before building its replacement. Include the active start command, proxy rules, cron entries, and storage paths: a Git repository rarely describes everything the VPS does.

Record the deployed commit, dependencies, environment variable names, port, database version, uploads, workers, jobs, and webhooks. Map each to a destination. Back up data and prove you can restore it. Keep secret values out of this inventory.

On aidrop.it, the application filesystem is read-only except for temporary scratch paths. Move durable files to suitable storage. Check database connectivity early: outbound access uses an HTTP/HTTPS proxy, so a normal PostgreSQL connection to a public VPS on port 5432 is not a supported shortcut. Use an attached managed database in the same Project, or a compatible provider's HTTPS API with a client designed for it.

2. Build a test deployment with isolated data

Package the app in a Dockerfile and build it in the destination Project using a restored test dataset. The first successful deployment has a public URL; protect private routes with authentication before exposing sensitive data.

Connect your coding agent through the quickstart. Store runtime values as Project secrets, select their names in required_secret_names, and build with service_build. Attach managed resources separately from storing their connection strings. Inspect failures through service_logs and fix one cause at a time.

Rehearse the database transfer through a route available to your tooling and network; do not assume the running Service can reach the old database. Measure the final export and import time. Check login, a read, a write, an upload, and any background job. Disable real emails, payments, and production webhooks during the rehearsal. Check that the migration landed gives a concrete persistence check.

3. Transfer data, then switch the domain

Use a maintenance window to establish one authoritative writer. Stop writes and background consumers on the old deployment, transfer the final data changes, and verify the destination before reopening writes. Keep the old host in maintenance mode while cached DNS answers can still direct requests there. Otherwise two live copies may accept conflicting records.

Plan the production hostname through service_domain_add, available on Pro and above. Save the old DNS configuration and apply the exact record returned by the tool during cutover. Run service_domain_verify after traffic reaches the new endpoint. Successful verification enables the name and orders its certificate; test HTTPS externally before treating the switch as complete.

Check callbacks, webhooks, cookies, redirects, and assets on the real domain. Resume each job and consumer once. Verify a transaction and watch errors before ending maintenance. Retain recovery copies for the agreed period.

4. Make rollback include new writes

A rollback plan needs to account for every record accepted after cutover. Before the destination accepts writes, returning traffic to the unchanged old app may be straightforward. Afterward, restoring the old server without reconciling the new data can lose transactions. Define the recovery procedure and responsible person before opening the new deployment.

Keep the previous application revision available and make schema changes compatible with it where possible. If the cutover fails after writes resume, pause writes again and decide whether to repair the new deployment or transfer the new records back. A code-image rollback does not restore a database or uploaded files.

Copy this VPS cutover sheet

Complete this sheet during rehearsal. Another operator should be able to identify the active writer and execute recovery from these instructions. Replace every placeholder before scheduling the window.

App / commit: <name, sha>       Cutover owner: <person>
Old host / new URL: <addresses>
Database and media transfer procedure: <tested instructions>
Measured transfer time / maintenance window: <durations>
Background jobs and webhook consumers: <list, destination>
Old DNS records / new records: <saved values>

[ ] Rehearsal passes login, read, write, upload, and job checks.
[ ] Old writers and consumers stop; final data transfer completes.
[ ] Destination data is verified before writes reopen.
[ ] Domain verification and external HTTPS check pass.
[ ] Real-domain callbacks and redirects work.
[ ] Exactly one set of jobs and consumers resumes.
[ ] Old host stays in maintenance while stale traffic arrives.

Rollback trigger: <specific failure and decision deadline>
Before new writes: <traffic and process reversal steps>
After new writes: <freeze, reconcile data, verify, then reroute>
Old host retirement: <checks, owner, retention date>

FAQ

Can I keep the database on my VPS? Check the destination's network model first. A conventional database connection needs a supported network path; an HTTP proxy alone cannot carry an ordinary PostgreSQL connection.

Does aidrop.it copy my server automatically? No. Your agent prepares the repository, runtime configuration, resource attachments, and data transfer. The build runs your application image; it does not reproduce arbitrary VPS services or files.

Is changing DNS enough to roll back? Only when the data and process state still allow it. Once the new deployment accepts writes, account for those records before returning users to the old database.

A codebase that already exists

Bring a project that has history

Connect the repository you already have. aidrop reads its current revision, names the blockers instead of working around them, and builds the record the next person or agent needs. A project with history is not two clicks, and it is not sold as one.