# 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.