Guides

Deploy from the command line

The same deploys from your terminal, with state and secrets on your own machine.

The launchpad command does everything the console does, from your terminal, with state and secrets kept on your own machine.

Install

Node.js 22 or newer.

npm install -g @axonscape/launchpad

Provider keys come from your shell's environment, the same names as in Providers and credentials:

export VERCEL_TOKEN=…
export NEON_API_KEY=…
launchpad doctor      # which credentials are set, and which are missing

Check it's safe to launch

In the app's folder, with no account or credentials:

launchpad launch-check                        # or, without installing: npx @axonscape/launchpad launch-check
launchpad launch-check --domain example.com   # and check the domain's email records
launchpad launch-check --json                 # the report as JSON

It's the launch check, run on your computer. It reads the files git would commit, and uploads nothing. It exits 1 when something must be fixed before launch, so it can stop a deploy in CI.

The main loop

cd ~/code/my-app
launchpad init --repo you/my-app --domain app.example.com   # writes launchpad.json
launchpad plan     # what up would create or change; fails if something is missing
launchpad up       # create, wire, deploy
launchpad check    # probe the health URLs
launchpad status   # what Launchpad manages

up is safe to re-run: each step saves its progress, so after a failure or a timeout it resumes rather than creating a second copy. Steps that need you are listed under Still to do.

Secrets

launchpad secrets set STRIPE_SECRET_KEY=sk_live_… --env production
printf %s "$TOKEN" | launchpad secrets set GITHUB_TOKEN
launchpad secrets generate SESSION_SECRET
launchpad secrets list
launchpad env --dotenv > .env.local

Starting from a template

launchpad templates
launchpad init --template saas-starter --repo you/my-saas

Templates copy nothing if a file would be overwritten or the result wouldn't be valid.

Moving an existing app onto Launchpad

Use link so up updates what exists instead of creating something new:

launchpad link hosting prj_…                                   # Vercel project
launchpad link process api srv-…                               # Render service
printf %s "$DB_PASSWORD" | launchpad link database <ref>       # Supabase project
launchpad link email <domain-id>                               # Resend domain
printf %s "$SECRET" | launchpad link botProtection <sitekey>   # Turnstile widget

Linked resources are never deleted by a teardown.

Bringing the data

An app moving off Lovable Cloud or Replit leaves its data behind. Export it from the tool, then load it into the app's new database:

launchpad db restore lovable-export.dump          # the database from this project's deploy
printf %s "$DATABASE_URL" | launchpad db restore replit.dump   # or one you name (deployed from the console)
  • It loads into an empty database only, and all in one transaction: everything goes in, or nothing does, so a failed load can be fixed and run again.
  • A Lovable Cloud export is a Supabase project's database. Launchpad loads the app's own tables, policies and functions, and its sign-in accounts, so people keep their passwords. Supabase's own parts stay as the new project has them, so the new database must be on Supabase. Files in storage, edge functions and secrets aren't in the export: set those up again.
  • A Replit database is plain Postgres. Make the dump in Replit's Shell, where the database can be reached, and download the file: pg_dump -Fc --no-owner --no-privileges "$DATABASE_URL" > replit.dump.
  • It runs PostgreSQL's own pg_restore and psql, which come with PostgreSQL's client tools (on a Mac, brew install libpq && brew link --force libpq; on Ubuntu, sudo apt install postgresql-client). The password goes to them in the environment, never on the command line.

Tearing down

launchpad down                      # lists what it would delete, and stops
launchpad down --confirm my-app     # deletes it, newest first

This deletes the database and its data. Linked resources and your own secrets are kept.

Where state lives

up writes a .launchpad/ folder next to launchpad.json, and init adds it to .gitignore:

  • state.json: resource ids only.
  • secrets.json: service variables, your secrets and generated passwords (file mode 0600). Never commit it.

Projects in the console keep both in its database instead, encrypted. If several people deploy the same app, use the console: a .launchpad folder on one laptop isn't shared.

Something missing or wrong? Edit this page on GitHub or email hello@axonscape.com.