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
Prepare your Django project for production.
Add PostgreSQL dependency and database config.
Configure static files and WhiteNoise.
Create a
requirements.txt,Procfile, andruntime.txtPush your code to GitHub (or connect a repo)
Create a Railway project and add a PostgreSQL plugin.
Set environment variables on Railway (DATABASE_URL, SECRET_KEY, DEBUG, ALLOWED_HOSTS)
Deploy and run migrations.
Collect static files and create a superuser.
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:
gunicorn— WSGI HTTP server for running Django in production.psycopg2-binary— PostgreSQL adapter for Python.dj-database-url— Parse DATABASE_URL into DjangoDATABASESconfig.python-dotenv— Load.envlocally (optional).whitenoise— Serve static files efficiently without a separate CDN during initial setup.
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
Sign in to Railway.app (or create an account).
Click New Project → Deploy from GitHub repo and connect your repository.
After creating the project, add a PostgreSQL plugin:
In the Railway dashboard, click Add Plugin → Postgres.
Railway provisions the database and provides a
DATABASE_URLvariable.
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:
DATABASE_URL— provided automatically by the Postgres pluginSECRET_KEY— a secure secret for DjangoDEBUG— set toFalsein productionALLOWED_HOSTS— set to your Railway domain (e.g.,your-project.up.railway.app) or*for testing
Example:
| KEY | VALUE |
|---|---|
| DATABASE_URL | (auto from Postgres plugin) |
| SECRET_KEY | somelongrandomsecret |
| DEBUG | False |
| ALLOWED_HOSTS | your-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)
Open Railway project → Plugins → Postgres (or click the project) → Run a new job or use the Railway CLI.
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
OperationalError: could not connect to server: CheckDATABASE_URLand Postgres plugin status.ModuleNotFoundError: Ensure all packages are inrequirements.txtand Railway installed them during build.Static files 404: Run
collectstaticand confirmSTATIC_ROOTandwhitenoisesettings.DisallowedHost: Add your Railway domain to
ALLOWED_HOSTS.500 errors after deploy: Check Railway logs (Build & Deployment logs) for stack traces.
14. Monitoring, Logs, and Health Checks
Use the Railway logs tab to monitor runtime errors and build logs.
Add health-check endpoints to your Django app (e.g.,
/healthz) and use external monitoring.For scaling, Railway provides options to increase resources or connect to a managed CDN.
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
Set
DEBUG=Falsein production.Keep
SECRET_KEYsecret and never commit it.Use HTTPS (Railway handles TLS for the default domain).
Use environment-specific settings or a configuration library.
Offload media to a persistent storage service (S3).
Quick Checklist Before Deploying
requirements.txtupdatedProcfilepresentruntime.txtpresent (optional)DATABASESusesdj-database-urlwhitenoisemiddleware configuredSECRET_KEY,DEBUG,ALLOWED_HOSTSset as env varsStatic files collected
Migrations applied
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.

Join the conversation! Your thoughts help the community grow.