Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.aspfox.com/llms.txt

Use this file to discover all available pages before exploring further.

Railway is the fastest path to production. It manages PostgreSQL and Redis as plugins, and deploys from your GitHub repository automatically on every push.
1

Create a Railway account and project

  1. Go to railway.app and sign up
  2. Click New Project
  3. Select Empty Project
  4. Name the project (e.g., Acme Production)
2

Add PostgreSQL

  1. In your project, click NewDatabaseAdd PostgreSQL
  2. Railway creates a PostgreSQL instance and adds it to your project
  3. Click on the PostgreSQL service → Variables tab
  4. Copy the DATABASE_URL value — you will need it shortly
3

Add Redis

  1. Click NewDatabaseAdd Redis
  2. Click on the Redis service → Variables tab
  3. Copy the REDIS_URL value
4

Deploy the API

  1. Click NewGitHub Repo
  2. Connect your GitHub account and select your repository
  3. Railway detects the Dockerfile in the project root and uses it
  4. Before the first deploy, go to the service’s Variables tab
  5. Add all required environment variables (see Environment Variables):
ASPNETCORE_ENVIRONMENT=Production
DATABASE_URL=<copied from PostgreSQL plugin>
REDIS_URL=<copied from Redis plugin>
JWT_PRIVATE_KEY=<base64 private key generate new for production>
JWT_PUBLIC_KEY=<base64 public key>
JWT_ISSUER=https://api.yourdomain.com
JWT_AUDIENCE=https://yourdomain.com
STRIPE_SECRET_KEY=sk_live_…
STRIPE_WEBHOOK_SECRET=whsec_…  (set this after registering the webhook)
STRIPE_PRO_PRICE_ID=price_…
STRIPE_BUSINESS_PRICE_ID=price_…
RESEND_API_KEY=re_…
EMAIL_FROM_ADDRESS=noreply@yourdomain.com
EMAIL_FROM_NAME=Acme
APP_URL=https://yourdomain.com
API_URL=https://api.yourdomain.com
  1. Click Deploy — Railway builds the Docker image and starts the container
5

Run migrations

  1. Install the Railway CLI: npm install -g @railway/cli
  2. Log in: railway login
  3. Link your project: railway link
  4. Run migrations against the production database:
railway run -- dotnet ef database update \
  --project src/Acme.Infrastructure \
  --startup-project src/Acme.Api
Or open a shell in the running container and run the migration:
railway shell
dotnet ef database update \
  --project src/Acme.Infrastructure \
  --startup-project src/Acme.Api
6

Run the database seeder

railway shell
dotnet run --project src/Acme.Api -- --seed-only
This creates the admin user. The --seed-only flag runs seeders and exits without starting the HTTP server.
7

Deploy the frontend

  1. In your Railway project, click NewGitHub Repo again
  2. Select the same repository, but this time set the Root Directory to frontend/
  3. Add the frontend environment variable:
VITE_API_URL=https://api.yourdomain.com
  1. Railway detects package.json and uses the Vite build command (npm run build)
  2. Set the Start Command to npx serve -s dist -l 3000
8

Configure custom domains

  1. For the API service: SettingsDomainsGenerate Domain or Add Custom Domain
  2. Add a CNAME record in your DNS pointing api.yourdomain.com to the Railway-provided domain
  3. Repeat for the frontend service at yourdomain.com or app.yourdomain.com
  4. Railway provisions SSL automatically via Let’s Encrypt
9

Register the Stripe webhook

Now that you have a production API URL:
  1. Stripe Dashboard → Developers → WebhooksAdd endpoint
  2. URL: https://api.yourdomain.com/api/v1/webhooks/stripe
  3. Select all five required events (checkout.session.completed, customer.subscription.updated, customer.subscription.deleted, invoice.payment_failed, invoice.payment_succeeded)
  4. Copy the signing secret → update STRIPE_WEBHOOK_SECRET in Railway
Railway redeploys automatically when you update environment variables.
10

Verify

  1. Open https://yourdomain.com — the login page should load
  2. Log in with admin credentials (email set via --AdminEmail at scaffold time, password Admin123!)
  3. Change the admin password immediately
  4. Test a complete checkout with a real payment method
  5. Confirm the Stripe webhook delivered successfully in the Stripe Dashboard
After verifying everything works, change the default admin password from Admin123! to something secure. Do this before announcing the application publicly.