Every SaaS product needs the same foundation: user authentication, payment processing, an admin panel, database models, and a deployment pipeline. Building those from scratch takes weeks of work before you write a single line of product-specific logic. ShipKit is a production-tested FastAPI boilerplate that gives you all of that infrastructure out of the box, extracted from the architecture running six live Wigley Studios products. This guide walks you through getting from a fresh download to a running SaaS backend.
What You Get
ShipKit is not a framework or a library you install as a dependency. It is a complete project you download and build on top of. When you open the project for the first time, you have a working FastAPI application with:
- JWT authentication with dual-key rotation, token refresh, and protected route guards
- Stripe Checkout integration with webhook signature validation and idempotent event processing
- Admin panel foundation with session-based auth and customer management views
- MySQL + SQLAlchemy models with typed ORM patterns and migration-ready schema design
- Structured project layout with modular routing, dependency injection, and clear module boundaries
The Professional tier adds deploy scripts, CI/CD templates, multi-tenant scaffolding, Redis caching, background worker queues, rate limiting, and transactional email.
Production-Tested Architecture
Every pattern in ShipKit was extracted from backends that handle real Stripe transactions, serve real API traffic, and run on real infrastructure. The gap between boilerplate and production code is already closed.
Step 1: Set Up Your Environment
1 Prerequisites
You need Python 3.10+, MySQL 8.0+ (or MariaDB), and pip. If you are using the Professional tier, you will also need Redis 5.0+ installed locally for caching and rate limiting. A Stripe account (test mode is fine for development) is needed to configure payment processing.
After downloading ShipKit from your purchase confirmation, unzip the project and create a virtual environment:
- Create and activate a Python virtual environment in the project root
- Install dependencies from the included
requirements.txtwith pinned versions - Copy the
.env.examplefile to.envand fill in your database credentials, JWT secret, and Stripe keys
The .env.example file documents every variable with comments explaining what each one controls. The only values you must change before the app will start are the database connection string and the JWT secret key.
Step 2: Configure Your Database
2 Database Setup
Create a MySQL database and user for your project. ShipKit's config reads the connection string from the DATABASE_URL environment variable. The included SQLAlchemy models create tables automatically on first run, or you can use the migration scripts for more controlled schema management.
The database layer uses SQLAlchemy with typed models. Each model follows patterns tested across six production applications: explicit column types, proper indexing, and foreign key relationships that work with MySQL's InnoDB engine. Connection pool sizing is pre-configured for typical VPS workloads but adjustable through environment variables.
Step 3: Wire Up Authentication
3 JWT Auth
ShipKit's auth system is ready to use immediately. Set your JWT_SECRET_KEY in .env, and the route guards, token generation, and refresh logic all work. The dual-key design means you can rotate secrets later without logging out every active user.
The auth module includes registration, login, token refresh, and logout endpoints. Protected routes use a dependency that validates the JWT, checks the token blacklist, and returns the current user. Adding a new protected endpoint is one decorator:
- Import the
get_current_userdependency - Add it as a parameter to your route function
- The user object is available in the function body with typed fields
Token blacklisting on logout uses Redis when available, with an in-memory fallback. This prevents revoked tokens from being reused even if the user copies them before logging out.
Step 4: Connect Stripe
4 Stripe Integration
Add your STRIPE_SECRET_KEY and STRIPE_WEBHOOK_SECRET to .env. The checkout endpoint creates payment sessions, and the webhook handler validates signatures, deduplicates events, and processes them with retry logic. Dead-letter handling prevents silent payment failures.
ShipKit ships with payment-mode Checkout Sessions. To add subscription billing, you extend the existing checkout handler with Stripe's subscription-mode parameters. The webhook handler already processes checkout.session.completed events and can be extended to handle customer.subscription.updated, invoice.payment_failed, and other subscription lifecycle events.
The webhook architecture follows a validate-enqueue-respond pattern: validate the Stripe signature, persist the event to a database queue, return 200 immediately, and process asynchronously. This prevents webhook timeouts and ensures no payment event is lost, even under heavy load.
Step 5: Build Your Product Logic
5 Add Your Modules
With auth, payments, and admin already handled, you can focus entirely on what makes your product unique. Create a new module directory, define your models and routes, and register the router in the main application. ShipKit's modular structure keeps your code separate from the infrastructure code.
The project layout uses FastAPI's router system with clear boundaries between modules. Each module gets its own directory with routes, models, and schemas. Adding a new module follows a consistent pattern:
- Create a directory under
app/for your module - Define SQLAlchemy models for your domain objects
- Create Pydantic schemas for request and response validation
- Write route handlers using the existing auth dependencies
- Register the router in the main app with a URL prefix
Because every module follows the same structure, navigating the codebase stays intuitive as your application grows. New developers can look at any existing module to understand the pattern.
Step 6: Deploy (Professional Tier)
6 VPS Deployment
The Professional tier includes systemd service definitions and nginx reverse-proxy configurations. These are the actual configs used in production, not generic templates. Connection pool sizing, SSL termination, and health check endpoints are already configured.
Deployment to a VPS follows a straightforward process:
- Provision a VPS with Python 3.10+, MySQL, Redis, and nginx
- Upload the project and create a virtual environment on the server
- Configure the production
.envwith live credentials - Install the systemd service file to run the FastAPI app as a background process
- Configure nginx as a reverse proxy with SSL termination via Let's Encrypt
- Start the service and verify the health check endpoint responds
The included CI/CD pipeline templates automate the deploy process for subsequent updates. Push to your main branch, and the pipeline handles file upload, dependency installation, service restart, and health verification.
Starter vs Professional: Which Tier Fits
| Capability | Starter ($29) | Professional ($79) |
|---|---|---|
| FastAPI structure & routing | ✓ | ✓ |
| JWT auth & protected routes | ✓ | ✓ |
| Stripe Checkout | ✓ | ✓ |
| Admin panel foundation | ✓ | ✓ |
| MySQL + SQLAlchemy models | ✓ | ✓ |
| VPS deploy scripts | — | ✓ |
| CI/CD pipeline templates | — | ✓ |
| Multi-tenant scaffolding | — | ✓ |
| Redis caching & rate limiting | — | ✓ |
| Background worker queues | — | ✓ |
| Transactional email | — | ✓ |
If you are building a side project or validating an idea, Starter gives you everything needed to build and test locally. If you plan to deploy to production and need operational infrastructure from the start, Professional saves you from rebuilding the deploy pipeline, caching layer, and background processing that every scaling SaaS eventually needs.
Upgrade Path
Start with Starter and upgrade to Professional later if you need the additional infrastructure. Contact support for a difference-priced upgrade checkout so you only pay the gap.
Skip the Setup
Auth, billing, admin, and deploy — already built, already tested, already shipping. Start building what makes your product different.
Explore ShipKit