> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ankra.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# ankra migrate

> Move an existing deployment (docker-compose, Dockerfile, running containers) into a cluster Ankra runs

## ankra migrate

Move an existing deployment into a cluster that Ankra runs.

'ankra migrate up \<dir> --cluster \<name>' does the whole journey in one
command: it plans (what will move, how big it is, what stays behind),
converts the deployment into a stack, deploys the stack, dumps every
database from the source and restores it in the cluster. Run it once as a
rehearsal, then again with --stop-source for the cutover.

The steps are also separate commands, for when you want to look at each
result: 'convert' writes the stack, 'ankra cluster apply' deploys it,
'export' dumps the data, 'restore' loads it, 'data' does export and
restore together. 'convert', 'detect', 'export' and 'modules' work offline;
'up', 'restore', 'restore-status' and 'data' talk to the platform.

Conversion and export are done by modules. The 'docker' module is built in
and reads docker-compose files, bare Dockerfiles, and the running Docker
daemon. Anyone can add a module for another format by putting an executable
named 'ankra-module-\<name>' on PATH or in \~/.ankra/modules - see
'ankra migrate modules --help' for the contract.

## ankra migrate convert

Convert the deployment described in a directory (default: the current one)
into an output directory holding cluster.yaml and the manifests it refers to.

The module is chosen by asking each one whether it recognises the directory;
pass --module to choose explicitly. Module-specific settings go through
\--option key=value, repeated as needed. For the built-in docker module:

\--option source=compose|dockerfile|daemon   which source to read (default: detected)
\--option profiles=app,dns                   compose profiles to include
\--option all-profiles=true                  include every compose profile
\--option use-environment=true               let your shell satisfy \$\{VAR} references
\--option project=\<name>                     compose project, for source=daemon
\--option containers=a,b                     specific containers, for source=daemon
\--option docker-host=ssh://root\@host        a remote daemon, for source=daemon
\--option image.\<workload>=\<registry/repo:tag>  image for a locally built workload
\--option ingress.\<workload>=\<host>          expose a workload through an Ingress
\--option cluster-issuer=letsencrypt-prod    request TLS for every Ingress
\--option volume-size=20Gi                   size of every PersistentVolumeClaim
\--option storage-class=\<name>               storageClassName for every claim

Read the warnings: they list what the module could not carry over - locally
built images, host directories, unresolved variables, credentials written in
plain text - and each one names the fix.

Then review the output and apply it:

ankra cluster apply -f \<out>/cluster.yaml

```bash theme={null}
ankra migrate convert [dir] [flags]
```

**Examples**

```bash theme={null}
ankra migrate convert
  ankra migrate convert ./app --out ./app-k8s --option profiles=app
  ankra migrate convert --option source=daemon --option project=aura-office
  ankra migrate convert --option ingress.app=example.com --option cluster-issuer=letsencrypt-prod
```

**Flags**

| Flag             | Default           | Description                                                             |
| ---------------- | ----------------- | ----------------------------------------------------------------------- |
| `--cluster-name` |                   | Name for the generated ImportCluster (default: the directory name)      |
| `--dry-run`      | `false`           | Print cluster.yaml and the files that would be written, without writing |
| `--force`        | `false`           | Overwrite an output directory that is not empty                         |
| `--module`       |                   | Module to use (default: the most confident detection)                   |
| `--namespace`    |                   | Namespace for the generated workloads (default: the cluster name)       |
| `--option`       | `[]`              | Module option as key=value (repeatable)                                 |
| `--out`          | `ankra-migration` | Output directory                                                        |
| `-o`, `--output` |                   | Output format: json or yaml (default: human-readable)                   |

## ankra migrate data

Run 'ankra migrate export' on the directory (default: the current one) and
'ankra migrate restore' on the result, back to back: the one command that
moves a Docker deployment's data into the cluster once its workloads are
running there. Every flag of both commands applies. The cluster and the
vault are resolved before anything is dumped, so a wrong target fails fast.

Each dump is a snapshot of a live server. Rehearse while the source is
running, then stop its writers and run it once more for the real cutover.

```bash theme={null}
ankra migrate data [dir] [flags]
```

**Examples**

```bash theme={null}
ankra migrate data ./app --cluster shop --wait
  ankra migrate data ./app --option docker-host=ssh://root@203.0.113.7 --option project=aura-office --cluster shop --wait
```

**Flags**

| Flag             | Default                | Description                                                                                             |
| ---------------- | ---------------------- | ------------------------------------------------------------------------------------------------------- |
| `--cluster`      |                        | Cluster to restore into, by name or id (default: the selected cluster)                                  |
| `--force`        | `false`                | Overwrite an output directory that is not empty                                                         |
| `--module`       |                        | Module to use (default: the most confident detection)                                                   |
| `--namespace`    |                        | Namespace the converted workloads run in (default: the directory name, as for convert)                  |
| `--option`       | `[]`                   | Module option as key=value (repeatable)                                                                 |
| `--out`          | `ankra-migration-data` | Output directory for the export                                                                         |
| `-o`, `--output` |                        | Output format: json or yaml (default: human-readable)                                                   |
| `--stack`        |                        | Stack the data belongs to (default: derived from the export)                                            |
| `--timeout`      | `10m0s`                | Maximum time to wait when --wait is set                                                                 |
| `--vault`        |                        | Backup vault to upload through, by name or id (default: the organisation's only ready vault)            |
| `--wait`         | `false`                | Wait for the operation to finish and report success or failure (default: submit and return immediately) |

## ankra migrate detect

Ask every module whether it recognises the directory (default: the current
one). Use it to see what 'ankra migrate convert' would pick, or why it picks
nothing.

```bash theme={null}
ankra migrate detect [dir] [flags]
```

**Flags**

| Flag             | Default | Description                                           |
| ---------------- | ------- | ----------------------------------------------------- |
| `-o`, `--output` |         | Output format: json or yaml (default: human-readable) |

## ankra migrate export

Dump every database the deployment in a directory (default: the current one)
runs - PostgreSQL and MySQL/MariaDB today - into an output directory, with a
manifest.json that says where each dump restores to: the Service that
'ankra migrate convert' generated for the database and the Secret holding its
password.

The dumps are taken through the docker CLI from the running containers, so
the source must be up. A deployment on another host is reached the way docker
itself reaches it:

\--option docker-host=ssh://root\@203.0.113.7  dump from a remote Docker daemon
\--option project=\<name>                      the compose project name, when it
differs from the directory name
\--option container.\<workload>=\<name>         dump from a specific container
\--option databases.\<workload>=a,b            only these databases (default: all)
\--option profiles=app,dns                    compose profiles, as for convert

Each dump is a snapshot of a live server. Rehearse with the source running,
then stop its writers and export once more right before the final cutover.

The output directory is self-contained: manifest.json describes every
artifact and where it belongs, and SHA256SUMS lets 'sha256sum -c' verify it.
Load it into the cluster with 'ankra migrate restore \<out>'.

```bash theme={null}
ankra migrate export [dir] [flags]
```

**Examples**

```bash theme={null}
ankra migrate export ./app --out ./app-data
  ankra migrate export ./app --option docker-host=ssh://root@203.0.113.7 --option project=aura-office
  ankra migrate export --option databases.postgres=office,pdns
```

**Flags**

| Flag             | Default                | Description                                                                            |
| ---------------- | ---------------------- | -------------------------------------------------------------------------------------- |
| `--force`        | `false`                | Overwrite an output directory that is not empty                                        |
| `--module`       |                        | Module to use (default: the most confident detection)                                  |
| `--namespace`    |                        | Namespace the converted workloads run in (default: the directory name, as for convert) |
| `--option`       | `[]`                   | Module option as key=value (repeatable)                                                |
| `--out`          | `ankra-migration-data` | Output directory                                                                       |
| `-o`, `--output` |                        | Output format: json or yaml (default: human-readable)                                  |

## ankra migrate imports

Every 'ankra migrate restore' (and 'up', and 'data') uploads the export's
dumps into the organisation's backup vault under imports/\<import-id>/ and
keeps them there, so the same upload can be restored again. These verbs
show what a vault holds and remove an import - its dumps in the vault and
the record - once it is no longer needed.

## ankra migrate imports delete

Delete the dumps an import uploaded into the backup vault and hide the
import. An import whose restore is still running is refused: its job is
reading those dumps. Objects the vault cannot be asked to remove are noted
in the audit record; the import is gone either way.

```bash theme={null}
ankra migrate imports delete <import-id> [flags]
```

**Examples**

```bash theme={null}
ankra migrate imports delete 6f1c8e2a-... --yes
  ankra migrate imports delete 6f1c8e2a-... --vault backups
```

**Flags**

| Flag          | Default | Description                                                                                        |
| ------------- | ------- | -------------------------------------------------------------------------------------------------- |
| `--vault`     |         | Backup vault the import went through, by name or id (default: the organisation's only ready vault) |
| `-y`, `--yes` | `false` | Skip the confirmation prompt                                                                       |

## ankra migrate imports list

List the imports a backup vault holds

```bash theme={null}
ankra migrate imports list [flags]
```

**Examples**

```bash theme={null}
ankra migrate imports list
  ankra migrate imports list --vault backups -o json
```

**Flags**

| Flag             | Default | Description                                                                |
| ---------------- | ------- | -------------------------------------------------------------------------- |
| `-o`, `--output` |         | Output format: json or yaml (default: human-readable)                      |
| `--vault`        |         | Backup vault, by name or id (default: the organisation's only ready vault) |

## ankra migrate modules

List every conversion module 'ankra migrate' can use.

Built-in modules ship with the CLI. External modules are executables named
'ankra-module-\<name>' found in \~/.ankra/modules or on PATH, in that order; a
name that collides with a built-in is ignored.

An external module answers three verbs, each with a JSON request on stdin
and a JSON reply on stdout:

ankra-module-\<name> describe
-> \{"name":"\<name>","version":"1.2","protocol":1,"summary":"...",
"file\_patterns":\["Procfile"]}
ankra-module-\<name> detect
\<- \{"dir":"/path/to/project"}
-> \{"confidence":0.9,"files":\["Procfile"],"reason":"Procfile present"}
ankra-module-\<name> convert
\<- \{"dir":"...","cluster\_name":"...","namespace":"...","options":\{"k":"v"}}
-> \{"cluster":\{\<ImportCluster>},"files":\{"manifests/web.yaml":"..."},
"warnings":\["..."]}

Confidence runs 0 (not mine) to 1 (certain); reserve 1 for an unambiguous
marker file so a specific module wins over a general one. File paths in the
reply are relative to the output directory and may not escape it. A non-zero
exit fails the verb and the module's stderr is shown as the reason.
Warnings are for anything the module could not translate faithfully: a
partial conversion a person can finish beats none.

A module that lists "export" under "capabilities" in its description also
answers a fourth verb, which backs 'ankra migrate export':

ankra-module-\<name> export
\<- \{"dir":"...","output\_dir":"/abs/path","namespace":"...","options":\{}}
-> \{"databases":\[\{"workload":"db","engine":"postgres","server\_version":"17.2",
"target":\{"namespace":"...","host":"db","port":5432,"username":"app",
"password\_secret":"db-secrets","password\_key":"POSTGRES\_PASSWORD"},
"artifacts":\[\{"path":"db/globals.sql","kind":"globals","format":"sql"},
\{"path":"db/app.dump","kind":"database","format":"pg\_custom","database":"app"}]}],
"warnings":\["..."]}

The module writes the dumps under output\_dir and reports their paths; the
CLI measures sizes and checksums itself. Stderr is relayed live while an
export runs, so narrate progress there.

Install a module without touching PATH with 'ankra migrate modules
install \<https-url-or-file>' (validated via its describe verb; --sha256
pins the download) and remove it with 'ankra migrate modules uninstall
\<name>'.

The protocol version is 1. The reference implementation is the built-in
'docker' module; a worked external example lives in the CLI repository under
examples/modules/.

```bash theme={null}
ankra migrate modules [flags]
```

**Flags**

| Flag             | Default | Description                                           |
| ---------------- | ------- | ----------------------------------------------------- |
| `-o`, `--output` |         | Output format: json or yaml (default: human-readable) |

## ankra migrate modules install

Fetch one module executable - from an https URL or a local file - into
\~/.ankra/modules, where 'ankra migrate' discovers it without touching PATH.

Before anything is kept, the module's describe verb is run and its answer
checked: the protocol version, and the name the module calls itself, which
is the name it is installed under. A module runs with your permissions, on
your files and your Docker socket; install only modules you trust, and pass
\--sha256 when the author publishes a checksum.

```bash theme={null}
ankra migrate modules install <url-or-file> [flags]
```

**Examples**

```bash theme={null}
ankra migrate modules install https://github.com/org/x/releases/download/v1/ankra-module-procfile
  ankra migrate modules install ./ankra-module-procfile --yes
  ankra migrate modules install https://example.com/m --sha256 9f86d081...
```

**Flags**

| Flag          | Default | Description                                                               |
| ------------- | ------- | ------------------------------------------------------------------------- |
| `--force`     | `false` | Replace a module of the same name that is already installed               |
| `--name`      |         | Expected module name; refused when the module calls itself something else |
| `--sha256`    |         | Hex sha256 the download must match                                        |
| `-y`, `--yes` | `false` | Skip the confirmation prompt                                              |

## ankra migrate modules uninstall

Delete an installed module's executable from \~/.ankra/modules. A module
found on PATH is managed by whatever put it there and is refused with its
location, so nothing outside the CLI's own directory is ever removed.

```bash theme={null}
ankra migrate modules uninstall <name> [flags]
```

**Examples**

```bash theme={null}
ankra migrate modules uninstall procfile --yes
```

**Flags**

| Flag          | Default | Description                  |
| ------------- | ------- | ---------------------------- |
| `-y`, `--yes` | `false` | Skip the confirmation prompt |

## ankra migrate restore

Load the databases 'ankra migrate export' dumped into the cluster that now
runs the converted deployment. The export directory's manifest says where
each dump belongs - the Service and Secret 'ankra migrate convert' generated
for the database - so nothing has to be looked up by hand.

The dumps are uploaded straight to the organisation's backup vault with
presigned URLs, the platform verifies every object arrived intact, and the
cluster's agent runs the restore inside the cluster: roles and globals
first, then each database with the engine's own tools. Ankra never holds
the data, and this machine needs neither kubectl nor a database client.

Prerequisites: a backup vault in the organisation ('ankra backup vaults
provision' creates one), the converted stack applied to the cluster
('ankra cluster apply'), and a cluster agent that supports data restores.
The vault is picked automatically when the organisation has exactly one
ready vault; pass --vault otherwise.

Pass --wait to follow the restore to its end; --timeout bounds only that
wait, never the upload. Without --wait the command returns once the restore
is running, and 'ankra migrate restore-status \<import-id>' reports progress.

```bash theme={null}
ankra migrate restore <export-dir> [flags]
```

**Examples**

```bash theme={null}
ankra migrate restore ./app-data --cluster shop --wait
  ankra migrate restore ./app-data --cluster shop --vault backups --stack shop
  ankra migrate restore ./app-data -o json
```

**Flags**

| Flag             | Default | Description                                                                                             |
| ---------------- | ------- | ------------------------------------------------------------------------------------------------------- |
| `--cluster`      |         | Cluster to restore into, by name or id (default: the selected cluster)                                  |
| `-o`, `--output` |         | Output format: json or yaml (default: human-readable)                                                   |
| `--stack`        |         | Stack the data belongs to (default: derived from the export)                                            |
| `--timeout`      | `10m0s` | Maximum time to wait when --wait is set                                                                 |
| `--vault`        |         | Backup vault to upload through, by name or id (default: the organisation's only ready vault)            |
| `--wait`         | `false` | Wait for the operation to finish and report success or failure (default: submit and return immediately) |

## ankra migrate restore-status

Read an import and the state of its restore jobs, one per database server.
Pass --wait to block until the restore has completed or failed.

```bash theme={null}
ankra migrate restore-status <import-id> [flags]
```

**Examples**

```bash theme={null}
ankra migrate restore-status 6f1c8e2a-... --vault backups
  ankra migrate restore-status 6f1c8e2a-... --wait
```

**Flags**

| Flag             | Default | Description                                                                                             |
| ---------------- | ------- | ------------------------------------------------------------------------------------------------------- |
| `-o`, `--output` |         | Output format: json or yaml (default: human-readable)                                                   |
| `--timeout`      | `10m0s` | Maximum time to wait when --wait is set                                                                 |
| `--vault`        |         | Backup vault the import went through, by name or id (default: the organisation's only ready vault)      |
| `--wait`         | `false` | Wait for the operation to finish and report success or failure (default: submit and return immediately) |

## ankra migrate up

Move the deployment described in a directory (default: the current one)
into a cluster that Ankra runs, end to end:

1. Plan.    Detect the source, find every database it runs and its size,
   resolve the cluster, the stack and the backup vault, and say
   what the migration will and will not carry. Nothing is
   touched until the plan checks out; --plan stops here.
2. Convert. Turn the deployment into a stack (cluster.yaml plus the
   manifests) under \<out>/stack, as 'ankra migrate convert' does.
3. Deploy.  Apply the stack to the cluster and wait for its database
   workloads to be running.
4. Export.  Dump every database from the source, as 'ankra migrate
   export' does, into \<out>/data. With --stop-source the
   source's other services are stopped first, so the dump is
   the last word on the data: that is the cutover.
5. Restore. Upload the dumps through the backup vault and load them
   into the cluster, as 'ankra migrate restore' does, and wait.

The command is safe to run more than once, into the same output directory:
the stack is re-applied, the databases are dumped and restored again.
Rehearse while the source runs, then run it once more with --stop-source
when you are ready to switch.
\--timeout bounds each waiting step (deploy, readiness, restore).

Not carried: files kept in the volumes of non-database workloads, and data
in engines the export does not dump (Redis, MongoDB, search indexes). The
plan names every such item so nothing is left behind unnoticed.

```bash theme={null}
ankra migrate up [dir] [flags]
```

**Examples**

```bash theme={null}
ankra migrate up ./app --cluster shop --plan
  ankra migrate up ./app --cluster shop --option ingress.app=shop.example.com --option cluster-issuer=letsencrypt-prod
  ankra migrate up ./app --cluster shop --stop-source --yes
  ankra migrate up ./app --cluster shop --option docker-host=ssh://root@203.0.113.7
```

**Flags**

| Flag             | Default           | Description                                                                                      |
| ---------------- | ----------------- | ------------------------------------------------------------------------------------------------ |
| `--cluster`      |                   | Cluster to migrate into, by name or id (default: the selected cluster)                           |
| `--force`        | `false`           | Overwrite an output directory that holds files no earlier run of this command wrote              |
| `--module`       |                   | Module to use (default: the most confident detection)                                            |
| `--namespace`    |                   | Namespace the workloads run in (default: the stack name)                                         |
| `--no-data`      | `false`           | Deploy the workloads only; carry no data over                                                    |
| `--option`       | `[]`              | Module option as key=value (repeatable); convert and export options both apply                   |
| `--out`          | `ankra-migration` | Output directory: \<out>/stack for the conversion, \<out>/data for the dumps                     |
| `-o`, `--output` |                   | Output format: json or yaml (default: human-readable)                                            |
| `--plan`         | `false`           | Print the plan and stop; change nothing                                                          |
| `--stack`        |                   | Name of the stack on the cluster (default: the directory name)                                   |
| `--stop-source`  | `false`           | Stop the source's non-database services before the export, so the dump is final (the cutover)    |
| `--timeout`      | `10m0s`           | Maximum time to wait when --wait is set                                                          |
| `--vault`        |                   | Backup vault the data goes through, by name or id (default: the organisation's only ready vault) |
| `-y`, `--yes`    | `false`           | Skip the confirmation prompt                                                                     |
