deplaneDocs Dashboard

Moving from Netlify

Move a Netlify site to Deplane with one command, or from the dashboard (From the dashboard). deplane import netlify reads the site on Netlify and the netlify.toml in your code, and shows what moves and what stays. It then creates the Deplane app with its production variables and deploys your code. Netlify keeps serving your users until you switch.

The command runs on your own computer with your Netlify token, which never leaves it. It only reads Netlify: nothing there is changed. The command and its flags are in the CLI reference, and every error has a fix in Troubleshooting and error codes. It works like Moving from Heroku.

From the dashboard

New app → Import from another platform (/import, or /import/netlify with Netlify already picked) does the same import without the CLI or a folder, in five steps:

  1. Connect. Create a personal access token in Netlify (User settings → Applications → Personal access tokens → New access token) with a short expiration, paste it into the masked field and press Read. Netlify has no read-only tokens: the token can change everything your account can. Deplane only reads with it (GET requests), inside the request that carries it, and never stores it. Delete the token in the same place when the import is done.
  2. Pick. The page lists the sites the token can see (at most 100, with a filter box). Pick the one to import, or type its name or ID. A link /import/netlify?ref=NAME fills it in, and a token that sees exactly one site checks it at once. Picking runs the check: the report, nothing created.
  3. Review. The same ✓ / ⚠ / ✗ report as --check, with the Plan section. There is no netlify.toml here: the build settings come from the site. Then Code and name, filled in: the repository and branch Netlify builds, preselected when the repository is among the ones you gave the Deplane GitHub App access to (the match is made only inside your own grants; otherwise the page shows the repository's name and a Connect GitHub link that brings you back), with the commit of the published deploy when the repository has it. The Deplane app's name is the site's, made a Deplane name, with a suffix when a team already holds it. Import asks for your passkey.
  4. Import. The page follows each step (the app with the production variables Netlify returns, as secrets and as build secrets), lists what exists so far, then stops at Set secrets when the site has secret variables.
  5. Set secrets. Netlify gives the values of secret variables only to code running on Netlify (see Secret variables), so the import waits here, as long as it takes, with one masked field per name the report listed. Take the values from where you keep them, fill them in, and press Set secrets: they go straight to the app's secrets, never through the import. Then Deploy connects the repository and builds, and ends with the live address, the switch-over checklist and the reminder to delete the token. A waiting import does not block your team's next import, and Cancel import ends it.

A failed or cancelled import has Delete what it created: the app this import made, nothing else, after your passkey. Then import again. The rest is as for Heroku's From the dashboard: the code comes from GitHub (previews off), the token is used inside the requests that list, check and start the import and dropped, only you signed in to the dashboard can do it, and a team runs one import at a time.

Before you start

  1. Install the Deplane CLI and run deplane login.
  2. Have the site's code in a folder: a checkout of the repository Netlify builds, at the commit it runs. If Netlify builds a subfolder (its Base directory), pass that folder with --source.
  3. Create a personal access token in Netlify: User settings → Applications → Personal access tokens → New access token, with a short expiration.

The Netlify token. A personal access token can do everything your account can; there are no read-only tokens. The CLI only reads with it (GET requests to api.netlify.com). Delete it when the import is done.

Give the token to Deplane in one of three ways, never as a flag:

A token piped on stdin wins over NETLIFY_AUTH_TOKEN. The CLI says which one it used, never the token itself. It is never written to disk, never printed, left out of --debug, and never sent to Deplane.

Secret variables

Netlify gives the values of secret variables only to code running on Netlify: the dashboard, API and CLI show none of them, except a local development value. The import lists them by name, copies the others, and creates the app without deploying it, since it would start without them. The next steps show what to set before you deploy:

deplane secrets set API_KEY=... --app my-site
deplane secrets set --build API_KEY=... --app my-site   # if the build reads it
cd my-site && deplane launch --app my-site   # deploys the app and writes deplane.toml

Variables shared by your Netlify team (Team settings → Environment variables) may not be listed for the site: check them there, and set the ones the site needs.

Check first

$ deplane import netlify shop --check
Netlify site shop (framework astro, team acme, repo github.com/acme/shop@main, commit 1a2b3c4) → Deplane app shop

Code
  ✓ Deploys /home/me/shop with Railpack: Detected Astro 5, Node 22, port 8080.
  ✓ Your folder is at commit 1a2b3c4, the one Netlify runs.
  ⚠ Netlify builds with `npm run build` and publishes dist. Railpack detects the build itself ...
  ⚠ Netlify applies 2 redirect rule(s) (_redirects, netlify.toml) and 0 header rule(s) itself; Deplane does not. ...
  ⚠ Netlify serves the site from its global CDN; Deplane serves it from one region, in Europe. ...

Processes
  ✓ web: Netlify serves the site from its CDN → 1 small instance. Set more with `deplane scale`.

Config vars
  ✓ 2 copied as secrets: PUBLIC_API_URL, SITE_ENV.
  ✓ 2 also set as build secrets, since Netlify gives them to the build ...

Domains
  ⚠ www.shop.example points at Netlify (shop.netlify.app). It moves when you switch ...

Plan
  ✓ Fits your Free plan: after the import the team uses 1 of 2 instances and 512 MB of 1 GB memory.

Nothing was changed (--check). Run the command again without --check to import.

✓ is what moves as it is, ⚠ is what you should know or do yourself, and ✗ is what stops the import. --check --json prints the same report as one JSON document. Then run the command again without --check (in a terminal it asks first; from a script, add --yes).

What moves

On NetlifyOn Deplane
A static site (Astro, Vite, Hugo, Eleventy, Gatsby ...)An app that Railpack builds and serves as files.
A Next.js siteAn app that Railpack builds and runs with next start.
Production variables (the production value, else the one for all contexts)Secrets. Those Netlify gives to builds are build secrets too, since a static site's variables are built into its files. netlify.toml's [build.environment] and [context.production.environment] apply to builds only, so they become build secrets only (over the site's value for the build). Not copied: Netlify's own variables, and variables without a production value.
Secret variablesListed by name, not copied: see Secret variables.
The custom domain and domain aliasesListed, and moved at the switch. *.netlify.app stays with Netlify.
Databases you connected (Netlify DB, Neon, Supabase ...)Their URLs are copied as they are, and the site keeps using them. To move a Postgres database later, use deplane db import.
The codeYour folder, built by Railpack, or by your Dockerfile if it has one.

Instances: Netlify has none to map. The app starts with one small instance (0.5 CPU, 512 MB).

What does not move

Switch over

  1. Set the secret variables and deploy, if the import listed any. Test the app at its Deplane address.
  2. Before the day: run deplane domains add HOSTNAME --app APP for each custom domain and add the TXT record it shows.
  3. Switch DNS to the target deplane domains add showed, and wait for the certificate (deplane domains check HOSTNAME --app APP).
  4. Remove the domains from the Netlify site, and delete it once the app has run well on Deplane.
  5. Delete the Netlify token in User settings → Applications.

Limits

The Heroku import's limits apply. Secret variables, functions and forms are not moved. The import is built on Netlify's public API; tell support@deplane.io if Netlify answers something the CLI does not expect.

This page is also available as Markdown. AI agents can start at /llms.txt.