Deploy by framework

Django

Deploy Django with a managed Python image and serve collected static files from the CDN.

Nitroship detects Django from manage.py and a django dependency in requirements.txt, pyproject.toml, or Pipfile. The managed preset builds a container and starts Gunicorn with the project's discovered WSGI module. Django views and APIs run on compute; collected static files are served from the CDN.

Deploy

Install the CLI

curl -fsSL https://nitroship.co/install.sh | bash
ntro login

Already installed? Skip ahead. Full options, PATH setup, and updates: Install the CLI.

Choose a compute region; there is no default. To select Django explicitly, put this in the deployment root:

nitroship.json
{
  "build": {"framework": "django"},
  "compute": {"regions": ["kr-icn"]}
}
ntro apps create my-django-app
ntro deploy . --prod

This preset requires the hosted builder. If your command has --local, remove it. After deploying, open a Django route and a collected static file at the URL printed by the CLI.

Dependencies and server

The generated build installs Python dependencies using pip, Poetry, uv, or Pipenv according to the project files. Commit your dependency manifests and lockfile. Python selection reads .python-version, then pyproject.toml's requires-python, then .tool-versions. Explicit version files map to the nearest pinned supported version. A requires-python range must admit a supported pinned interpreter; incompatible bounds fail the build plan rather than silently selecting an unsupported version. Without a declaration, the builder uses a stable default.

manage.py must declare DJANGO_SETTINGS_MODULE. The preset reads a literal WSGI_APPLICATION in that settings module or finds an ancestor package's wsgi.py. Keep these modules in the deployment source tree. Gunicorn listens on 0.0.0.0:$PORT, with 3000 as the default. The managed preset is for WSGI Django apps; a custom ASGI startup or an undiscoverable project layout should use your own Dockerfile.

Static files

When your settings configure STATIC_ROOT, the build runs collectstatic and places the collected files under /nitroship/static, preserving the URL prefix configured by STATIC_URL. For example, /static/admin/css/base.css should remain a /static/... URL, not become /admin/....

The builder automatically extracts /nitroship/static to the CDN before starting the runtime. Only public static assets belong there, never Python source or secrets. Without a configured STATIC_ROOT, there is no automatic collected-static CDN output. Configure it before relying on CDN delivery. User-uploaded media is not a build asset.

STATIC_URL must be a local URL prefix, such as /static/ or static/. An external URL or protocol-relative URL cannot be mapped to this deployment's CDN and is rejected.

Production environment and database

Set environment variables according to what your settings actually read:

  • DJANGO_SETTINGS_MODULE when your application needs an explicit settings module.
  • A production SECRET_KEY, DEBUG=False, and the deployment/custom hostnames in ALLOWED_HOSTS. Environment variable names alone do not change Django settings: your settings must parse them, especially booleans and hostname lists.
  • DATABASE_URL only if your settings read it; otherwise configure the database variables your project uses.

Use an external database. Do not rely on a SQLite file in the image for durable data. If settings need build-time values for collectstatic, provide those through the build environment too; never hard-code production secrets into source.

Runtime limits

Generated images run as a non-root user. The instance filesystem is ephemeral, and the generated image directs temporary writes to /tmp. Nothing written there is durable. Put uploads in S3 or other object storage, not in MEDIA_ROOT on the container filesystem.

Nitroship does not automatically run migrations, queue workers, or schedulers. Run python manage.py migrate from CI or your local machine against the external database. Deploy workers separately, and use Cron jobs for scheduled HTTP work rather than an in-process scheduler.

Framework selection and Dockerfile escape hatch

build.framework: "django" explicitly chooses this preset and overrides an automatically discovered Dockerfile. It cannot be combined with build.dockerfile.

Without build.framework, Nitroship detects the build as described in How Nitroship chooses a build. If you need OS packages, a custom startup command, or different asset handling, remove build.framework and use your own Dockerfile.

On this page