Migrating from NuxtHub to NuxFly

This guide explains how to migrate an existing NuxtHub project to NuxFly. NuxFly provides similar functionality to NuxtHub but with deployment targetted to Fly.io instead of Cloudflare.

Overview

The migration process involves:

Replacing NuxtHub dependencies with NuxFly equivalents

Updating configuration files

Modifying code to use NuxFly composables instead of NuxtHub functions

Setting up Fly.io deployment configuration

Step-by-Step Migration

1. Update Dependencies

Replace NuxtHub dependencies with NuxFly equivalents:

{
  "dependencies": {
-   "@nuxthub/core": "0.9.0",
+   "@nuxfly/core": "^1.0.9"
  }
}

Update your imports in nuxt.config.ts:

export default defineNuxtConfig({
  modules: [
-   '@nuxthub/core',
+   '@nuxfly/core',
  ],
- hub: {
-   database: true,
-   blob: true
- },
+ nuxfly: {
+   litestream: true,      // Enable SQLite with Litestream backup
+   publicStorage: true,   // Enable public S3 storage
+   privateStorage: true,  // Enable private S3 storage
+ },
})

2. Update Database Usage

Replace NuxtHub database functions with NuxFly equivalents:

-import { drizzle } from 'drizzle-orm/d1'
+import { drizzle } from 'drizzle-orm/libsql'
import * as schema from '../database/schema'

export { eq, and, or, ne, not, lt, gt, asc, desc, count } from 'drizzle-orm'

export const tables = schema
+const db = drizzle(useSqliteDatabase().db, { schema })

export function useDB() {
-   return drizzle(hubDatabase(), { schema })
+   return db
}

3. Update Blob Storage Usage

Replace NuxtHub blob storage functions with NuxFly equivalents:

-const file = await hubBlob().put(image.name, image, {
-  addRandomSuffix: true,
-})
-return file.pathname
+const { minioClient, bucket } = usePublicStorage()
+
+const filePath = `${Math.random().toString(36).substring(2, 15)}-${image.name.replace(/\\W+/g, '-')}`
+await minioClient.putObject(bucket, filePath, image, {
+  'Content-Type': image.type,
+})
+return filePath

Update file URL construction in your components:

-return `/files/${filePath}`
+return `${useRuntimeConfig().public.s3PublicUrl}/${filePath}`

4. Add Database Migration Script

Add the database migration script to your package.json:

{
  "scripts": {
    "db:generate": "drizzle-kit generate",
+   "db:migrate": "drizzle-kit migrate"
  }
}

5. Configure Fly.io Deployment

NuxFly will automatically generate the necessary Fly.io configuration files when you run nuxfly launch. These files are fly.toml, fly.*.toml and .nuxfly/*. You can re-generate these files as well using nuxfly generate.

6. Environment Configuration

NuxFly uses environment variables for configuration. Make sure to set the following in your Fly.io application:

  • NUXFLY_ENV - Environment name (staging, development, etc.)
  • Database and storage credentials as needed

Key Differences

Database

  • NuxtHub uses Cloudflare D1, NuxFly uses SQLite with Litestream backup
  • Database access is through useSqliteDatabase() composable instead of hubDatabase()

Storage

  • NuxtHub uses Cloudflare R2, NuxFly uses S3-compatible storage (Minio/Tigris)
  • Storage access is through usePublicStorage() and usePrivateStorage() composables
  • File URLs need to be constructed manually using s3PublicUrl runtime config

Deployment

  • NuxtHub deploys to Cloudflare, NuxFly deploys to Fly.io
  • NuxFly includes automatic Litestream backup configuration
  • NuxFly includes automatic database migration on deployment

Deployment Commands

After migration, use NuxFly commands for deployment:

# Install NuxFly CLI globally
npm install -g @nuxfly/cli

# Launch a new app
nuxfly launch

# Generate remaining .nuxfly files
nuxfly generate

# Deploy to the configured app
nuxfly deploy --build

# Deploy to specific environment
NUXFLY_ENV=staging nuxfly launch

Post-Migration Checklist

Verify database connections work correctly

Test file upload and retrieval functionality

Check that all environment variables are properly configured

Verify Fly.io deployment works correctly

Test database migrations run properly on deployment

Confirm Litestream backup is functioning