# Migrating from Pterodactyl

> Move a Pterodactyl panel to FeatherPanel with feathercli migrate. What is imported, the 15 migration steps, and how to switch each node from Wings to FeatherWings.

Source: https://featherpanel.com/docs/migrating/pterodactyl/

FeatherPanel imports a Pterodactyl panel through the Pterodactyl Migration Agent, which is the `migrate` command of
[FeatherCli](https://featherpanel.com/docs/cli/feathercli). The agent reads the Pterodactyl database and sends the data to the importer endpoints
of your new panel. The direct HTTP import in older versions is gone.

> [!IMPORTANT]
> Back up the Pterodactyl database and `.env` before you start. The migration only reads from Pterodactyl, but it puts the
> panel into maintenance mode.

## What is imported

The migration runs 15 steps in this order and records progress in `.migration-progress.json` in the current directory,
so an interrupted run can resume:

1. Panel settings
2. Locations
3. Nests, as [realms](https://featherpanel.com/docs/admin/realms-and-spells)
4. Eggs and their variables, as [spells](https://featherpanel.com/docs/spells)
5. Nodes
6. Database hosts
7. Allocations
8. Users, with their bcrypt password hashes
9. SSH keys
10. Servers and server variables, keeping their UUIDs
11. Server databases
12. Backups
13. Subusers
14. Schedules
15. Schedule tasks

The migration decrypts values Pterodactyl stored with its `APP_KEY`, which is why it needs the Pterodactyl `.env` or the
key itself.

If [Blueprint](https://blueprint.zip) is installed on the Pterodactyl panel, the agent warns that its database changes may
break the migration and asks you to confirm with `--confirm-blueprint`.

## 1. Prepare FeatherPanel

[Install FeatherPanel](https://featherpanel.com/docs/panel/installation) on a new server or next to Pterodactyl, and register the first account. Do
not create nodes, locations or servers: the importer checks that the panel has at most one user and nothing else.

Open `/admin/pterodactyl-importer`. The page shows the prerequisite check, lets you create an API key for the agent, and
lists the commands below. The key needs the `admin.root` permission.

## 2. Install and configure FeatherCli

On the Pterodactyl server:

```bash
curl -sSL https://get.featherpanel.com/stable.sh | bash   # choose [3] CLI
feathercli config setup                                   # panel URL and the API key from step 1
feathercli config test
```

## 3. Run the migration

<div role="tablist" class="tabs tabs-border fpd-tabs" data-sync="ptero-source">
<input type="radio" name="ptero-source" class="tab" aria-label="Standard install" checked />
<div class="tab-content">

```bash
feathercli migrate check --pterodactyl-dir /var/www/pterodactyl
feathercli migrate --pterodactyl-dir /var/www/pterodactyl
```

The agent reads `/var/www/pterodactyl/.env`, connects to the Pterodactyl database and runs `php artisan down` to stop
changes during the import. If that fails it asks you to run it yourself.

</div>
<input type="radio" name="ptero-source" class="tab" aria-label="Docker / SQL dump" />
<div class="tab-content">

For a Dockerised Pterodactyl, export the database and `.env`, then let the agent load the dump into a staging MySQL
server it can reach:

```bash
docker compose exec database mariadb-dump -u root -p"$MARIADB_ROOT_PASS" panel > panel.sql
docker compose exec panel cat /app/var/.env > panel.env

feathercli migrate \
  --sql-dump ./panel.sql \
  --env-file ./panel.env \
  --staging-db-host 127.0.0.1 \
  --staging-db-user root \
  --staging-db-password 'your-mysql-password'
```

Use `--app-key` instead of `--env-file` if you only have the key. `--sql-dump` and `--pterodactyl-dir` cannot be combined.

</div>
</div>

| Flag | Meaning |
|------|---------|
| `--confirm-migrate` | Skip the final confirmation |
| `--confirm-blueprint` | Continue although Blueprint is installed |
| `--reset` | Forget saved progress and start from step 1 |
| `--staging-db-port` | Port of the staging database |

## 4. Switch each node to FeatherWings

The migration moves data, not daemons. Right after it finishes, do this on every node:

```bash
sudo systemctl disable --now wings
curl -sSL https://get.featherpanel.com/installer.sh | bash   # choose [2] Wings, install only
```

Then get the node's configuration from FeatherPanel (the node page in the admin area) and apply it with
`featherwings configure --join-data ... --override`, or place it in `/etc/featherpanel/config.yml`, and start the service:

```bash
sudo systemctl enable --now featherwings
```

Imported nodes keep their data directory, so FeatherWings finds the existing server files in
`/var/lib/pterodactyl/volumes` without copying anything. Server UUIDs are unchanged.

## After the migration

- Sign in with a migrated user and open a few servers: console, files, backups.
- Check that every node is green and that schedules run.
- Point your domain at FeatherPanel when you are satisfied, and keep the Pterodactyl backup for a while.
- If you used the Pterodactyl API in other tools, read the [API reference](https://featherpanel.com/docs/api/reference). The agent's closing
  message recommends a Pterodactyl API compatibility plugin for existing integrations.

For a side by side comparison of the two panels, see [FeatherPanel vs Pterodactyl](https://featherpanel.com/docs/featherpanel-vs-pterodactyl).

## Frequently asked questions

### Do users need new passwords after migrating from Pterodactyl?

No. Pterodactyl stores bcrypt password hashes and the migration copies them unchanged, so users sign in to FeatherPanel with their existing passwords.

### Are server files copied during the migration?

No. Server files stay on the nodes. Imported nodes keep Pterodactyl's data directory (/var/lib/pterodactyl/volumes by default), and FeatherWings uses it once you switch the node over.

### Can I migrate into a FeatherPanel that already has servers?

No. The importer requires a clean panel with at most one user and no nodes, locations, realms, spells, servers, databases or allocations.
