A web UI and CLI for generating images with Cloudflare Workers AI and Google Gemini. Built with FastAPI, styled with Tailwind CSS, and deployable to Railway in one click.
- Web UI with model selection, prompt input, image preview, and download
- 11 Cloudflare models (6 free, 5 paid) + 2 Gemini models (admin-only)
- Model comparison mode (test same prompt across 2-3 models side by side)
- Prompt history with reusable recent prompts
- Gallery with favorites, tags, and filtering
- Shareable public links for individual images
- Usage dashboard with daily stats and model usage breakdown
- Toast notifications for all actions
- Neobrutalist UI with dark/light mode toggle
- CLI scripts for quick one-off generation
- Black image / content filter detection
- Cloudinary-backed image storage (CDN-hosted, persistent across deploys)
- Self-service forgot password flow with email reset links
- User authentication (bcrypt-hashed passwords, session cookies)
- Admin roles (Gemini restricted, rate limit exempt)
- CSRF protection on all mutations
- Rate limiting (5 image generations per 5 minutes per user)
- Security headers (CSP, HSTS, X-Frame-Options, etc.)
- One-click Railway deployment
git clone https://github.com/nodelabstudio/gemini-n-cloudflare-imagegen-ai.git
cd gemini-n-cloudflare-imagegen-ai
pip install -r requirements.txtCreate a .env file in the project root:
# Cloudflare (free)
CF_ACCOUNT_ID=your-account-id
CF_API_TOKEN=your-api-token
# Gemini (optional)
GEMINI_API_KEY=your-gemini-keyRun the web UI:
uvicorn app:app --reloadOpen http://localhost:8000 in your browser.
-
Push this repo to GitHub
-
Go to railway.com and create a new project from your repo
-
Click + New > Database > PostgreSQL to add a database
-
Railway auto-injects
DATABASE_URLinto your app -
Add your environment variables in the Railway dashboard under Variables:
CF_ACCOUNT_ID,CF_API_TOKEN(Cloudflare)GEMINI_API_KEY(Google, optional)SESSION_SECRET(generate withpython3 -c "import secrets; print(secrets.token_hex(32))")SMTP_HOST,SMTP_PORT,SMTP_USER,SMTP_PASS,FROM_EMAIL(for password reset emails — see below)CLOUDINARY_CLOUD_NAME,CLOUDINARY_API_KEY,CLOUDINARY_API_SECRET(image storage — see cloudinary.com)
-
Important: Link the Postgres service to your web service so
DATABASE_URLis auto-injected (or add it manually). Without this, the app falls back to SQLite which is wiped on every deploy. -
Railway auto-detects the
Procfileand deploys
Password reset emails are sent via SMTP. We use Resend (free tier: 100 emails/day).
- Sign up at resend.com and verify your sending domain
- Add these variables in Railway:
SMTP_HOST=smtp.resend.comSMTP_PORT=587SMTP_USER=resendSMTP_PASS=re_your_api_keyFROM_EMAIL=noreply@yourdomain.com
Without SMTP configured, the app still works — reset links are logged to the server console instead of emailed.
The database table is created automatically on first startup. Locally it uses SQLite (images.db) so you don't need PostgreSQL for development.
| Key | Model | Tier |
|---|---|---|
flux-schnell |
FLUX.1 Schnell (default) | Free |
sdxl |
Stable Diffusion XL | Free |
dreamshaper |
DreamShaper 8 LCM | Free |
sd-lightning |
SDXL Lightning | Free |
sd-img2img |
SD v1.5 Img2Img | Free |
sd-inpaint |
SD v1.5 Inpainting | Free |
flux-2-dev |
FLUX.2 Dev (best quality) | Paid |
flux-2-klein-4b |
FLUX.2 Klein 4B | Paid |
flux-2-klein-9b |
FLUX.2 Klein 9B | Paid |
phoenix |
Leonardo Phoenix | Paid |
lucid |
Leonardo Lucid Origin | Paid |
| Key | Model |
|---|---|
gemini-2.5-flash |
Gemini 2.5 Flash |
gemini-3.1-flash |
Gemini 3.1 Flash (Preview) |
You can also generate images from the command line:
# Cloudflare
python3 cloudflare_image_gen.py "A lighthouse at sunset, digital art"
python3 cloudflare_image_gen.py --model=dreamshaper "your prompt"
python3 cloudflare_image_gen.py --models
# Gemini
python3 gemini_image_gen.py "your prompt"
python3 gemini_image_gen.py --diagnose- Sign up at dash.cloudflare.com (no credit card)
- Copy your Account ID from the dashboard sidebar
- Create an API token at dash.cloudflare.com/profile/api-tokens using the "Workers AI" template
- Get an API key at aistudio.google.com/apikey
- For image generation, you may need to link a billing account (no minimum spend)
- Authentication: Username/password with bcrypt-hashed passwords stored in PostgreSQL
- Password Reset: Self-service forgot password via email (SMTP through Resend)
- Sessions: Signed cookies (7-day expiry, SameSite=Lax, Secure flag in production)
- CSRF: Token-based protection on all POST/DELETE endpoints
- Rate Limiting: 5 image generations per 5 minutes per user (slowapi/limits)
- Headers: CSP, X-Frame-Options DENY, X-Content-Type-Options, HSTS (in production), Referrer-Policy, Permissions-Policy
- Add a custom domain to your Railway app (Settings > Networking > Custom Domain)
- In Cloudflare DNS, add a CNAME record pointing to your Railway domain
- Enable the orange cloud (Proxy) for DDoS protection, WAF, and SSL termination
- Under Security > WAF, enable managed rulesets for additional protection
- Backend: FastAPI + Uvicorn
- Frontend: Tailwind CSS (CDN)
- Auth: passlib + bcrypt, Starlette sessions
- Email: Resend (SMTP)
- Database: PostgreSQL (Railway) / SQLite (local dev)
- Image Storage: Cloudinary (CDN)
- Providers: Cloudflare Workers AI, Google Gemini
- Deployment: Railway
