{
  "manifest_version": "1",
  "slug": "migrate-lovable",
  "title": "Apps from Lovable",
  "headline": "Move a Lovable app and its data to exe.dev",
  "description": "Move a Lovable app off Lovable Cloud to an exe.dev VM: its TanStack Start server, and Supabase with your database, users, and files.",
  "category": "migration",
  "tags": [
    "lovable",
    "lovable cloud",
    "export lovable",
    "self-host lovable",
    "lovable hosting",
    "tanstack start",
    "supabase",
    "self-hosted supabase",
    "github"
  ],
  "url": "https://exe.dev/deploy/migrate-lovable",
  "markdown_url": "https://exe.dev/deploy/migrate-lovable.md",
  "upstream": {
    "website": "https://lovable.dev",
    "source": "https://github.com/supabase/supabase/tree/master/docker",
    "docs": "https://docs.lovable.dev/tips-tricks/external-deployment-hosting",
    "license": "Proprietary (Lovable); Apache-2.0 (Supabase); your app's code is yours"
  },
  "example_vm_name": "my-lovable",
  "time": "30 minutes",
  "stack": [
    {
      "name": "Caddy",
      "detail": "The front door on port 8000; Supabase's APIs and the app at one address",
      "port": 8000
    },
    {
      "name": "Your Lovable app",
      "detail": "TanStack Start's Node.js server, built from GitHub, as app.service",
      "port": 3000,
      "data": "~/app → the current release in ~/releases"
    },
    {
      "name": "Supabase",
      "detail": "Database, sign-in, storage, and realtime in Docker, in place of Lovable Cloud; Studio on port 8001",
      "port": 8001,
      "data": "~/supabase/volumes; its settings and keys in ~/supabase/.env"
    },
    {
      "name": "Node.js 24 and Bun",
      "detail": "Bun installs from Lovable's bun.lock; Node.js builds and runs"
    },
    {
      "name": "Deploys and backups",
      "detail": "app-deploy.timer builds each new commit and applies its migrations; app-backup.timer saves the database and files nightly",
      "data": "~/app.git, ~/backups"
    }
  ],
  "access": [
    {
      "url": "https://my-lovable.exe.xyz/",
      "who": "private",
      "what": "Your app, until you make it public"
    },
    {
      "url": "https://my-lovable.exe.xyz:8001/",
      "who": "private",
      "what": "Supabase Studio, behind a password as well"
    }
  ],
  "inputs": [
    {
      "name": "REPO",
      "description": "the GitHub repository Lovable syncs your project to, as owner/name (Lovable shows it under Project settings → Git → GitHub)"
    }
  ],
  "delivers": [
    "Supabase running in Docker in `~/supabase` with keys of its own, restarting after a reboot, and Caddy on port 8000 serving its APIs and the app at https://my-lovable.exe.xyz/.",
    "`~/app.git` cloned through the GitHub integration, and `~/bin/app-deploy` building the newest commit as a Node.js server, applying new files in `supabase/migrations`, switching over, and keeping the previous release if anything fails; `app-deploy.timer` runs it every minute.",
    "The app answering on port 8000 as `app.service`, on a database with the app's tables and no data yet.",
    "`~/bin/app-restore`, as published with the recipe, ready to load a Lovable Cloud export; `~/bin/app-backup` with `app-backup.timer` enabled, and a first backup in `~/backups`.",
    "The output of `~/bin/app-check`, saying what in this app still depends on Lovable."
  ],
  "deployable": true,
  "deploy": {
    "new_vm_url": "https://exe.dev/new?prompt=REPO%3D%3Cfill-this-in%3E%0A%0ASet%20up%20Apps%20from%20Lovable%20on%20this%20VM%20by%20following%20the%20exe.dev%20recipe%20at%20https%3A%2F%2Fexe.dev%2Fdeploy%2Fmigrate-lovable.md%20from%20top%20to%20bottom.%0A%0AThe%20values%20at%20the%20top%20of%20this%20message%20are%20mine%3A%0A-%20REPO%3A%20the%20GitHub%20repository%20Lovable%20syncs%20your%20project%20to%2C%20as%20owner%2Fname%20%28Lovable%20shows%20it%20under%20Project%20settings%20%E2%86%92%20Git%20%E2%86%92%20GitHub%29%0AAsk%20me%20for%20any%20that%20still%20say%20%3Cfill-this-in%3E%20before%20you%20need%20them.%0A%0AThe%20recipe%27s%20example%20VM%20name%20is%20my-lovable.%20This%20VM%27s%20name%20is%20the%20output%20of%20%60hostname%60%3A%20use%20it%20wherever%20the%20recipe%20writes%20my-lovable.%20Skip%20the%20step%20that%20creates%20the%20VM%3B%20you%20are%20on%20it.%0A%0AYou%20are%20done%20when%20all%20of%20these%20are%20true.%20Check%20each%20one%20yourself%3A%0A-%20Supabase%20running%20in%20Docker%20in%20%60~%2Fsupabase%60%20with%20keys%20of%20its%20own%2C%20restarting%20after%20a%20reboot%2C%20and%20Caddy%20on%20port%208000%20serving%20its%20APIs%20and%20the%20app%20at%20https%3A%2F%2Fmy-lovable.exe.xyz%2F.%0A-%20%60~%2Fapp.git%60%20cloned%20through%20the%20GitHub%20integration%2C%20and%20%60~%2Fbin%2Fapp-deploy%60%20building%20the%20newest%20commit%20as%20a%20Node.js%20server%2C%20applying%20new%20files%20in%20%60supabase%2Fmigrations%60%2C%20switching%20over%2C%20and%20keeping%20the%20previous%20release%20if%20anything%20fails%3B%20%60app-deploy.timer%60%20runs%20it%20every%20minute.%0A-%20The%20app%20answering%20on%20port%208000%20as%20%60app.service%60%2C%20on%20a%20database%20with%20the%20app%27s%20tables%20and%20no%20data%20yet.%0A-%20%60~%2Fbin%2Fapp-restore%60%2C%20as%20published%20with%20the%20recipe%2C%20ready%20to%20load%20a%20Lovable%20Cloud%20export%3B%20%60~%2Fbin%2Fapp-backup%60%20with%20%60app-backup.timer%60%20enabled%2C%20and%20a%20first%20backup%20in%20%60~%2Fbackups%60.%0A-%20The%20output%20of%20%60~%2Fbin%2Fapp-check%60%2C%20saying%20what%20in%20this%20app%20still%20depends%20on%20Lovable.%0A%0ARead%20the%20whole%20recipe%2C%20including%20the%20closed%20details.%20Follow%20%22Set%20up%20by%0Ahand%22%20from%20%22Install%20Node.js%2C%20Bun%2C%20Caddy%2C%20and%20PostgreSQL%27s%20tools%22%20to%20the%0Aend%20of%20it%2C%20as%20exedev%3B%20the%20walkthrough%20above%20it%20is%20for%20the%20owner%0Aafterwards.%20Do%20not%20run%20%22Move%20to%20a%20new%20VM%22%20or%20%22Update%22%2C%20do%20not%20reboot%2C%0Aand%20leave%20public%20sharing%20off.%20The%20scripts%20and%20units%20were%20tested%20as%0Awritten%3A%20use%20them%20unchanged%2C%20check%20that%20yours%20match%20the%20recipe%2C%20and%0Aleave%20no%20test%20files%20behind.%0AREPO%20is%20a%20GitHub%20repository%3B%20turn%20a%20URL%20into%20owner%2Fname.%20Clone%20it%0Athrough%20the%20GitHub%20integration.%20If%20that%20fails%20with%20%22not%20found%22%20or%20a%20403%2C%0Aand%20https%3A%2F%2Fgithub.com%2FOWNER%2FNAME%20is%20public%2C%20clone%20that%20instead%3B%0Aotherwise%20give%20the%20owner%20the%20integration%20command%20from%20%22Get%20the%20code%22%2C%0Awith%20this%20VM%27s%20name%2C%20and%20wait%20for%20them.%20Install%20everything%20else%20meanwhile.%0ANever%20commit%20or%20push%20to%20the%20repository%3A%20Lovable%20writes%20to%20it.%0AIf%20the%20first%20deploy%20stops%20because%20this%20isn%27t%20a%20TanStack%20Start%20app%2C%20say%0Aso%20and%20point%20the%20owner%20to%20the%20FAQ%20on%20older%20apps%3B%20leave%20the%20rest%20set%20up.%0ADon%27t%20wait%20for%20the%20Lovable%20export%3A%20the%20owner%20downloads%20it.%20Don%27t%20run%0Aapp-restore%20until%20they%20ask%20you%20to.%0AKeep%20keys%20and%20passwords%20out%20of%20your%20replies%3B%20say%20which%20file%20holds%20them.%0AIn%20your%20report%2C%20say%20what%20~%2Fbin%2Fapp-check%20found%2C%20in%20plain%20words%2C%20with%20the%0Asection%20of%20this%20recipe%20that%20deals%20with%20each%20item.%20Then%20give%20the%20owner%0Athe%20next%20step%3A%20export%20from%20Lovable%20as%20%22Bring%20your%20data%20over%22%20says%2C%20the%0Ascp%20command%20with%20this%20VM%27s%20name%2C%20and%20to%20ask%20you%20to%20restore%20it.%0A%0AFinish%20with%20the%20URLs%20I%20should%20open.%0A",
    "terminal": "curl -fsSL https://exe.dev/deploy/migrate-lovable/prompt.txt | ssh exe.dev new --prompt=/dev/stdin",
    "prompt": "REPO=\u003cfill-this-in\u003e\n\nSet up Apps from Lovable on this VM by following the exe.dev recipe at https://exe.dev/deploy/migrate-lovable.md from top to bottom.\n\nThe values at the top of this message are mine:\n- REPO: the GitHub repository Lovable syncs your project to, as owner/name (Lovable shows it under Project settings → Git → GitHub)\nAsk me for any that still say \u003cfill-this-in\u003e before you need them.\n\nThe recipe's example VM name is my-lovable. This VM's name is the output of `hostname`: use it wherever the recipe writes my-lovable. Skip the step that creates the VM; you are on it.\n\nYou are done when all of these are true. Check each one yourself:\n- Supabase running in Docker in `~/supabase` with keys of its own, restarting after a reboot, and Caddy on port 8000 serving its APIs and the app at https://my-lovable.exe.xyz/.\n- `~/app.git` cloned through the GitHub integration, and `~/bin/app-deploy` building the newest commit as a Node.js server, applying new files in `supabase/migrations`, switching over, and keeping the previous release if anything fails; `app-deploy.timer` runs it every minute.\n- The app answering on port 8000 as `app.service`, on a database with the app's tables and no data yet.\n- `~/bin/app-restore`, as published with the recipe, ready to load a Lovable Cloud export; `~/bin/app-backup` with `app-backup.timer` enabled, and a first backup in `~/backups`.\n- The output of `~/bin/app-check`, saying what in this app still depends on Lovable.\n\nRead the whole recipe, including the closed details. Follow \"Set up by\nhand\" from \"Install Node.js, Bun, Caddy, and PostgreSQL's tools\" to the\nend of it, as exedev; the walkthrough above it is for the owner\nafterwards. Do not run \"Move to a new VM\" or \"Update\", do not reboot,\nand leave public sharing off. The scripts and units were tested as\nwritten: use them unchanged, check that yours match the recipe, and\nleave no test files behind.\nREPO is a GitHub repository; turn a URL into owner/name. Clone it\nthrough the GitHub integration. If that fails with \"not found\" or a 403,\nand https://github.com/OWNER/NAME is public, clone that instead;\notherwise give the owner the integration command from \"Get the code\",\nwith this VM's name, and wait for them. Install everything else meanwhile.\nNever commit or push to the repository: Lovable writes to it.\nIf the first deploy stops because this isn't a TanStack Start app, say\nso and point the owner to the FAQ on older apps; leave the rest set up.\nDon't wait for the Lovable export: the owner downloads it. Don't run\napp-restore until they ask you to.\nKeep keys and passwords out of your replies; say which file holds them.\nIn your report, say what ~/bin/app-check found, in plain words, with the\nsection of this recipe that deals with each item. Then give the owner\nthe next step: export from Lovable as \"Bring your data over\" says, the\nscp command with this VM's name, and to ask you to restore it.\n\nFinish with the URLs I should open.\n",
    "prompt_url": "https://exe.dev/deploy/migrate-lovable/prompt.txt"
  },
  "updated": "2026-10-22",
  "related": [
    "nextjs",
    "postgres",
    "dev-test-prod",
    "migrate-heroku",
    "migrate-digitalocean-droplet",
    "migrate-durable-objects"
  ],
  "alternatives": [
    "Lovable Cloud"
  ],
  "files": [
    "https://exe.dev/deploy/migrate-lovable/app-restore"
  ]
}
