This guide moves an existing installation to another machine: changing hosting provider, going from a local server to a VPS, replacing a machine at the end of its life. Every step says what you should see, and why it matters.
The one thing to remember. Take the whole data folder with you, master key included. Then the license has nothing to reactivate, the phones reconnect by themselves if the address does not change, and the migration costs a few minutes. Without the master key, it still works, but every phone must be paired again and the license key entered again.
1. What decides how smooth the migration is
Two things, and only two:
| What | If it is kept | If it changes |
|---|---|---|
The master key (secret.key, in the data folder) |
Phones, webhook secrets and license key stay readable; the license sees the same machine | Every phone must be paired again, webhook secrets regenerated, license key entered again; the license sees a new machine |
The public address (your domain, or <name>.local) |
Phones reconnect on their own | Every phone must be paired again (the address is in their QR code) |
The IP address, the hardware, the operating system and the hosting provider play no part. With the provided installation, the machine identity seen by our license server follows the master key: take it along, and for us it is the same machine.
| Your situation | Phones | License |
|---|---|---|
| Full archive moved, same domain | Reconnect on their own | Nothing to do |
| Full archive moved, address changed (new domain, local to domain...) | Pair again | Nothing to do |
| Database only, without the master key | Pair again | Free the old machine, enter the key again (section 5) |
2. What never breaks
- Your service does not stop because of the license. Our license server being unreachable, or seeing a new machine, never suspends sending. At worst, the License screen shows a renewal pending. Only a license withdrawn by us (for example after a refund) suspends sending.
- After twelve months of ownership, the license no longer needs to contact us at all.
- Your data stays readable and exportable in every case.
3. Before you start
| Check | Why |
|---|---|
| The new machine meets the requirements | Same needs as a first installation |
You know the version of the old gateway (version in https://<address>/health) |
The new one must be the same or newer: a backup made by a newer version is refused |
| Domain mode: lower the TTL of your DNS record a day before, if your registrar allows it | The switch to the new IP address then spreads in minutes |
| Pending messages are few (Queue screen) | Messages sent after the last backup would stay on the old machine |
4. Route A: move the full archive (recommended)
This route keeps everything: history, accounts, settings, phones, license.
Step 1: back up, then stop the old gateway
On the old machine:
sudo sms-gateway backup
sudo sms-gateway stop
backup writes sms-gateway-backup-<date>.tar.gz to the current folder; stop then stops the
gateway for good, so that nothing new is written on the old machine after the copy. While no gateway
answers, phones keep outgoing and incoming messages in their queue.
Check that the archive contains the master key:
tar tzf sms-gateway-backup-*.tar.gz | grep secret.key
If secret.key is not listed, stop: you would be on route B without knowing it.
On Windows, see Backup and restore for the equivalent commands.
Step 2: copy the archive to the new machine
scp sms-gateway-backup-20260901-023000.tar.gz user@new-machine:~/
The archive contains all your data and the master key: transfer it only over an encrypted channel
(scp, sftp), and delete the copies once the migration is checked.
Step 3: point the domain at the new machine (domain mode)
Change the A record of your domain to the IP address of the new machine. Keep the same domain:
the phones will find the new machine by themselves.
Step 4: install the gateway on the new machine
Run the usual installation, with the same mode as before:
curl -fsSL https://sms-gateway.araylab.com/install.sh | sudo bash -s -- --domain sms.example.com --yes
(or --lan for a local server; in that case, give the new machine the same name as the old one,
see Local server).
Do not create an account on the screen that appears: your accounts come back with the archive. If the DNS has not switched yet, the script warns you; the certificate is obtained automatically once it has.
Step 5: put the archive in place
On the new machine, in the folder where the archive is:
sudo sms-gateway stop
docker run --rm -v sms-gateway_gateway-data:/data -v "$PWD:/in" alpine:3 sh -c '
rm -rf /data/* &&
tar xzf /in/sms-gateway-backup-20260901-023000.tar.gz -C /data'
sudo sms-gateway start
This replaces the empty data of the fresh installation with yours, master key included. If the
volume name is different on your machine (older installation), find it with
docker volume ls --filter label=com.docker.compose.volume=gateway-data.
Step 6: check
Go through section 8. Phones reconnect within a minute or two, and hand over the messages they kept.
5. Route B: only a database copy
Use this route when the old machine is lost and you only have a database copy: a backup downloaded
from Settings > Backup and export, or a .db file. It brings back your history, contacts and
settings, but not the master key.
- Install the gateway on the new machine (same or newer version than the copy), in the mode you want. You can create the first account: the copy will replace it.
- Put the copy in the backups folder and restore it, as described in
Restore a copy made on another machine,
then restart with
sudo sms-gateway restart. Sign in with the accounts of the copy. - The license: the old machine still holds it, so entering your key directly is refused with a message saying the key is already in use on another machine (the dashboard may title it as a withdrawn key: it is not, and nothing is suspended). Free it first: in your customer area, click Regenerate key. This detaches every machine from the license and gives you a new key. Enter that new key in License.
- Pair every phone again (section 7).
- Webhooks: their secrets can no longer be read. Give each webhook a new secret through the API
(
PATCH /api/v1/webhooks/{id}with a newsecret) and update it on the receiving side. See Webhooks.
If you do still have the old secret.key, you can avoid steps 3 to 5: use route A's step 5 with
a full archive, or ask us for help.
6. The license after the move
With route A, there is nothing to do: the new machine presents the same identity as the old one. The License screen shows Licence active.
If the license sees a new machine (route B, or a customized installation that changed the container name or data folder), here is what you see, and none of it stops sending:
| When | Status shown on License | What it means |
|---|---|---|
| Right after the move | Licence active | The gateway still holds a valid activation |
| Later, when renewal is due | Local token due for renewal | Renewal is refused for this machine; it retries on its own |
| After a long while | Renewal pending for a while | Still nothing suspended. The message disappears at the next successful renewal |
The Check log shows these attempts with a signed refusal for a different machine. To solve it, free the license with Regenerate key in your customer area, then enter the new key in License, and click Check now. Details in License.
Do this at the end of the migration, once you are sure you keep the new machine: regenerating the key also prevents the old machine from renewing, which makes rolling back more work.
7. The paired phones
A phone remembers the address of its QR code, its identity and its secret. The gateway cannot push a new address to it.
| Situation | What to do |
|---|---|
| Same address, master key moved | Nothing. Phones reconnect on their own |
| The address changes | Pair every phone again |
| The master key was not moved | Pair every phone again, even at the same address |
To pair a phone again:
- Let it hand over its pending messages first if it can still reach a gateway: Unpair deletes the messages still queued on the phone.
- In the app, Unpair, then confirm.
- In the dashboard, Devices > Pair a device, and scan the new QR code (valid five minutes).
Then check the daily quota and settings of each SIM in Devices: see Devices.
If a phone does not reconnect although nothing should have changed, first check the address: open
https://<your address>/health in the phone's browser. Only then consider pairing again.
8. Check after the migration
| To check | How | Expected |
|---|---|---|
| The gateway runs | sms-gateway status, then https://<address>/health |
{"status":"ok","version":"..."} |
| The database is open | https://<address>/ready |
{"status":"ready","schemaVersion":N} |
| The version | version in /health |
The same as the old one, or newer |
| Your history | Conversations | The threads from before |
| The license | License | Licence active, server reachable |
| The phones | Devices | Online |
| Sending | Quick send, to a number you control | Received |
| Receiving | Reply from that number | The reply appears in Conversations |
Do not dismantle the old machine before every line is checked. As long as it exists, rolling back takes a minute.
Once everything is checked:
- On the old machine,
sudo sms-gateway uninstall --purgedeletes the gateway and its data. Only do it when you are sure: it cannot be undone. - Delete the transferred archive copies, or store them encrypted with your backups.
- After a route B restore, the database set aside as
gateway.db.pre-restore-...can be deleted (see Backup and restore). - Schedule backups on the new machine: see Backup and restore.
9. Roll back
| Situation | What to do |
|---|---|
| Route A, something is wrong on the new machine | sudo sms-gateway stop on the new one, point the DNS back if you changed it, sudo sms-gateway start on the old one. Phones reconnect to it |
| Route B, restore prepared but not applied | Cancel the restore in Settings > Backup and export |
| Route B, restore applied but the result is wrong | Put the previous database back: see Backup and restore |
| You already regenerated the key | The old machine keeps sending, but must receive the new key in License to renew |
10. When the new gateway does not start
sms-gateway logs shows the reason on a line containing gateway stopped. After a migration, the
usual causes are:
| Cause | Fix |
|---|---|
| The archive comes from a newer version | Update: sudo sms-gateway update |
| A setting you had added by hand is missing or invalid | Copy your additions from the old .env (see Installation, settings), then sms-gateway restart |
| Files of the data folder not readable by the gateway | Extract the archive as shown in step 5 (it keeps the right owner), not by copying files by hand |
The full list of startup messages is in Installation.
Settings to carry over by hand: anything you changed or uncommented in the .env file of the old
installation (GATEWAY_LOG_LEVEL, GATEWAY_TRUSTED_PROXIES, GATEWAY_ROUTING_MODE,
GATEWAY_CARRIER_PREFIXES, GATEWAY_LOG_RETENTION_DAYS, GATEWAY_WEBHOOKS_ALLOW_PRIVATE_NETWORKS,
GATEWAY_SECRET_KEY...). An installation older than this version may also have variables added by
hand to its docker-compose.yml: move them to the new .env. Everything set in the dashboard,
the automatic backup schedule included, travels with the data.