# Niblit.ai Deployment Spec: Python + Flask You are deploying a Python Flask application to Niblit.ai. Follow these instructions EXACTLY. Do not deviate. ## Requirements - Python 3.11 or 3.12 - Flask as the web framework - SQLite for any database needs (no Postgres, no MySQL) - App must listen on port 5000 - All persistent data must be stored in /data/ directory ## Required Project Structure ``` your-project/ ├── Dockerfile ← REQUIRED (use the template below exactly) ├── requirements.txt ← REQUIRED (must include flask and gunicorn) ├── app.py ← REQUIRED (your Flask application entry point) └── ... other files ``` ## Dockerfile (use this EXACTLY) ```dockerfile FROM python:3.12-slim WORKDIR /app # Install dependencies first (better caching) COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # Copy application code COPY . . # Create data directory for persistent storage RUN mkdir -p /data # Environment variables ENV PORT=5000 ENV FLASK_ENV=production ENV DATABASE_PATH=/data/app.db EXPOSE 5000 # Run with gunicorn for production CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "2", "app:app"] ``` ## requirements.txt must include ``` flask gunicorn ``` Add any other dependencies your app needs. ## Flask App Structure (app.py) Your app.py MUST have a Flask app instance named `app` at the module level: ```python from flask import Flask app = Flask(__name__) @app.route('/') def home(): return 'Hello from Niblit.ai!' if __name__ == '__main__': app.run() ``` ## Database Rules - Use SQLite ONLY - Database file MUST be stored at: `/data/app.db` - The /data directory is persistent storage — it survives restarts and redeploys - Everything outside /data is ephemeral and will be reset on redeploy Example database setup: ```python import os import sqlite3 DATABASE_PATH = os.environ.get('DATABASE_PATH', '/data/app.db') def get_db(): conn = sqlite3.connect(DATABASE_PATH) conn.row_factory = sqlite3.Row return conn def init_db(): db = get_db() db.execute(''' CREATE TABLE IF NOT EXISTS items ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ''') db.commit() db.close() # Call init_db() when your app starts ``` ## File Storage If your app handles file uploads: - Store files in `/data/uploads/` - Create the directory if it doesn't exist - Never store files in `/app/` (they will be lost on redeploy) ```python import os UPLOAD_FOLDER = '/data/uploads' os.makedirs(UPLOAD_FOLDER, exist_ok=True) ``` ## Environment Variables These are available to your app: - `PORT` - Always 5000 - `DATABASE_PATH` - Path to SQLite database (/data/app.db) - `FLASK_ENV` - Set to "production" ## What NOT to Include - No `.env` files (will be rejected) - No `node_modules/` directory - No `__pycache__/` directories - No `.git/` directory - No `venv/` or `.venv/` directories - No secret keys or API tokens in code - No external database connections (Postgres, MySQL, etc.) ## Testing Locally Before Upload 1. Build and run with Docker: ```bash docker build -t my-app . docker run -p 5000:5000 -v $(pwd)/data:/data my-app ``` 2. Visit http://localhost:5000 3. If it works, create the zip and upload to Niblit.ai. ## Creating the Upload Zip ```bash # From your project root: zip -r my-app.zip . -x "*.git*" -x "__pycache__/*" -x "*.pyc" -x ".env" -x "venv/*" -x ".venv/*" -x "data/*" ``` Upload this zip file to Niblit.ai. ## Common Errors and Fixes | Error | Fix | |-------|-----| | "Missing Dockerfile" | Add Dockerfile using template above | | "Port mismatch" | Ensure Dockerfile has `EXPOSE 5000` and gunicorn binds to 5000 | | "Missing requirements.txt" | Create file with flask and gunicorn | | "Database not persisting" | Store DB at `/data/app.db`, not `./app.db` | | "App crashes on start" | Ensure app.py has `app = Flask(__name__)` at module level | | "Module not found" | Add missing dependency to requirements.txt | | "gunicorn not found" | Add gunicorn to requirements.txt | ## Resource Limits - **Free tier**: 256MB RAM, shared CPU, 1GB storage - **Pro tier**: 512MB RAM, shared CPU, 1GB storage - **Team tier**: 1GB RAM, 2 shared CPUs, 5GB storage Free tier apps sleep after 5 minutes of no traffic and wake automatically (3-5 second cold start). ## Example App See the `example/` directory for a complete working example.