← All Stacks
📦

Django

Raw Text

✨ How to use: Copy this entire spec and paste it into your AI assistant (Claude, ChatGPT, etc.) when asking it to prepare your project for Niblit.ai deployment.

# Niblit.ai Django Stack Specification

You are deploying a Python Django application to Niblit.ai.
Follow these instructions EXACTLY. Do not deviate.

## Requirements

- Python 3.12
- Django 4.2 or higher
- gunicorn as the WSGI server
- dj-database-url for database URL configuration
- whitenoise for static file serving
- SQLite by default (stored in /data), PostgreSQL optional
- App must listen on port 8080
- All persistent data must be stored in /data/ directory

## Required Project Structure

```
your-project/
├── requirements.txt ← REQUIRED (must include django, gunicorn, dj-database-url, whitenoise)
├── manage.py ← REQUIRED (standard Django manage.py)
├── myproject/
│ ├── __init__.py
│ ├── settings.py ← REQUIRED (see settings template below)
│ ├── urls.py
│ └── wsgi.py ← REQUIRED
├── deploy.toml ← OPTIONAL (startup commands, db config)
└── ... other files
```

**Note:** You do NOT need to include a Dockerfile. Niblit.ai generates an optimised Django Dockerfile automatically.

## settings.py Template

```python
import os
import dj_database_url
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent

SECRET_KEY = os.environ.get('SECRET_KEY', 'change-me-in-production')
DEBUG = os.environ.get('DEBUG', 'False').lower() == 'true'
ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', '*').split(',')

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'whitenoise.runserver_nostatic',
'django.contrib.staticfiles',
# your apps here
]

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 = 'myproject.urls'

TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [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 = 'myproject.wsgi.application'

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

LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True

STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

MEDIA_URL = '/media/'
MEDIA_ROOT = '/data/media/'

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
```

## requirements.txt must include

```
django>=4.2
gunicorn
dj-database-url
whitenoise
```

Add any other dependencies your app needs.

## deploy.toml (optional)

You can include a `deploy.toml` at your project root to configure startup commands and database engine:

```toml
[startup]
commands = [
"python manage.py migrate --noinput",
"python manage.py collectstatic --noinput",
]

[database]
engine = "sqlite"
```

- `startup.commands`: max 10 commands, max 500 chars each
- `database.engine`: `sqlite` or `postgres`

If you don't include deploy.toml, Niblit.ai will run `migrate` and `collectstatic` automatically.

## Environment Variables

Niblit.ai sets these automatically:

| Variable | Value | Notes |
|----------|-------|-------|
| `PORT` | `8080` | Always |
| `DJANGO_SETTINGS_MODULE` | `myproject.settings` | Auto-detected from wsgi.py |
| `DATABASE_URL` | `sqlite:////data/db.sqlite3` | For SQLite |
| `SECRET_KEY` | randomly generated | 50-char URL-safe token |

You can add custom env vars in the app management dashboard.

## Database Rules

- Default: SQLite stored at `/data/db.sqlite3`
- The /data directory is persistent storage — it survives restarts and redeploys
- Everything outside /data is ephemeral and will be reset on redeploy
- Use `dj-database-url` to read the `DATABASE_URL` environment variable

## Static Files

- collectstatic runs automatically during startup
- whitenoise serves static files efficiently
- Set `STATIC_ROOT = BASE_DIR / 'staticfiles'`

## File Storage

If your app handles file uploads:
- Store files in `/data/media/`
- Set `MEDIA_ROOT = '/data/media/'`
- Never store files outside /data (they will be lost on redeploy)

## What NOT to Include

- No Dockerfile (Niblit.ai generates one for you)
- No `.env` files with secrets (use the dashboard instead)
- No `node_modules/` directory
- No `__pycache__/` directories
- No `.git/` directory
- No `venv/` or `.venv/` directories
- No `db.sqlite3` database files (will be overwritten)

## Testing Locally Before Upload

1. Create and activate a virtual environment:

```bash
python -m venv venv
source venv/bin/activate # or venv\Scripts\activate on Windows
```

2. Install dependencies:

```bash
pip install -r requirements.txt
```

3. Run locally:

```bash
python manage.py migrate
python manage.py runserver
```

4. Visit http://localhost:8000

## Creating the Upload Zip

```bash
# From your project root:
zip -r myapp.zip . \
-x "*.git*" \
-x "__pycache__/*" \
-x "*.pyc" \
-x ".env" \
-x "venv/*" \
-x ".venv/*" \
-x "db.sqlite3" \
-x "staticfiles/*" \
-x "media/*"
```

Upload this zip file to Niblit.ai.

## Common Errors and Fixes

| Error | Fix |
|-------|-----|
| "manage.py not found" | Ensure manage.py is at the zip root |
| "wsgi.py not found" | Create myproject/wsgi.py with standard Django content |
| "Missing dj-database-url" | Add `dj-database-url` to requirements.txt |
| "Missing gunicorn" | Add `gunicorn` to requirements.txt |
| "Static files not found" | Add whitenoise and set STATIC_ROOT |
| "Database not persisting" | Use DATABASE_URL env var pointing to /data/db.sqlite3 |
| "Secret key error" | Read SECRET_KEY from environment variable |
| "Module not found" | Add missing dependency to requirements.txt |

## Resource Limits

- **Starter tier**: 512MB RAM, shared CPU, 1GB storage
- **Pro tier**: 512MB RAM, shared CPU, 1GB storage

This stack requires a Starter plan or higher.

## Example App

See the `example/` directory for a complete working example.