DEV Community

Cover image for Building a Complete Social Media Backend with Django - Part 2: Development Environment Setup
Samwit Adhikary
Samwit Adhikary

Posted on

Building a Complete Social Media Backend with Django - Part 2: Development Environment Setup

Ready to get your hands dirty with code? In this tutorial, we'll set up a complete development environment that mirrors production infrastructure. By the end, you'll have Django, PostgreSQL, Redis, and all dependencies running locally in under 15 minutes.

🎯 What You'll Accomplish

  • 🐳 Docker-based setup: One command to rule them all
  • πŸ—„οΈ PostgreSQL database: Production-grade data storage
  • πŸ”΄ Redis server: Caching and background task processing
  • βš™οΈ Django Project: Our social media backend foundation
  • πŸ”¨ Development tools: VS Code configuration and debugging

πŸš€ Setup Path 1: Docker (Recommended)

Docker gives us identical environments across all machines and operating systems. This eliminates the classic "works on my machine" problem

Prerequisites Check

Ensure you have these installed:

Step 1: Create Project Structure

# Create project directory
mkdir social-media-backend
cd social-media-backend

# Initialize Git repository
git init
Enter fullscreen mode Exit fullscreen mode

Step 2: Docker Configuration Files

Create docker-compose.yml in your project root:

version: '3.8'

services:
    db:
        image: postgres:15
        volumes:
            - postgres_/var/lib/postgresql/data/
        environment:
            POSTGRES_DB: social_media_db
            POSTGRES_USER: postgres
            POSTGRES_PASSWORD: postgres123
        ports:
            - "5432:5432"

    redis:
        image: redis:7-alpine
        ports:
            - "6379:6379"
        command: redis-server --appendonly yes
        volumes:
            - redis_/data

    web:
        build: .
        command: python manage.py runserver 0.0.0.0:8000
        volumes:
            - .:/code
        ports:
            - "8000:8000"
        depends_on:
            - db
            - redis
        environment:
            - DEBUG=1
            - DATABASE_URL=postgresql://postgres:postgres123@db:5432/social_media_db
            - REDIS_URL=redis://redis:6379/0

volumes:
    postgres_
    redis_
Enter fullscreen mode Exit fullscreen mode

Step 3: Django Project Setup

Create Dockerfile:

FROM python:3.11-slim

# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONBUFFERED 1

# Set work directory
WORKDIR /code

# Install system dependencies
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
        postgresql-client \
        build-essential \
        libpq-dev \
    && rm -rf /var/lib/apt/lists/*

# Install Python dependencies
COPY requirements.txt /code/
RUN pip install --upgrade pip
RUN pip install -r requirements.txt

# Copy project
COPY . /code/
Enter fullscreen mode Exit fullscreen mode

Create requirements.txt:

Django==4.2.7
djangorestframework==3.14.0
django-cors-headers==4.3.1
python-decouple==3.8
psycopg2-binary==2.9.9
redis==5.0.1
celery==5.3.4
django-celery-beat==2.5.0
channels==4.0.0
channels-redis==4.1.0
Pillow==10.1.0
boto3==1.34.0
django-storages==1.14.2
PyJWT==2.8.0
cryptography==41.0.0
python-multipart==0.0.6
dj-database-url==2.1.0
whitenoise==6.6.0
gunicorn==21.2.0
Enter fullscreen mode Exit fullscreen mode

Step 4: Initialize Django Project

Create the initial Django project:

# Start containers and create Django project
docker-compose run web django-admin startproject core .

# Create Django apps
docker-compose run web python manage.py startapp accounts
docker-compose run web python manage.py startapp posts
docker-compose run web python manage.py startapp connections
docker-compose run web python manage.py startapp groups
docker-compose run web python manage.py startapp stories
docker-compose run web python manage.py startapp notifications
Enter fullscreen mode Exit fullscreen mode

Step 5: Configure Django Settings

Edit core/settings.py:

import os
from decouple import config
import dj_database_url
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = config('SECRET_KEY', default='your-secret-key-here')
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = config('DEBUG', default=True, cast=bool)
ALLOWED_HOSTS = ['localhost', '127.0.0.1', '[::1]']
# Application definition
DJANGO_APPS = [
   'django.contrib.admin',
   'django.contrib.auth',
   'django.contrib.contenttypes',
   'django.contrib.sessions',
   'django.contrib.messages',
   'django.contrib.staticfiles',
]
THIRD_PARTY_APPS = [
   'rest_framework',
   'corsheaders',
   'channels',
]
LOCAL_APPS = [
   'accounts',
   'posts',
   'connections',
   'groups',
   'stories',
   'notifications',
]
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS
MIDDLEWARE = [
   'corsheaders.middleware.CorsMiddleware',
   'django.middleware.security.SecurityMiddleware',
   'whitenoise.middleware.WhiteNoiseMiddleware',
   'django.contrib.sessions.middleware.SessionMiddleware',
   'django.middleware.common.CommonMiddleware',
   'django.middleware.csrf.CsrfViewMiddleware',
   'django.contrib.auth.middleware.AuthenticationMiddleware',
   'django.contrib.messages.middleware.MessageMiddleware',
   'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'core.urls'
# Database
DATABASES = {
   'default': dj_database_url.parse(
       config('DATABASE_URL',
              default='postgresql://postgres:postgres123@localhost:5432/social_media_db')
   )
}
# Redis Configuration
REDIS_URL = config('REDIS_URL', default='redis://localhost:6379/0')
# Celery Configuration
CELERY_BROKER_URL = REDIS_URL
CELERY_RESULT_BACKEND = REDIS_URL
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = 'UTC'
# Channels Configuration
ASGI_APPLICATION = 'core.asgi.application'
CHANNEL_LAYERS = {
   'default': {
       'BACKEND': 'channels_redis.core.RedisChannelLayer',
       'CONFIG': {
           "hosts": [REDIS_URL],
       },
   },
}
# Django REST Framework
REST_FRAMEWORK = {
   'DEFAULT_AUTHENTICATION_CLASSES': [
       'rest_framework.authentication.SessionAuthentication',
   ],
   'DEFAULT_PERMISSION_CLASSES': [
       'rest_framework.permissions.IsAuthenticated',
   ],
   'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
   'PAGE_SIZE': 20
}
# CORS settings
CORS_ALLOW_ALL_ORIGINS = True  # Only for development
# Internationalization
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'
# Media files
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'
# Default primary key field type
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
Enter fullscreen mode Exit fullscreen mode

Step 6: Environment Variables

Create .env file:

SECRET_KEY=your-super-secret-key-change-this-in-production
DEBUG=True
DATABASE_URL=postgresql://postgres:postgres123@db:5432/social_media_db
REDIS_URL=redis://redis:6379/0
Enter fullscreen mode Exit fullscreen mode

Create .gitignore:

# Django
*.log
*.pyc
__pycache__/
db.sqlite3
media/
staticfiles/

# Environment variables
.env
.env.local
.env.production

# IDE
.vscode/
.idea/
*.swp
*.swo

# OS
.DS_Store
Thumbs.db

# Docker
.dockerignore
Enter fullscreen mode Exit fullscreen mode

βœ… Success! Your development environment is now running at:

πŸ› οΈ Setup Path 2: Manual Installation

Prefer full control? Here's the manual setup process.

Prerequisites Installation

macOS (using Homebrew):

# Install Homebrew if not already installed
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# Install required software
brew install python@3.11 postgresql@15 redis git
brew services start postgresql
brew services start redis
Enter fullscreen mode Exit fullscreen mode

Ubuntu/Debian:

# Update package list
sudo apt update

# Install Python and dependencies
sudo apt install python3.11 python3.11-venv python3-pip
sudo apt install postgresql postgresql-contrib redis-server
sudo apt install libpq-dev python3-dev

# Start services
sudo systemctl start postgresql
sudo systemctl start redis-server
sudo systemctl enable postgresql
sudo systemctl enable redis-server
Enter fullscreen mode Exit fullscreen mode

Windows:

Database Setup

# Create database user and database
sudo -u postgres psql

# In PostgreSQL shell:
CREATE USER social_user WITH PASSWORD 'social_password';
CREATE DATABASE social_media_db OWNER social_user;
GRANT ALL PRIVILEGES ON DATABASE social_media_db TO social_user;
\q
Enter fullscreen mode Exit fullscreen mode

Python Environment Setup

# Create virtual environment
python3.11 -m venv social_media_env
source social_media_env/bin/activate    # On Windows: social_media_env\Scripts\activate

# Upgrade pip
pip install --upgrade pip

# Install Django and create project
pip install Django==4.2.7
django-admin startproject social_media_backend
cd social_media_backend

# Install all dependencies
pip install -r requirements.txt     # Use the same requirements.txt from Docker setup
Enter fullscreen mode Exit fullscreen mode

Configure Manual Setup

Use the same Django settings configuration as the Docker setup, but update the database URL:

# In settings.py
DATABASE = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'social_media_db',
        'USER': 'social_user',
        'PASSWORD': 'social_password',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

REDIS_URL = 'redis://localhost:6379/0'
Enter fullscreen mode Exit fullscreen mode

Run Development Server

# Apply migrations
python manage.py migrate

# Create superuser
python manage.py createsuperuser

# Start development server
python manage.py runserver
Enter fullscreen mode Exit fullscreen mode

πŸ” Verification & Testing

Let's verify everything works correctly.

Basic Functionality Test

# Test database connection
docker-compose exec web python manage.py shell

# In Django shell:
>>> from django.db import connection
>>> cursor = connection.cursor()
>>> cursor.execute("SELECT version();")
>>> cursor.fetchone()
# Should return PostgreSQL version

# Test Redis Connection
>>> import redis
>>> r = redis.from_url('redis"//redis:6379/0')
>>> r.ping()
# Should return True
Enter fullscreen mode Exit fullscreen mode

API Health Check

Create core/health_check.py:

from django.http import JsonResponse
from django.db import connection
import redis
from django.conf import settings

def health_check(request):
    """Health check endpoint for development verification"""
    status = {
        'django': 'OK',
        'database': 'Unknown',
        'redis': 'Unknown'
    }

    # Test database
    try:
        with connection.cursor() as cursor:
            cursor.execute("SELECT 1")
            status['database'] = 'OK'
    except Exception as e:
        status['database'] = f'Error: {str(e)}'

    # Test Redis
    try:
        r = redis.from_url(settings.REDIS_URL)
        r.ping()
        status['redis'] = 'OK'
    except Exception as e:
        status['redis'] = f'Error: {str(e)}'

    return JsonResponse(status)
Enter fullscreen mode Exit fullscreen mode

Add to core/urls.py:

from django.contrib import admin
from django.urls import path
from .health_check import health_check

urlpatterns = [
    path('admin/', admin.site.urls),
    path('health/', health_check, name='health_check'),
]
Enter fullscreen mode Exit fullscreen mode

Visit http://localhost:8000/health/ - you should see all services as "OK".

🚨 Troubleshooting Common Issues

Port Already in Use

# Kill processes using ports
sudo lsof -ti:8000 | xargs kill -9  # Django
sudo lsof -ti:5432 | xargs kill -9  # PostgreSQL
sudo lsof -ti:6379 | xargs kill -9  # Redis
Enter fullscreen mode Exit fullscreen mode

Docker Build Issues

# Clean rebuild
docker-compose down -y
docker-compose build --no-cache
docker-compose up
Enter fullscreen mode Exit fullscreen mode

Database Connection Errors

# Reset database completely
docker-compose down -v
docker volume rm social-media-backend_postgres_data
docker-compose up --build
Enter fullscreen mode Exit fullscreen mode

Permission Issue (Linux/macOS)

# Fix file permissions
sudo chown -R $USER:$USER .
chmod -R 755 .
Enter fullscreen mode Exit fullscreen mode

🎯 Development Workflow

Your daily development routine:

# Start development environment
docker-compose up

# Run migrations after model changes
docker-compose exec web python manage.py makemigrations
docker-compose exec web python manage.py migrate

# Access Django shell
docker-compose exec web python manage.py shell

# Run tests
docker-compose exec web python manage.py test

# Stop environment
docker-compose down
Enter fullscreen mode Exit fullscreen mode

πŸ”œ What's Next in Part 3?

Now that your development environment is rock-solid, we'll dive into Django project architecture:

  • App organization: How to structure large Django projects
  • File Structure: Best practices for maintainable code
  • URL routing: Clean, scalable URL patterns
  • Settings management: Environment-specific configurations
  • Database design: Planning our social media data models

πŸ’¬ Need Help?

Drop your questions in the comments!
Common setup questions I'll answer:

  • Environment-specific configuration issues
  • Docker vs manual setup trade-offs
  • IDE configuration and debugging tips
  • Database connection troubleshooting

Environment setup complete? React with πŸš€ and let me know which setup path you chose!
Next, we will explore Django project architecture and start building our first models.
The real fun begins!!

Top comments (0)