Move apps from another platform
Move apps one at a time from your old platform to launchroom without downtime. Variables, Compose apps, databases and files, then the DNS switch. Umami as the worked example.
You move one app at a time. Your old platform keeps serving each app until you switch its DNS, so the app stays online the whole time. For every app:
- Deploy it on launchroom.
- Copy its variables.
- Import its database and files.
- Check it on its generated address.
- Switch DNS.
- Remove it from your old platform.
The examples move Umami (website analytics on PostgreSQL). The same steps work for any app with a PostgreSQL, MySQL or MongoDB database and files on disk.
Before you start
- Install launchroom on a server.
- Lower the DNS TTL of every domain you'll move to 300 seconds or less, at least as long before the switch as the current TTL (often 1 hour or 1 day). Resolvers then pick up the switch within minutes, and you can switch back as fast.
- Keep shell access to your old server. The commands below run there with
docker exec.
Deploy the app
How depends on how it runs on your old platform:
- A common app such as Umami: open New project, choose Template and pick it. The Umami template adds Umami and a managed PostgreSQL 17 database, connects them, generates
APP_SECRETand deploys. - A
docker-compose.yml: import the Compose file. Well-known database images become managed databases, so you can import their data in the next steps. - Your own code: import the repository. launchroom detects how to build it.
Pick the same database engine and the same or a newer major version as on your old platform: a dump only imports into the same or a newer version.
On its first start, Umami creates its tables. That's expected: the import replaces them.
Copy the variables
Write the app's variables to a .env file on your old server:
docker exec umami env > umami.envRemove what launchroom sets itself: PATH, HOSTNAME, HOME, the database's address and credentials (DATABASE_URL, DB_HOST and similar come from the connection), and anything the image sets itself (NODE_VERSION and similar).
Open the service's Variables tab and paste the file or choose Import .env. launchroom shows a preview with conflicts and suggests which values to keep as secrets. Deploy to apply them. From a terminal, launchroom env set KEY=VALUE… adds variables (staged) and launchroom deploy --staged applies them.
Umami's secrets
Umami 3.4 reads one secret, APP_SECRET. When it isn't set, Umami derives it from DATABASE_URL. It signs sign-in tokens, share links and the tracker's cache tokens, and it is part of how Umami hashes visitor sessions. The data doesn't depend on it, but with a new secret everyone signs in again, shared links stop working and visitors in the current month count as new sessions. Copy these from your old server when they are set:
APP_SECRETTWO_FACTOR_ENCRYPTION_KEY: Umami encrypts two-factor secrets with it. Without it, users with two-factor sign-in can't sign in.SALT_ROTATION, if you changed it.
If your old app had no APP_SECRET, its secret came from its old DATABASE_URL. Keep the generated one; everyone signs in once more. Older Umami versions used HASH_SALT. Umami 3.4 doesn't read it.
Umami 1.x
Umami 2 changed the database schema. If your old platform runs Umami 1, upgrade it there with Umami's v1 to v2 migration before you dump the database.
Import the database
Find the database container and its user and database name:
docker ps --format '{{.Names}}\t{{.Image}}'
docker exec umami-db env | grep -E '^(POSTGRES|MYSQL|MONGO)'Dump it with the engine's own tool. The dump streams to a file on your old server:
# PostgreSQL: custom format, compressed
docker exec umami-db pg_dump -Fc -U umami umami > umami.dump
# MySQL or MariaDB (password from the container's env)
docker exec shop-db sh -c 'exec mysqldump --single-transaction --routines --triggers -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" "$MYSQL_DATABASE"' | gzip > shop.sql.gz
# MongoDB
docker exec chat-db mongodump --archive --gzip --db chat -u app -p '<password>' --authenticationDatabase admin > chat.archiveTo dump inside the container instead, write to /tmp and copy it out: docker exec umami-db pg_dump -Fc -U umami -f /tmp/umami.dump umami, then docker cp umami-db:/tmp/umami.dump .. Copy the dump to the machine you upload from, for example with scp.
On launchroom, open the database on the canvas and go to Backups → Move data → Import data…. Drop the dump in. The upload resumes if your connection drops. launchroom shows what it found ("PostgreSQL custom dump · from PostgreSQL 15.8") and what the database holds now.
Umami already created its tables, so choose Replace everything. launchroom takes a safety snapshot, stops Umami, drops and recreates the database, imports the dump and starts Umami again. Type the database's name to confirm.
From a terminal, with a token that has the data:transfer ability:
launchroom db import postgres umami.dump --replaceWhen the old database is reachable from the internet, From a connection URL copies it directly without a dump file. See Import and export for formats, version rules and what launchroom adjusts in a dump.
Import files
If the app keeps uploads or other files on disk, add a volume at the same path on the service (Settings → Volumes) and deploy. Then pack the folder on your old server:
docker exec app tar -czf - -C /app/uploads . > uploads.tar.gzIn the service's Backups tab, choose Import files… next to the volume and upload uploads.tar.gz. Owners and modes from the archive are kept, or set one owner for all files if the image runs as a non-root user. See Import files into a volume.
Check the app
Open the app on its generated address. For Umami: sign in with your old account and check that your websites and their history are there. Check the service's logs for errors.
Switch DNS
Add your domain to the service and point its DNS record at launchroom. launchroom issues a certificate once the record resolves. With a low TTL, traffic moves within minutes. The Umami tracking script on your sites keeps working because the domain stays the same.
Requests that reach your old platform between the dump and the switch stay there. To move without that gap, stop the app on your old platform, take a fresh dump, import it again with Replace everything and switch DNS right after.
Clean up
Once traffic reaches launchroom (check the service's metrics) and you're sure:
- Stop the app on your old platform, and keep its last dump until launchroom has taken its first scheduled backups.
- Raise the DNS TTL again.
- Remove
umami.envand the dump files from your machines: they hold secrets and data.
Next steps
Moving to launchroom
Move your apps from your old platform onto a launchroom server one at a time, later move launchroom to another machine, and add a home machine for builds.
Move launchroom to a new server
Move launchroom with every app, database, volume and domain from one machine to another without losing data, also to another CPU architecture. No backup storage needed.