Introduction

Railway is a popular platform that makes it easy to deploy web apps and databases quickly. In this guide, you will learn how to deploy a Django application that uses PostgreSQL on Railway. The instructions are written in simple, natural language and include all required steps, commands, and configuration examples.

Overview of the Steps

  1. Prepare your Django project for production.

  2. Add PostgreSQL dependency and database config.

  3. Configure static files and WhiteNoise.

  4. Create a requirements.txt, Procfile, and runtime.txt

  5. Push your code to GitHub (or connect a repo)

  6. Create a Railway project and add a PostgreSQL plugin.

  7. Set environment variables on Railway (DATABASE_URL, SECRET_KEY, DEBUG, ALLOWED_HOSTS)

  8. Deploy and run migrations.

  9. Collect static files and create a superuser.

  10. Troubleshoot and monitor logs

1. Prepare Your Django Project for Production

Ensure your Django project is functioning locally and utilizes a virtual environment. Install production-ready components:

python -m venv .venv
source .venv/bin/activate  # macOS / Linux
.\.venv\Scripts\activate   # Windows
pip install django gunicorn psycopg2-binary dj-database-url python-dotenv whitenoise

Key packages explained:

2. Add PostgreSQL Dependency and Database Config

In settings.py, replace the default SQLite configuration with code that reads DATABASE_URL:

# settings.py
import os
import dj_database_url

DATABASES = {
    'default': dj_database_url.config(default='sqlite:///db.sqlite3')
}

This allows Railway to provide a DATABASE_URL environment variable that Django will use automatically.

3. Configure Static Files with WhiteNoise

Configure static files so that Django can serve them in production.

Install whitenoise (already included above) and update settings.py:

# settings.py (near top)
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
    # ... other middleware
]

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'

# Optional: compress and cache static files
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

This config reduces latency and removes the need for a separate static server for small/medium apps.

4. Create requirements.txt, Procfile, and runtime.txt

Generate requirements.txt:

pip freeze > requirements.txt

Create a Procfile (root of repo):

web: gunicorn yourprojectname.wsgi --log-file -

Create runtime.txt to pin Python version (optional but recommended):

python-3.11.6

Replace yourprojectname with the name of the Django project folder containing wsgi.py.

5. Use Environment Variables Locally (Optional)

Create a .env file for local testing (DO NOT commit .env to git):

SECRET_KEY=your_local_secret_key
DEBUG=True
DATABASE_URL=postgres://user:pass@localhost:5432/dbname

Load it locally with python-dotenv or your chosen method.

6. Push Your Code to GitHub

Railway connects to GitHub repositories. Initialize git, commit, and push:

git init
git add .
git commit -m "Prepare app for Railway deployment"
git branch -M main
git remote add origin https://github.com/your-username/your-repo.git
git push -u origin main

7. Create a Railway Project and Add PostgreSQL

  1. Sign in to Railway.app (or create an account).

  2. Click New ProjectDeploy from GitHub repo and connect your repository.

  3. After creating the project, add a PostgreSQL plugin:

    • In the Railway dashboard, click Add PluginPostgres.

    • Railway provisions the database and provides a DATABASE_URL variable.

Railway will also show project secrets under the Variables (environment) section.

8. Set Environment Variables on Railway

In the Railway project settings or environment variables UI, add the following variables:

Example:

KEYVALUE
DATABASE_URL(auto from Postgres plugin)
SECRET_KEYsomelongrandomsecret
DEBUGFalse
ALLOWED_HOSTSyour-app.up.railway.app

Note: Railway masks secret values and exposes them to the runtime.

9. Configure ALLOWED_HOSTS and DEBUG in settings.py

Read Django environment variables in settings.py:

# settings.py
import os

SECRET_KEY = os.environ.get('SECRET_KEY', 'fallback-secret')
DEBUG = os.environ.get('DEBUG', 'False') == 'True'
ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', 'localhost').split(',')

This makes your settings flexible for different environments.

10. Deploy, Run Migrations, and Collect Static Files

After Railway builds your app from the GitHub repo, you need to run migrations and collect static files.

Run migrations (Railway Console / Deploy Jobs)

You can create a deploy script in package.json or use Railway’s Web Console to run commands:

# run in Railway console or via deployment commands
python manage.py migrate
python manage.py collectstatic --noinput

Create a superuser

python manage.py createsuperuser

Railway provides a web-based shell/console where you can run these commands after deployment.

11. Using the Railway CLI (Optional)

Railway offers a CLI that can make running commands easier locally and remotely.

Install Railway CLI and login:

npm i -g railway
railway login
railway init  # link to project
railway run python manage.py migrate
railway run python manage.py collectstatic --noinput

This is helpful for automating post-deploy tasks.

12. Configure Static Media and File Uploads

If your app uses user-uploaded files (media), you should use cloud storage (S3, DigitalOcean Spaces) because Railway’s ephemeral filesystem will not persist uploads across restarts.

Example using django-storages with AWS S3:

pip install django-storages boto3

Then configure in settings.py with environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_STORAGE_BUCKET_NAME).

13. Common Errors and How to Fix Them

14. Monitoring, Logs, and Health Checks

15. Optional: Dockerize Your Django App

You can deploy with Docker for more control.

Example Dockerfile (simple):

FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
CMD ["gunicorn", "yourprojectname.wsgi", "--bind", "0.0.0.0:8000", "--log-file", "-"]

Then set Railway to deploy from Docker or use GitHub with Dockerfile present.

16. Security and Best Practices

Quick Checklist Before Deploying

Summary

Deploying a Django app with PostgreSQL on Railway is straightforward: prepare your Django settings to read DATABASE_URL, configure static files with WhiteNoise, create requirements.txt and a Procfile, push your code to GitHub, add a PostgreSQL plugin in Railway, set environment variables, run migrations, and collect static files. Use Railway’s logs and CLI for troubleshooting and automation.