Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Migrate From SS-Panel UIM

This guide walks Helium operators through migrating an existing SS-Panel UIM deployment. The migration intentionally happens in two isolated passes so you can export data from the legacy MariaDB instance without touching the new Helium PostgreSQL database until you are ready.

At a high level:

  1. mariadb-pass reads all data from the SS-Panel MariaDB schema and saves it to a local rkyv archive.
  2. postgre-pass consumes that rkyv archive and writes normalized data into Helium’s PostgreSQL schema.

Because Helium normally targets PostgreSQL, the first pass uses a dedicated crate that bundles the MySQL client driver and builds separately from the rest of the project.

What Gets Migrated

The migration transfers the following SS-Panel data into Helium’s schema:

User Accounts

  • Email and password hashes (preserved as-is for seamless login)
  • User names and registration timestamps
  • Last active timestamps
  • Account balances (available balance for purchasing)
  • Referral relationships (affiliate ref_by links)
  • Traffic usage (upload/download totals)
  • VMess UUIDs (for node authentication)
  • Subscribe tokens (subscription links)
  • Invite codes (user-specific invite codes)

Helium creates corresponding entries in:

  • auth.user_account (login credentials)
  • auth.user_profile (profile metadata)
  • shop.user_balance (financial data)
  • market.affiliate_user_policy (referral relationships)
  • telecom.user_nodes_token (node authentication tokens)

Products → Packages

SS-Panel products are converted to Helium packages with:

  • Package name
  • Price
  • Duration (time allowance in days)
  • Bandwidth quota

These populate the telecom.package table.

Orders → Package Queues

Historical purchase orders are replayed into Helium’s package queue system:

  • Order status (activated vs. pending)
  • Creation and update timestamps
  • Associated product/package

Orders are inserted into telecom.package_queue to preserve user entitlements and purchase history.

Nodes → Node Servers & Clients

SS-Panel nodes are split into two Helium entities:

  • Node servers (telecom.node_server): server address, rate, class
  • Node clients (telecom.node_client): protocol configurations (VMess, WebSocket, gRPC)

Each node’s custom configuration (ports, security, network transport) is normalized to Helium’s node client schema.

Data Not Migrated

The following SS-Panel data is not migrated:

  • Invoices (read but not written to Helium)
  • Payback records (read but not written)
  • Admin accounts (must be created manually via helium-cli)
  • System configurations (initialize via helium-cli init-config)
  • Announcements and tickets (start fresh in Helium)

Prerequisites

  • SS-Panel UIM running on MariaDB (or MySQL-compatible) that you can access in read-only mode during export.
  • A ready Helium PostgreSQL database with migrations applied and no production users yet. Run sqlx migrate run before importing.
  • Adequate disk space wherever you write the rkyv archive. Expect several hundred megabytes for large installs.
  • Rust toolchain (same as Helium) and network access to both databases from the machine performing the migration.
  • Optional: a safe location (e.g., object storage) to back up the generated rkyv file.

Pass 1 – Export From SS-Panel (MariaDB)

The exporter lives in ssp-migrator/mariadb-pass and is compiled with SQLx’s MySQL feature set. Build and run it separately from the main server binaries.

Build the exporter

mariadb-pass uses SQLx’s compile-time query checking. The workspace ships with .sqlx caches for PostgreSQL only, so generic commands such as cargo build --release -p mariadb-pass will fail. You must compile from the crate directory with access to a live SS-Panel database (or export SQLx metadata for MariaDB manually).

cd ssp-migrator/mariadb-pass
SQLX_OFFLINE=false DATABASE_URL="$SSP_DATABASE_URL" cargo build --release

The DATABASE_URL environment variable is required during compilation so SQLx can introspect the MariaDB schema. If you cannot open a direct connection from the build host, generate SQLx data offline with sqlx prepare against MariaDB and commit it alongside the crate before building.

Prepare connection settings

You can pass the database URL directly on the command line or export it as an environment variable. A typical MariaDB connection string looks like:

export SSP_DATABASE_URL="mysql://user:password@legacy-host:3306/sspanel"

Run the exporter

cd ssp-migrator/mariadb-pass
SQLX_OFFLINE=false DATABASE_URL="$SSP_DATABASE_URL" cargo run --release -- \
  --database-url "$SSP_DATABASE_URL" \
  --output-file /tmp/helium-migration.rkyv

The command performs several steps internally:

  • Streams each SS-Panel entity (users, products, orders, nodes, etc.) in batches.
  • Normalizes relationships to Helium’s intermediate structs.
  • Serializes the result to an rkyv archive (default name migration_data.rkyv).

Monitor the logs for warnings about rows that cannot be converted. The exporter skips invalid records but continues processing.

When the run finishes you should have an archive file similar to /tmp/helium-migration.rkyv. Back it up before moving on.

Pass 2 – Import Into Helium (PostgreSQL)

The importer lives in ssp-migrator/postgre-pass and understands Helium’s canonical schema. Ensure the target PostgreSQL database is empty or freshly provisioned to avoid collisions.

Build the importer

cargo build --release -p postgre-pass

This binary only links the PostgreSQL driver, so it compiles with the same workspace settings as other Helium components.

Prepare connection settings

export HELIUM_DATABASE_URL="postgres://helium:password@new-host:5432/helium_db"

Run the importer

cargo run --release -p postgre-pass -- \
  --rkyv-file /tmp/helium-migration.rkyv \
  --database-url "$HELIUM_DATABASE_URL"

The importer performs conversions aligned with Helium’s modules:

  • Inserts node servers and clients in the correct dependency order.
  • Creates packages, affiliate policies, balances, and user accounts.
  • Replays historical purchases into the package queue so users retain entitlements.

If anything fails, no partial state is left behind—each insert group is committed in dependency order. Fix the reported data issue, rebuild the rkyv archive if necessary, and rerun the importer.

Post-migration Checklist

  • Confirm the importer logs Migration completed successfully.
  • Inspect a handful of migrated users in Helium’s admin tools (profiles, balances, active packages).
  • Verify node configurations in telecom match the expected SS-Panel node inventory.
  • Rotate user credentials if required by your migration policy (password hashes are imported as-is).
  • Schedule DNS cutover and client config updates after validating the new deployment.

Troubleshooting

  • MariaDB TLS or authentication errors: confirm the MariaDB driver accepts your certificates or append parameters (e.g., ?ssl-mode=REQUIRED).
  • Missing subscribe links or invite codes: the exporter requires these tables to be populated for each user. Reconcile data in SS-Panel before exporting.
  • Importer stops on unique constraint violations: verify the PostgreSQL database is clean. Drop and recreate the schema, then rerun the importer.
  • Large datasets: run the exporter on a machine close to the database to reduce latency. You can copy the resulting rkyv file to the environment where the importer runs.

With both passes complete, Helium now has a faithful copy of the SS-Panel data and you can proceed with normal deployment and cutover activities.