YouTip LogoYouTip

Django Blog Deploy

Bundle and Deploy β€” Deploy to Railway |

\n\n

In this chapter, you will learn how to configure a production environment and deploy your Django blog application to Railway, obtaining a publicly accessible link.

\n\n
\n\n

Production Environment Configuration

\n\n

In the development environment, DEBUG=True, and Django displays detailed error messages and the debug page.

\n\n

In production, DEBUG must be disabled, and security settings must be configured correctly.

\n\n

Production Configuration in settings.py

\n\n

Example

\n\n
# File path: blog_project/settings.py\n\nimport os\n\n# Security key is read from environment variable (do NOT hardcode in code)\nSECRET_KEY = os.environ.get('SECRET_KEY', 'Default Secret Key for Development Environment')\n\n# DEBUG is controlled via environment variable\nDEBUG = os.environ.get('DEBUG', 'True').lower() == 'true'\n\n# Allowed hostnames\nALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', '127.0.0.1,localhost').split(',')\n\n# Static files collection directory\nSTATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')  # staticfiles/ under project root\nSTATIC_URL = '/static/'\n
\n\n
\n

SECRET_KEY is Django’s most critical security key, used to encrypt sessions, CSRF tokens, etc. It must never be hardcoded in code or committed to Git. In production, inject it via environment variables.

\n
\n\n
\n\n

Dependency Management and requirements.txt

\n\n

Generate a dependency list; the deployment platform uses it to install required packages.

\n\n
(venv) $ pip freeze > requirements.txt\n
\n\n

Check the file contents to ensure it includes the following key dependencies:

\n\n
Django>=5.0,=21.0  # production-grade WSGI server\nwhitenoise>=6.0  # static file serving (optional)\n
\n\n

If gunicorn is missing, install it first:

\n\n
(venv) $ pip install gunicorn\n(venv) $ pip freeze > requirements.txt\n
\n\n
\n\n

Configure Gunicorn + Whitenoise

\n\n

Django’s built-in runserver is unsuitable for production.

\n\n

Gunicorn is a production-grade WSGI server for Python, handling concurrent requests.

\n\n

Whitenoise enables Gunicorn to serve static files (CSS, JS, images) directly.

\n\n

Example

\n\n
# File path: blog_project/settings.py\n\n# Whitenoise middleware must be placed AFTER SecurityMiddleware and BEFORE other middleware\nMIDDLEWARE = [\n    'django.middleware.security.SecurityMiddleware',\n    'whitenoise.middleware.WhiteNoiseMiddleware',  # New: static files middleware\n    'django.contrib.sessions.middleware.SessionMiddleware',\n    'django.middleware.common.CommonMiddleware',\n    'django.middleware.csrf.CsrfViewMiddleware',\n    'django.contrib.auth.middleware.AuthenticationMiddleware',\n    'django.contrib.messages.middleware.MessageMiddleware',\n    'django.middleware.clickjacking.XFrameOptionsMiddleware',\n]\n
\n\n

Create a Procfile in the project root to tell Railway how to start the app:

\n\n
web: gunicorn blog_project.wsgi --log-file -\n
\n\n
\n\n

Collect Static Files

\n\n

In production, Django does not serve static files automatically. Use collectstatic to gather them into a unified directory.

\n\n
(venv) $ python manage.py collectstatic\n
\n\n

This command copies static files from the admin backend and your blog app into the STATIC_ROOT directory (staticfiles/).

\n\n
\n

In development, you usually don’t need to run collectstatic (Django automatically finds static files in each app’s static/ directory). However, you must run it before deployment to ensure all static assets are centralized for the web server.

\n
\n\n
\n\n

Push Project to GitHub

\n\n

Create .gitignore

\n\n

Ensure sensitive and temporary files are not committed:

\n\n
venv/\n__pycache__/*.pyc\ndb.sqlite3\nstaticfiles/\n.env\n
\n\n

Push to GitHub

\n\n
$ git init\n$ git add .\n$ git commit -m "Initialize Django Blog Project"\n$ git branch -M main\n$ git remote add origin https://github.com/your-username/django-blog.git\n$ git push -u origin main\n
\n\n
\n\n

Railway Deployment

\n\n

Railway is an emerging cloud deployment platform with strong support for full-stack apps like Django.

\n\n

Deployment Steps

\n\n
    \n
  1. Visit railway.app and log in with your GitHub account.
  2. \n
  3. Click "New Project" β†’ "Deploy from GitHub repo" β†’ select the django-blog repository.
  4. \n
  5. Railway automatically detects the Procfile and recognizes the startup command.
  6. \n
  7. In the Variables section, set environment variables.
  8. \n
  9. Click Deploy and wait for the build and deployment to complete.
  10. \n
\n\n

Environment Variable Configuration

\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
Variable NameValueDescription
SECRET_KEYA randomly generated long stringDjango security key
DEBUGFalseDisable debug mode
ALLOWED_HOSTS.railway.appAllow access from Railway domains
\n\n

Quickly generate a SECRET_KEY:

\n\n
$ python -c "import secrets; print(secrets.token_urlsafe(50))"\n
\n\n

After successful deployment, you’ll get a link like: https://django-blog.up.railway.app

\n\n
\n

Railway has limited free tier (e.g., $5/month or 500 hours). If you’re only testing/learning, remember to pause the project after usage. Heroku has discontinued its free plan, so Railway is recommended in this tutorial as an alternative.

\n
\n\n
\n\n

Next Learning Directions

\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
Learning DirectionWho It’s ForRecommended Starting Point
Django REST Framework (DRF)Those needing an API backend for frontend frameworks (Vue3/React)Learn Serializer + ViewSet; convert the blog into an API service
PostgreSQLThose needing a production-grade databaseReplace SQLite; use django-environ to manage database configuration
Celery Async TasksThose needing background tasks (e.g., sending emails, generating reports)Integrate Redis + Celery to implement an async task queue
Django + Vue3/React (Frontend-Backend Separation)Those wanting a frontend-backend decoupled architectureUse DRF for the API backend, Vue3/React for the frontend, and communicate via fetch
\n\n
\n\n

Chapter Summary

\n\n

In this chapter, you completed the final step: configuring the production environment (SECRET_KEY/DEBUG/ALLOWED_HOSTS), generating requirements.txt, configuring Gunicorn + Procfile, pushing to GitHub, and deploying to Railway with one click.

← Flask Blog Jinja2 TemplatesDjango Blog Forms Favorites β†’