Packaging and Going Live — Deploying to Railway

In this chapter, you will learn about FastAPI production environment configuration and deploy the blog to production using Railway.


Production environment configuration management

(venv) $ pip install pydantic-settings python-dotenv

Example

# File path: config.py
from pydantic_settings import BaseSettings

class Settings(BaseSettings):
    """Application configuration (automatically read from .env file)"""
    app_name: str = "EXAMPLE blog"
    debug: bool = False
    secret_key: str = "dev-secret-key-change-me"
    database_url: str = "sqlite:///./blog.db"
    access_token_expire_minutes: int = 60 * 24 * 7   # 7 days

    class Config:
        env_file = ".env"     # Specify environment variable file

settings = Settings()

Create.envFile:

SECRET_KEY=a1b2c3d4...your-real-secret-key
DATABASE_URL=sqlite:///./blog.db
DEBUG=False

Generate dependency files

(venv) $ pip freeze > requirements.txt

confirmprotectcontainsCore Dependencies:fastapi、uvicorn、sqlalchemy、jinja2、alembic、passlib、python-jose、python-multipart、sqladmin、pydantic-settings.


Configure the Procfile and startup command

FastAPI uses an ASGI server, unlike Flask/Django's WSGI:

web: uvicorn main:app --host 0.0.0.0 --port $PORT

If multiple workers are needed (recommended for production):

web: gunicorn -k uvicorn.workers.UvicornWorker -w 4 main:app

WSGI vs ASGI:Django/Flask use Gunicorn(WSGI Server),FastAPI use Uvicorn(ASGI Server)。Gunicorn book身Yes WSGI, butCan be accessed throughuvicorn.workers.UvicornWorkerRun ASGI application.


Push to GitHub

$ git init
$ echo "venv/" > .gitignore
$ echo "__pycache__/" >> .gitignore
$ echo "*.pyc" >> .gitignore
$ echo ".env" >> .gitignore
$ git add .
$ git commit -m "初始化 FastAPI 博客项目"
$ git branch -M main
$ git remote add origin https://github.com/你的用户名/fastapi-blog.git
$ git push -u origin main

Railway Deployment

  1. Visitrailway.app, log in with GitHub
  2. New Project → Deploy from GitHub repo → Select fastapi-blog
  3. Railway automatically detects Procfile
  4. Set environment variables in Variables
  5. Click Deploy

Environment variable configuration

Variable NameValueDescription
SECRET_KEYRandomly generated long stringJWT signing key
DATABASE_URLInjected by RailwayProduction database

After successful deployment, you'll get a link. Visit /docs to see the Swagger documentation, and visit /admin to access the admin panel.


Framework comparison

FeaturesFastAPIDjangoFlask
ORMSQLAlchemyDjango ORM (built-in)Flask-SQLAlchemy
Data validationPydanticDjango FormsFlask-WTF
Route organizationAPIRouterurls.pyBlueprint
User AuthenticationJWT + OAuth2Session Auth (built-in)Flask-Login(Session)
Database MigrationsAlembicmakemigrations / migrateFlask-Migrate
Admin PanelsqladminDjango AdminFlask-Admin
API Documentation/docs (auto)Requires drf-spectacularRequires Flasgger
ServerUvicorn(ASGI)Gunicorn(WSGI)Gunicorn(WSGI)

Next learning directions

Learning DirectionWho It's ForRecommended Starting Point
Async SQLAlchemyNeed higher concurrency performanceSwitch synchronous Session to AsyncSession
FastAPI + Vue3/React Frontend/Backend SeparationSPA + API architectureReplace Jinja2 templates with Vue3/React, with FastAPI pure as the API backend.
WebSocketNeed real-time push (chat, notifications)FastAPI natively supports WebSocket: @app.websocket()
PostgreSQLProduction-grade databaseReplace DATABASE_URL, install asyncpg or psycopg2
other extensions