From Localhost to Production: Deploying an AI Blog Generator (FastAPI + React)
Jenkins
Source: Dev.to | Jan 25, 2026 (UTC)
Part 2 of building an AI blog generator with FastAPI, React, Hugging Face, Railway, and Vercel.
This post is for developers who’ve built full-stack apps locally and want to confidently ship them to production without overengineering.
Welcome Back!
In Part 1, I built an AI-powered blog generator locally. In this post, I’ll show how I deployed the full system to production using Railway and Vercel—covering backend deployment, database setup, frontend integration, and the real issues I ran into along the way.
This was the easiest database setup I’ve ever done:
Click "New" → "Database" → "PostgreSQL"
Enter fullscreen mode
Exit fullscreen mode
Railway automatically:
Provisioned a PostgreSQL instance
Created the DATABASE_URL environment variable
Connected it to my backend service
No configuration files, no manual connection strings – just magic.
Step 3: Environment Variables
Railway makes environment management clean and secure.
I added these variables via the Railway dashboard:
HUGGINGFACE_API_KEY=hf_xxxxxxxxxxxxx HUGGINGFACE_MODEL=meta-llama/Llama-3.3-70B-Instruct ENVIRONMENT=production APP_NAME=AI Blog Generator API VERSION=1.0.0
Enter fullscreen mode
Exit fullscreen mode
Pro tip: The DATABASE_URL was automatically set when I added PostgreSQL. No manual configuration needed!
Step 4: First Deployment Attempt
I pushed my code and watched the build logs:
git add . git commit -m "Prepare for Railway deployment" git push origin main
Enter fullscreen mode
Exit fullscreen mode
Railway detected the push and started building…
And it failed. 😅
Challenge #1: Import Errors
The Problem:
ModuleNotFoundError: No module named 'app.database'
Enter fullscreen mode
Exit fullscreen mode
The Cause:
My local environment had different import paths than production.
The Solution:
I realized I needed to ensure all imports were relative to the backend directory. Updated app/main.py:
# Before (worked locally) from database import engine, Base # After (works everywhere) from app.database import engine, Base
Enter fullscreen mode
Exit fullscreen mode
Lesson learned: Always test imports from the project root!
Challenge #2: Database Tables Not Created
The Problem:
API worked, but generating blogs failed with:
relation "blog_posts" does not exist
Enter fullscreen mode
Exit fullscreen mode
The Cause:
FastAPI wasn’t creating tables on startup in production.
Access to fetch at 'https://ai-blog-generator-production-bd0c.up.railway.app/api/v1/generate' from origin 'https://frontend-ochre-rho-71.vercel.app' has been blocked by CORS policy
Enter fullscreen mode
Exit fullscreen mode
The Problem:
The backend wasn’t configured to accept requests from the Vercel domain.
Railway auto-redeployed the backend with new CORS settings.
Hard refreshed the frontend (Ctrl+Shift+R) and… Connected! The status indicator turned green!
Testing in Production
First Blog Generation
Held my breath and tried generating a blog:
Input:
Topic: The Future of Cloud Computing Tone: Professional Length: Medium Keywords: cloud, scalability, innovation
Enter fullscreen mode
Exit fullscreen mode
Clicked “Generate Blog Post”…
20 seconds later…
Success!
Title: The Future of Cloud Computing: Embracing Innovation and Scalability Word Count: 1,247 words SEO Score: 82 [Full formatted blog content displayed]
Enter fullscreen mode
Exit fullscreen mode
Everything worked:
✅ AI generation
✅ Database storage
✅ SEO scoring
✅ Copy to clipboard
✅ Download as Markdown
✅ Blog history
Performance Testing
I generated several blogs to test:
Response Times:
API health check: ~50ms
Blog generation: 25-35 seconds (AI processing)
Blog retrieval: ~100ms
Blog list: ~150ms
Database:
Tables created automatically ✅
Blogs saving correctly ✅
Queries performing well ✅
Challenges & Solutions Summary
Let me share all the issues I encountered and how I solved them:
1. Module Import Errors
Error:
ModuleNotFoundError: No module named 'app.database'
Enter fullscreen mode
Exit fullscreen mode
Solution: Ensured all imports were absolute from the project root:
from app.database import engine from app.models.blog import BlogPost from app.services.ai_service import hf_service
Enter fullscreen mode
Exit fullscreen mode
2. Database Tables Not Created
Error:
psycopg2.errors.UndefinedTable: relation "blog_posts" does not exist
Enter fullscreen mode
Exit fullscreen mode
Solution: Added lifespan context manager to create tables on startup:
Залишити відповідь