How to Serve media files on render.com for Django app deployed?

`Below is following render.com documentation for serving static and media when deploying Django webapp. Everything works, except when you upload a profile picture. Below, setting.py, build.sh and render.yaml code. It was deployed via blueprint instance with PostgreSQL. Also useing PGAdmin 4 GUI

If you spot an issue, great. If not I have spent A week on my Linux/Ubuntu machine on my wondows laptop trying to get Nginx to server the media files.

https://djangocareershifterswebsite.onrender.com (with sqlite 3 db) https://careershiftforum.onrender.com (with postgresql db)

  1. setting.py
import os
import dj_database_url
from django.core.management.utils import get_random_secret_key

# Generate or retrieve SECRET_KEY from environment variables
SECRET_KEY = os.getenv('DJANGO_SECRET_KEY', default=get_random_secret_key())

# Define BASE_DIR to point to the root directory of your Django project
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

DEBUG = os.getenv("DEBUG", "False").lower() == "true"

ALLOWED_HOSTS = ['careershiftforum.onrender.com', 'localhost', '127.0.0.1']

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'base.apps.BaseConfig',
    'rest_framework',
    'corsheaders',
]

AUTH_USER_MODEL = 'base.User'

MIDDLEWARE = [
    '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 = 'careershiftforum.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'careershiftforum.wsgi.application'

# Use dj_database_url to parse the DATABASE_URL environment variable
DATABASE_URL = os.getenv('DATABASE_URL')

DATABASES = {
    'default': dj_database_url.config(default=DATABASE_URL)
}


STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

# Whitenoise configuration for serving static files in production
if not DEBUG:
    STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
    STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

# CORS settings (allow all origins for testing purposes)
CORS_ALLOW_ALL_ORIGINS = True
  1. render.yaml file
databases:
  - name: postgres
    plan: free
    databaseName: ####
    user: ####

services:
  - type: web
    plan: free
    name: careershiftforum
    runtime: python
    buildCommand: "./build.sh"
    startCommand: "python -m gunicorn careershiftforum.asgi:application -k uvicorn.workers.UvicornWorker"
    envVars:
      - key: DATABASE_URL
        fromDatabase:
          name: postgres
          property: connectionString
      - key: SECRET_KEY
        generateValue: true
      - key: WEB_CONCURRENCY
        value: 4

  1. build.sh
#!/usr/bin/env bash
# Exit on error
set -o errexit

# Modify this line as needed for your package manager (pip, poetry, etc.)
pip install -r requirements.txt

# Convert static asset files
python manage.py collectstatic --no-input

# Apply any outstanding database migrations
python manage.py migrate

Serving files with nginx: Main issue retrieving SSL scertificates from render.com/access denied

Nginx Configuration: sudo nano /etc/nginx/sites-available/careershiftforum

Redirect HTTP to HTTPS

server {
    listen 80;
    server_name careershiftforum.onrender.com;

    return 301 https://$host$request_uri;
}

Serve HTTPS requests

server {
    listen 443 ssl;
    server_name careershiftforum.onrender.com;

    ssl_certificate /etc/nginx/ssl/careershiftforum.onrender.com.crt;
    ssl_certificate_key /etc/nginx/ssl/careershiftforum.onrender.com.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        alias /var/www/careershiftforum/static/;
    }

    location /media/ {
        alias /var/www/careershiftforum/media/;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/run/gunicorn.sock;
    }

    error_page 404 /404.html;
    location = /404.html {
        internal;
    }

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        internal;
    }
}

Enable the Site Configuration:

sudo ln -s /etc/nginx/sites-available/careershiftforum /etc/nginx/sites-enabled/

Create Directories and Set Permissions: Ensure the directories for your website, static, and media files exist and set the correct permissions.

sudo mkdir -p /var/www/careershiftforum/static
sudo mkdir -p /var/www/careershiftforum/media
sudo chown -R www-data:www-data /var/www/careershiftforum
sudo chmod -R 755 /var/www/careershiftforum

Install SSL Certificate:

sudo mkdir -p /etc/nginx/ssl
sudo cp /path/to/your/certificate.crt /etc/nginx/ssl/careershiftforum.onrender.com.crt
sudo cp /path/to/your/private.key /etc/nginx/ssl/careershiftforum.onrender.com.key

Gunicorn Socket Configuration: Ensure Gunicorn is set up to serve your Django application and create a socket file.

sudo nano /etc/systemd/system/gunicorn.service

ini
Copy code
[Unit]
Description=gunicorn daemon
After=network.target

[Service]

User=www-data
Group=www-data
WorkingDirectory=/path/to/your/django/project
ExecStart=/path/to/your/venv/bin/gunicorn \
          --access-logfile - \
          --workers 3 \
          --bind unix:/run/gunicorn.sock \
          yourproject.wsgi:application

WantedBy=multi-user.target

Reload the systemd daemon and start the Gunicorn service:


sudo systemctl daemon-reload
sudo systemctl start gunicorn
sudo systemctl enable gunicorn

Test Nginx Configuration: Test the configuration to ensure there are no syntax errors.

sudo nginx -t

Res tart Nginx: Restart Nginx to apply the changes.

Open your browser and navigate to https://careershiftforum.onrender.com/media/your-uploaded-file.jpg

404 error, and nginx failed to get access to render.com! Please advise.

I tried django doumentaion, render.com dumentaion and nginx. Media not being saved or even loaded when profile pic is updated. Nginx configuraion access issue.`

Back to Top