Run Django on Falix

Django expects a manage.py and a WSGI server; the Python application runs one app.py. This build bridges the two — migrations on start, then runserver — verified serving in a container, and honest about where the development server stops being enough.

Django is a batteries-included web framework, and it makes an assumption the Falix Python application doesn't share: that you'll run it through manage.py and, in production, a separate WSGI server. The Python application instead runs one entry file — app.py. This guide bridges that gap honestly: a minimal Django project whose app.py applies migrations and then starts Django's own server, verified serving in a container. It also tells you plainly where this approach stops being the right one.

At a glance
You need A server running the Python application (default Python version is fine)
Plan Any plan — free runs while your session timer has time left, premium runs 24/7
Time About thirty minutes
No server yet? Create your first app server

For the Python fundamentals this leans on — the app.py entry file, requirements.txt auto-install, and the SERVER_PORT rule — see Python on Falix.

🎯 Read this first: runserver is Django's development server. It's perfect for building, prototyping, and small personal projects, and that's what this guide sets up. It is not designed for heavy production traffic — Django's own docs say so. For a real deployment you'd run Django behind a WSGI/ASGI server (gunicorn, uvicorn) and a proper database. This build gets Django genuinely running and serving on Falix; treat it as the honest starting point, not the finish line.

Step 1 — The files

Four small files. requirements.txt:

django

settings.py — a minimal but real Django configuration:

import os
from pathlib import Path

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

SECRET_KEY = os.environ.get("SECRET_KEY", "dev-only-key-change-me")
DEBUG = True
ALLOWED_HOSTS = ["*"]

INSTALLED_APPS = [
    "django.contrib.contenttypes",
    "django.contrib.auth",
    "django.contrib.sessions",
]

MIDDLEWARE = [
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
]

ROOT_URLCONF = "urls"

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.sqlite3",
        "NAME": BASE_DIR / "db.sqlite3",
    }
}

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

urls.py — one route so there's something to see:

from django.http import HttpResponse
from django.urls import path


def home(request):
    return HttpResponse(
        "<h1>Django is running on Falix</h1>"
        "<p>Migrations were applied on start and the dev server is serving this page.</p>"
    )


urlpatterns = [
    path("", home),
]

app.py — the bridge, and the Main file the Python application runs:

import os

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")

from django.core.management import execute_from_command_line

if __name__ == "__main__":
    port = os.environ.get("SERVER_PORT", "8080")
    # Apply migrations on every start, then launch Django's development server.
    execute_from_command_line(["manage.py", "migrate", "--noinput"])
    print(f"Listening on port {port}", flush=True)
    execute_from_command_line(
        ["manage.py", "runserver", f"0.0.0.0:{port}", "--noreload"]
    )

Step 2 — How the bridge works

The Python application always runs python app.py. Django normally does its work through a generated manage.py, but manage.py is just a thin wrapper around one function — execute_from_command_line. So app.py calls that function directly:

  • DJANGO_SETTINGS_MODULE = "settings" points Django at your settings.py.
  • migrate --noinput runs on every start, creating or updating the database tables. On the first boot it builds Django's built-in tables; afterwards it's a fast no-op unless you've added models.
  • runserver 0.0.0.0:$SERVER_PORT starts Django's server bound to the public port — the one Falix rule every web app follows. --noreload turns off the file-watching auto-reloader, which has no place on a server and would only spawn an extra process.

💡 Tip: Binding 0.0.0.0 and reading the port from SERVER_PORT are what make the app reachable — the same two rules as every other web build. Hard-coding 127.0.0.1 or a fixed port is the classic "runs but can't be reached" mistake.

Step 3 — Start it and verify

Press Start. The console installs Django, then shows the migrations applying:

Operations to perform:
  Apply all migrations: auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  ...

Then the server comes up. Open your server's address (from the Network page) and you'll see the "Django is running on Falix" page. That page loading is the proof: migrations ran, the database was created (db.sqlite3), and Django is serving.

From here it's ordinary Django — add an app with INSTALLED_APPS, define models, write views and templates. Whenever you add or change models, create the migration files (locally, with manage.py makemigrations) and commit them; the migrate on start applies them.

The honest trade-offs

Two things to be clear-eyed about:

Concern The reality on Falix
The dev server runserver is single-process and unoptimized. Fine for prototypes and low-traffic personal sites; for real load, run Django under gunicorn or uvicorn (launched the same way from app.py) — see Django's deployment docs.
SQLite The database is a file, db.sqlite3, in the server's file system. It's wiped by a reinstall or application switch and handles only light concurrency. For anything you can't lose or that gets real traffic, use a managed database (PostgreSQL or MySQL) — set it in DATABASES.
*DEBUG = True / `ALLOWED_HOSTS = [""]`** Convenient while building, but not for a public site. Before exposing it, set DEBUG = False, put a real value in ALLOWED_HOSTS, and load SECRET_KEY from your .env — all standard Django hardening.

⚠️ Heads up: For a durable, public Django site, the managed-database swap is the important one — it's the difference between "my data survives a reinstall" and losing everything with the server's files. Take backups regardless.

Troubleshooting

  • ModuleNotFoundError: No module named 'django' — the install didn't finish; confirm django is in requirements.txt or add it from the Packages page, then restart.
  • django.core.exceptions.ImproperlyConfigured — usually DJANGO_SETTINGS_MODULE isn't finding settings.py. Keep settings.py, urls.py, and app.py in the same folder (the server root).
  • Migrations error / no such table — the migrate step failed or was removed from app.py; read the console output above the server start.
  • Page won't load / connection refused — a port or bind problem. Confirm runserver 0.0.0.0:$SERVER_PORT; see I can't reach my app.
  • A newer Django won't install — recent Django versions need a recent Python. The application's default is fine; if needed, pick a newer Python on the Settings page (any plan).

Models, the admin site, templates, and production deployment are all standard Django — the official docs at docs.djangoproject.com own everything past the Falix bridge, including the deployment checklist.


Next steps

Was this guide helpful?