ShipAny Image Generator

新官方
Iidoubi·发布于 3个月前
$199$99会员价

可直接上线的 AI 图片 SaaS:文生图、图片编辑和图片工具,配齐积分、计费和管理后台。

ai-image-generatorshipany-image
成为 ShipAny Premium 会员,即可用会员价购买模板

技术栈

Next.jsTanStackShadcn/UITailwindCSSAI SDKNode.js

ShipAny Image Generator 是什么?

ShipAny Image Generator 是基于 TanStack Start 和 ShipAny SaaS 引擎构建的完整 AI 图片产品。它包含面向公众的文生图、图生图生成器,以及抠图、图片放大、扩图和风格迁移等独立工具。

生成器之外的一切都已接好:用户账户、积分账本、订阅与收款、权限、内容管理、中英文、SEO 元数据和完整的管理后台。模型和服务商在后台配置,你只需换品牌、定价格,就能上线。

适合谁

  • 想上线 AI 图片网站的创业者
  • 需要可用生成器而非空白模板的开发者
  • 做细分图片工具获取 SEO 流量的运营者
  • 部署在 Cloudflare Workers 或 Node 的团队

核心功能

文生图与图生图

在同一流程中根据提示词生成,或编辑上传的图片。

独立图片工具

抠图、放大、扩图、风格迁移各自成页,每个都是可获取搜索流量的落地页。

多服务商

支持 gRouter、Replicate、Fal 和兼容 OpenAI 的接口,在后台切换。

积分与计费

按次扣积分,支持订阅、充值、收银台和支付回调。

管理后台

用户、角色、支付、内容、工单和系统配置集中管理。

双语与 SEO

中英文与按语言区分的 URL,canonical、hreflang、Open Graph 和结构化数据齐全。

包含内容

框架
TanStack Start、Vite 8、Nitro、React 19、TypeScript
UI
Tailwind CSS 4、shadcn/ui v4
AI 服务
gRouter、Replicate、Fal、兼容 OpenAI 的接口
登录
better-auth:邮箱密码、Google、GitHub
数据库
Drizzle ORM:SQLite、PostgreSQL、MySQL、Turso、Cloudflare D1
存储
Cloudflare R2、S3 兼容存储
多语言
Paraglide JS:中文、英文
部署
Cloudflare Workers(D1、R2、Hyperdrive)或 Node

如何开始

  1. 1

    安装运行

    克隆仓库,执行 pnpm install,复制 .env.example,同步 SQLite 表结构后启动开发服务器。

  2. 2

    创建管理员

    用你的邮箱运行 rbac:init 创建超级管理员,然后登录 /admin。

  3. 3

    配置服务商并上线

    在后台「设置」中填写 AI、存储和支付密钥,设置价格后部署。

可以用 ShipAny Image Generator 做什么

通用 AI 图片生成站

面向大众、按积分和订阅收费的图片网站。

细分图片工具

针对特定搜索词的抠图、放大或风格迁移网站。

新模型体验站

围绕新发布的图片模型,几天内上线站点。

常见问题

和 Image Lite 有什么区别?

Image Generator 包含抠图、放大、扩图、风格迁移等独立工具,支持的服务商更多;Image Lite 只有一个专注的生成器,功能面更小。

可以用哪些 AI 模型?

gRouter、Replicate、Fal 或兼容 OpenAI 的接口上可用的模型,都可以在后台配置。

能部署到 Cloudflare Workers 吗?

可以,使用 D1 或通过 Hyperdrive 连接 Postgres,生成的图片存到 R2。也可以作为 Node 服务运行。

技术说明(README)

ShipAny AI Image Generator

A production-ready AI image SaaS built with TanStack Start and the ShipAny headless SaaS engine.

The repository includes the public image generator, image-to-image editing, focused image tools, user accounts, credits, subscriptions, payments, RBAC, content management, internationalization, and a complete admin console.

What is included

  • AI image generation — text-to-image and image-to-image workflows
  • Focused image tools — background removal, upscaling, outpainting, and style transfer
  • Multiple providers — gRouter, Replicate, Fal, OpenAI-compatible endpoints, and other providers configured from the admin console
  • SaaS accounts — email/password, Google/GitHub OAuth, sessions, and user settings
  • Credits and billing — credit ledger, subscriptions, checkout, and payment webhooks
  • Admin console — users, RBAC, payments, content, support, and system configuration
  • Storage — S3-compatible and Cloudflare R2 providers
  • Internationalization — English and Chinese with locale-aware URLs
  • SEO — route metadata, canonical/hreflang links, Open Graph, and structured data

Tech stack

  • TanStack Start, Vite 8, Nitro, React 19, and TypeScript
  • TanStack Query, Form, Router, and Table
  • Tailwind CSS 4 and shadcn/ui v4
  • better-auth with a Drizzle adapter
  • Drizzle ORM with SQLite, PostgreSQL, MySQL, Turso, and Cloudflare D1 support
  • Paraglide JS for internationalization
  • Cloudflare Workers, D1, R2, and Hyperdrive deployment support

Prerequisites

  • Node.js 20 or newer
  • pnpm
  • OpenSSL, used to generate application secrets
  • A database server only when using PostgreSQL or MySQL
  • A Cloudflare account and Wrangler when deploying to Cloudflare Workers

Enable pnpm through Corepack if it is not already installed:

corepack enable

Local development

1. Install dependencies

pnpm install

The post-install script creates data/ and prepares the default SQLite schema when src/config/db/schema.ts does not exist.

2. Create the local environment file

cp .env.example .env.development

Generate an auth secret:

openssl rand -base64 32

Paste the generated value into .env.development:

VITE_APP_URL=http://localhost:3000
VITE_APP_NAME=My AI Image Generator
VITE_APP_DESCRIPTION=Create and edit images with AI
VITE_APP_LOGO=/logo.svg
VITE_DEFAULT_LOCALE=en

DATABASE_PROVIDER=sqlite
DATABASE_URL=file:data/local.db

AUTH_SECRET=replace-with-the-generated-value

# Recommended: encrypt secrets saved from Admin → Settings.
# Generate this separately with `openssl rand -base64 32`.
CONFIG_ENCRYPTION_KEY=replace-with-another-generated-value

.env.development is the canonical local environment file and is ignored by Git. An existing .env.local can override values during some commands, so avoid keeping conflicting database or URL values in both files.

Public browser-visible variables use the VITE_ prefix. Secrets such as AUTH_SECRET and database credentials must never use that prefix.

3. Prepare the database

For the default SQLite database:

pnpm db:setup
pnpm db:push

db:push directly synchronizes the development database and may perform destructive changes. Use it for local development, not for production deployments.

To use a different database locally, update .env.development before running the commands:

Provider DATABASE_PROVIDER DATABASE_URL example
SQLite sqlite file:data/local.db
PostgreSQL postgresql postgresql://localhost:5432/app
MySQL mysql mysql://localhost:3306/app
Turso turso libsql://database.turso.io

Turso also requires DATABASE_AUTH_TOKEN.

pnpm db:setup copies the matching dialect template into the ignored working file src/config/db/schema.ts. Permanent schema changes must also be kept in the appropriate committed template:

  • src/config/db/schema.sqlite.ts
  • src/config/db/schema.postgres.ts
  • src/config/db/schema.mysql.ts

4. Initialize RBAC and create an administrator

Create the default roles, permissions, and a local super administrator:

pnpm rbac:init \
  --admin-email=admin@example.com \
  --admin-password=choose-a-local-password

Alternatively, initialize RBAC without creating a user:

pnpm rbac:init

After a user signs up, grant the user a role with:

pnpm rbac:assign \
  --email=admin@example.com \
  --role=super_admin

Available built-in roles are super_admin, admin, editor, and viewer.

5. Start the development server

pnpm dev

Open:

6. Configure providers

Sign in as a super administrator and open Admin → Settings. Configure the services the product needs:

  • Auth — Google, GitHub, and email authentication
  • Payment — Stripe, Creem, PayPal, and supported regional providers
  • Email — Resend or Cloudflare Email
  • Storage — Cloudflare R2 or an S3-compatible service
  • AI — gRouter, Replicate, Fal, OpenAI, Anthropic, and model selection
  • Analytics — Google Analytics, Plausible, and advertising settings

Provider credentials are stored in the database. When CONFIG_ENCRYPTION_KEY is set, secret values are encrypted with AES-256-GCM. Keep this key stable: rotating or deleting it makes existing encrypted settings unreadable.

Environment variables with matching names can still be used as server-side fallbacks, but the admin console is the normal configuration path and database values take precedence.

7. Verify before committing

pnpm format:check
pnpm build

The production build must pass before deployment.

Database workflow

Development

After changing the schema:

pnpm db:push

Production

Generate and review a migration before applying it:

pnpm db:generate
# Inspect the generated SQL under drizzle/ before continuing.
pnpm db:migrate

Do not use db:push against a production database.

The drizzle/ directory is ignored in this product repository, so make sure your deployment process preserves or packages the generated migration files.

Production deployment

The project supports two primary deployment targets:

  1. Cloudflare Workers, using D1 or PostgreSQL through Hyperdrive
  2. A regular Node.js server, using SQLite, PostgreSQL, MySQL, or Turso

Cloudflare Workers is the recommended target for this template.

Deploy to Cloudflare Workers

In Claude Code or another compatible agent environment, run:

/deploy-cloudflare

The project skill performs the full idempotent deployment flow:

  • verifies the local build and Wrangler login
  • creates or reuses D1/Hyperdrive resources
  • generates and applies migrations
  • seeds RBAC
  • creates and uploads AUTH_SECRET and CONFIG_ENCRYPTION_KEY
  • configures the production URL
  • asks for confirmation before the final deployment
  • optionally creates or promotes the first super_admin
  • smoke-tests the deployed application

Re-running the skill updates the existing deployment without recreating resources.

Manual Cloudflare deployment with D1

The following commands assume macOS or Linux.

1. Authenticate and create the working configuration

npx wrangler login
cp wrangler.example.jsonc wrangler.jsonc

wrangler.jsonc is intentionally ignored by Git because it contains the real resource IDs and deployment URL. Do not edit generated files under .output/.

2. Create the D1 database

npx wrangler d1 create my-image-generator-db

Update wrangler.jsonc with:

  • your Worker name
  • the returned D1 database_id
  • the chosen database_name
  • vars.DATABASE_PROVIDER set to d1
  • a D1 binding named DB
  • migrations_dir set to drizzle

3. Configure the production URL

Create .env.production:

VITE_APP_URL=https://my-image-generator.<your-subdomain>.workers.dev
VITE_APP_NAME=My AI Image Generator

Set the same VITE_APP_URL and VITE_APP_NAME under vars in wrangler.jsonc. The URL must be correct in both places because it is used for trusted auth origins, callbacks, canonical URLs, and server-side runtime fallbacks.

For a custom domain, add:

"routes": [
  {
    "pattern": "images.example.com",
    "custom_domain": true
  }
]

Then use https://images.example.com as VITE_APP_URL. The domain or its parent zone must already be in the same Cloudflare account.

4. Generate and apply D1 migrations

DATABASE_PROVIDER=d1 pnpm db:setup
pnpm db:generate

Review the SQL under drizzle/, then apply it remotely:

npx wrangler d1 migrations apply my-image-generator-db --remote

5. Seed RBAC

pnpm rbac:init cannot connect directly to a remote D1 binding. Seed a local Wrangler D1 database, export the RBAC rows, and import them remotely:

npx wrangler d1 migrations apply my-image-generator-db --local

LOCAL_D1=$(find .wrangler/state -name "*.sqlite" -path "*d1*" | head -1)
DATABASE_PROVIDER=sqlite DATABASE_URL="file:$LOCAL_D1" pnpm rbac:init

sqlite3 "$LOCAL_D1" ".dump role permission role_permission" \
  | grep "^INSERT INTO" \
  | sed 's/^INSERT INTO/INSERT OR IGNORE INTO/' \
  > /tmp/rbac-seed.sql

npx wrangler d1 execute my-image-generator-db \
  --remote \
  --file=/tmp/rbac-seed.sql

The sqlite3 CLI is included with macOS. On Debian/Ubuntu, install it with apt-get install sqlite3.

6. Add Worker secrets

Never place secrets in wrangler.jsonc vars; Worker vars are visible configuration, not secret storage.

openssl rand -base64 32 | npx wrangler secret put AUTH_SECRET
openssl rand -base64 32 | npx wrangler secret put CONFIG_ENCRYPTION_KEY

Keep CONFIG_ENCRYPTION_KEY stable after provider settings have been saved.

7. Build and deploy

Always use the provided deployment command:

pnpm cf:deploy

This command loads .env.production, builds with NITRO_PRESET=cloudflare_module, merges the root wrangler.jsonc into the generated Nitro configuration, and runs wrangler deploy.

After the first deployment, update .env.production and wrangler.jsonc if Wrangler assigned a different workers.dev URL, then run pnpm cf:deploy again.

8. Create the first production administrator

The easiest option is to let /deploy-cloudflare create the account.

For a manual deployment, sign up through /sign-up, then promote the user:

npx wrangler d1 execute my-image-generator-db --remote --command="
INSERT OR IGNORE INTO user_role (id, user_id, role_id)
SELECT lower(hex(randomblob(16))), u.id, r.id
FROM user u, role r
WHERE u.email = 'admin@example.com'
  AND r.name = 'super_admin'
"

Sign out and sign in again after changing a user's role.

9. Configure R2 storage

The local upload fallback writes files to public/uploads. Cloudflare Workers does not provide a persistent writable filesystem, so production image upload requires R2 or another public S3-compatible storage service.

Configure it at Admin → Settings → Storage and verify the public domain before enabling image generation.

10. Verify the deployment

curl -I https://your-production-url.example/
curl -I https://your-production-url.example/api/config/public

Both endpoints should return a successful response.

PostgreSQL on Workers with Hyperdrive

Use this option when an existing PostgreSQL database is preferred over D1.

  1. Create a Hyperdrive configuration with the direct PostgreSQL connection string:

    npx wrangler hyperdrive create my-image-generator \
      --connection-string="$DATABASE_URL"
    
  2. In wrangler.jsonc, set vars.DATABASE_PROVIDER to postgresql, remove d1_databases, and add:

    "hyperdrive": [
      {
        "binding": "HYPERDRIVE",
        "id": "the-returned-hyperdrive-id"
      }
    ]
    
  3. Put the direct PostgreSQL URL in .env.production for migration commands. Do not put it in wrangler.jsonc vars.

  4. Prepare and migrate the database:

    set -a
    . ./.env.production
    set +a
    
    DATABASE_PROVIDER=postgresql pnpm db:setup
    DATABASE_PROVIDER=postgresql pnpm db:generate
    DATABASE_PROVIDER=postgresql pnpm db:migrate
    DATABASE_PROVIDER=postgresql pnpm rbac:init
    
  5. Ensure .env.production contains DATABASE_PROVIDER=postgresql, then deploy:

    pnpm cf:deploy
    

At runtime, the application reads the connection string from the binding named exactly HYPERDRIVE. Schema migrations still connect directly to PostgreSQL; they do not run through Hyperdrive.

Deploy to a Node.js server

Use a Node deployment for a VPS, container platform, or any host that can run a persistent Node process.

PostgreSQL, MySQL, or Turso is recommended for multi-instance production deployments. SQLite is suitable only for a single instance with persistent disk.

1. Create .env.production

At minimum:

VITE_APP_URL=https://images.example.com
VITE_APP_NAME=My AI Image Generator

DATABASE_PROVIDER=postgresql
DATABASE_URL=postgresql://database-host:5432/app

AUTH_SECRET=replace-with-a-production-secret
CONFIG_ENCRYPTION_KEY=replace-with-a-stable-encryption-key

Set these values in the hosting platform's secret manager when possible. VITE_APP_URL must be present during the build because it is embedded in client metadata and auth configuration.

2. Generate and apply production migrations

Load the production environment, generate the migration, review it, and apply it:

set -a
. ./.env.production
set +a

NODE_ENV=production pnpm db:setup
NODE_ENV=production pnpm db:generate
NODE_ENV=production pnpm db:migrate
NODE_ENV=production pnpm rbac:init

3. Build

NODE_ENV=production pnpm build

4. Start

The runtime process must receive the same production environment:

set -a
. ./.env.production
set +a

NODE_ENV=production PORT=3000 pnpm start

In production, run this command through a process manager or your hosting platform. Terminate TLS at the reverse proxy and forward requests to the configured port.

5. Verify

curl -I https://images.example.com/
curl -I https://images.example.com/api/config/public

Environment variable rules

Variable Required Purpose
VITE_APP_URL Yes Public application URL, auth origin, callbacks, and SEO URLs
VITE_APP_NAME Yes Product name shown in the UI and metadata
DATABASE_PROVIDER Yes sqlite, postgresql, mysql, turso, or d1
DATABASE_URL Node/local Direct database connection string
AUTH_SECRET Yes better-auth signing/encryption secret
CONFIG_ENCRYPTION_KEY Recommended Encrypts provider secrets stored in the config table
AUTH_TRUSTED_ORIGINS Optional Extra comma-separated auth origins
VITE_DEFAULT_LOCALE Optional Default locale, normally en

Do not expose server secrets through VITE_* variables.

Common deployment problems

Problem Cause Fix
Every production request returns 500 AUTH_SECRET is missing or still a placeholder Set a real secret in the runtime environment or with wrangler secret put
Sign-in returns 403 Invalid origin The production URL was not present during the build or does not match runtime config Keep .env.production and wrangler.jsonc VITE_APP_URL synchronized, then rebuild
D1 binding "DB" not found Missing binding, wrong binding name, or placeholder database ID Configure d1_databases with binding DB and a real ID
Image upload fails on Workers The local filesystem fallback is unavailable Configure R2/S3 in Admin → Settings → Storage
Cloudflare reports a stubbed DB driver The build-time provider differs from wrangler.jsonc Correct vars.DATABASE_PROVIDER and run pnpm cf:deploy again
Admin returns 403 after a role change The current session still has old claims Sign out and sign in again
A custom domain deployment fails with “not a zone” The domain is not managed by the current Cloudflare account Add the zone or deploy to workers.dev

For live Worker errors:

npx wrangler tail

Useful commands

Command Description
pnpm dev Start the development server on port 3000
pnpm build Build the Node production bundle
pnpm start Start the generated Node server
pnpm cf:build Build with the Cloudflare module preset
pnpm cf:deploy Build and deploy to Cloudflare Workers
pnpm db:setup Copy the schema template for the selected database
pnpm db:push Synchronize a development database directly
pnpm db:generate Generate production migration SQL
pnpm db:migrate Apply production migrations to a direct database
pnpm db:studio Open Drizzle Studio
pnpm rbac:init Seed default roles and permissions
pnpm rbac:assign Assign a role to an existing user
pnpm format Format the repository
pnpm format:check Check formatting

Project structure

src/
├── blocks/             # Product and landing-page sections
├── components/         # Reusable UI and shadcn primitives
├── config/             # Environment, database schemas, and locale config
├── content/pages/      # MDX content pages
├── core/               # Auth, database, AI, payment, email, and storage
├── hooks/              # Shared client data hooks
├── lib/                # API client and application utilities
├── modules/            # Business services
└── routes/             # Pages and API routes

messages/
├── en.json             # English messages
└── zh.json             # Chinese messages

drizzle/                # Generated migration SQL
wrangler.example.jsonc  # Committed Cloudflare configuration template
wrangler.jsonc          # Ignored deployment-specific working copy

License

This is proprietary software. See LICENSE for the full license agreement.

Built with ShipAny.

开始构建你的 AI 产品

成为 ShipAny Premium 会员,获取 ShipAny 模板代码,一小时极速上线