Django Hosting

In development, Django works with a single command. Production is different. Gunicorn serves your WSGI application behind Nginx, collectstatic moves your static files to a directory Nginx can serve, DEBUG is off with all the security settings that implies, and migrations run against a live database without bringing the site down. If you're adding WebSockets, the architecture changes again. Bitfoo VPS gives you the environment to set all of it up correctly - full root access, dedicated resources, and no restrictions on what you install.

Django in production

The infrastructure setup - Gunicorn, Nginx, virtual environments, systemd, and PostgreSQL - is covered on the Python hosting page. This page covers what's specific to Django: the production settings that need to change from development defaults, the static file workflow, the migration deployment process, and optionally Django Channels for real-time features.

Production settings - what changes from development

DEBUG = False is the switch that enables Django's production mode - but it requires several other settings to be correctly configured before it's safe to turn off. ALLOWED_HOSTS must list your domain explicitly. SECRET_KEY must come from an environment variable, not a hardcoded string in settings.py. SECURE_SSL_REDIRECT = True forces HTTPS. SECURE_HSTS_SECONDS, SESSION_COOKIE_SECURE, and CSRF_COOKIE_SECURE complete the baseline security configuration. Run python manage.py check --deploy on your server to catch any missed settings before going live.

Static files - collectstatic and Nginx

In development, Django serves its own static files. In production, it does not - serving files through the Python process is slow and unnecessary. Run python manage.py collectstatic to copy all static files (including Django admin's CSS, JavaScript, and images) to the directory defined by STATIC_ROOT. Configure Nginx to serve that directory directly at your STATIC_URL path, bypassing Gunicorn entirely for static requests. The same approach applies to user-uploaded media via MEDIA_ROOT.

Database migrations - deployment workflow

Every Django release and schema change involves python manage.py migrate. In production, migrations run against a live database, which means timing and sequencing matter. The standard deployment workflow: pull new code, install dependencies, run collectstatic, run migrate, then restart Gunicorn. For additive migrations (new tables, new nullable columns), this order is safe with zero downtime. For destructive changes (removing columns, renaming fields), Django's documented multi-step migration approach applies - the Python hosting page's deployment steps cover the mechanics.

Redis - caching and session storage

Django's cache framework supports Redis as a backend via django-redis. Use it for view-level caching, per-site caching, session storage, and rate limiting. Install Redis on your VPS (sudo apt install redis-server), install django-redis in your virtual environment, and configure the CACHES setting to point to your Redis instance. Redis runs alongside your Django application and Gunicorn workers on the same server - size your plan to account for Redis memory usage alongside your Gunicorn worker footprint.

Django REST Framework - no additional infrastructure required

Django REST Framework (DRF) is a Python package installed via pip - it does not change your hosting setup. Your DRF API runs through the same Gunicorn server as the rest of your Django application. Pagination, throttling, authentication, and permission classes are all application-level configuration. The hosting considerations are the same as any Django application: Gunicorn workers, Nginx, and appropriate RAM per worker.

Django Channels - adding WebSocket support

Django's standard deployment is synchronous WSGI - one Gunicorn worker handles one request at a time. WebSockets require a persistent connection that stays open after the initial handshake, which WSGI cannot accommodate. Django Channels switches your application to ASGI and adds the ability to handle WebSocket connections, long-polling, and background tasks alongside standard HTTP requests.

ASGI server - Daphne or Uvicorn replaces Gunicorn

Django Channels runs under an ASGI server. Daphne is the reference implementation, built and maintained by the Django Channels project. Uvicorn also works and is commonly used. Configure your ASGI application in asgi.py (Django generates this file automatically), point your systemd service at Daphne or Uvicorn instead of Gunicorn, and update your Nginx configuration to proxy WebSocket upgrade requests correctly alongside standard HTTP requests.

Redis as the channel layer

Django Channels requires a channel layer - a shared message-passing backend that coordinates between Django worker processes. Redis is the standard choice. Install channels_redis alongside channels in your virtual environment and configure CHANNEL_LAYERS in your Django settings to point to your Redis instance. The same Redis instance used for caching and sessions can serve as the channel layer, or you can run a separate Redis instance for isolation.

Nginx WebSocket proxy configuration

WebSocket connections from browsers require specific Nginx proxy headers: proxy_http_version 1.1, proxy_set_header Upgrade $http_upgrade, and proxy_set_header Connection "upgrade". Without these, the WebSocket handshake fails at the proxy layer. Add these to your Nginx location block alongside your existing proxy_pass directive. SSL WebSocket connections (wss://) work through the same Nginx SSL configuration used for HTTPS.

Channel workers - optional background task processing

Django Channels can run background workers that consume messages from the channel layer - similar to Celery but using Channels' own protocol. These run as separate systemd services alongside your ASGI server. For applications that already use Celery for background tasks, there's no requirement to switch to Channels workers - both can coexist.

Plans

Django applications vary widely in resource usage - a simple content site has different requirements from a high-traffic API or a real-time application running Channels. All plans run on KVM with dedicated AMD Ryzen 9 9900X resources.

VPS-1 Low-traffic Django sites or development and staging environments VPS-2 Production Django applications with PostgreSQL, Redis, and Celery - the recommended starting point VPS-4 Higher-traffic Django applications, Django Channels with many concurrent WebSocket connections, or larger Celery worker pools VPS-6 High-traffic production workloads, large Django REST Framework APIs, or servers running multiple Django applications
vCPU1246
RAM1GB DDR52GB DDR54GB DDR58GB DDR5
Storage25GB NVMe50GB NVMe100GB NVMe200GB NVMe
Bandwidth1TB2TB4TB6TB
IPv41111
Price[price][price][price][price]
Deploy your VPS. Deploy your VPS. Deploy your VPS. Deploy your VPS.

These are renewal prices. What you pay today is what you pay next year.

All VPS plans are unmanaged. Bitfoo handles the hardware and network; your Django environment, application server configuration, and deployments are your responsibility.

If your server exceeds its monthly bandwidth allocation, throughput is throttled for the remainder of the billing cycle - no additional charges.

Running Django with Channels and Redis adds to your server's baseline RAM usage. A VPS-2 running Gunicorn (5 workers), PostgreSQL, Redis, and Celery workers will use 1.2-1.8GB RAM depending on your Django application's per-worker footprint. Size up if you're regularly approaching your allocation's limit.

What every VPS plan includes

Everything on the VPS hosting page applies to Django. The Python hosting page covers the infrastructure setup specific to Python applications: virtual environments, Gunicorn and Uvicorn, Nginx configuration, systemd, Python version management, and PostgreSQL. This page focuses on what's specific to Django.

Full root access and SSH from first boot - required for Gunicorn/Daphne, Nginx, Redis, and PostgreSQL installation and configuration

KVM virtualization - your own kernel; Django's ORM connection management, Celery worker processes, and Channels ASGI workers all operate without host-imposed restrictions

AMD Ryzen 9 9900X - strong single-core performance for Django's synchronous ORM-heavy views and Gunicorn worker processes

NVMe SSD storage - fast I/O for PostgreSQL queries, Django ORM operations, and media file access

99.9% uptime SLA - measured monthly, service credit issued for any shortfall

5 datacenter locations at order time: US East, US West, UK, EU, Asia-Pacific

10Gbps network ports on all plans

Who uses this

Django is one of the most widely used Python web frameworks - it powers content management systems, REST APIs, real-time applications, and internal tools across organisations of every size.

Developers · SaaS companies · Startups · Agencies

Common questions

How does deploying Django with ASGI and Channels differ from a standard WSGI deployment?

Standard Django runs as a WSGI application - Gunicorn spawns multiple worker processes, each handling one HTTP request at a time. Django Channels switches to ASGI, which enables persistent connections like WebSockets alongside standard HTTP. The key differences: your ASGI server is Daphne or Uvicorn instead of Gunicorn, your asgi.py defines the application entry point instead of wsgi.py, Redis is required as a channel layer backend for coordinating between workers, and your Nginx configuration needs additional headers to proxy WebSocket upgrade requests. Your existing Django views, models, and URLs work without changes - Channels adds WebSocket handling alongside them, it does not replace the HTTP routing.

How do I handle database migrations during deployment without downtime?

For most migrations, the standard workflow - migrate before restarting Gunicorn - is safe without downtime. Django holds off on destructive schema changes while the old code is still running. The cases that require care are removing a column that the current deployed code still reads, renaming a field without a backwards-compatible alias, or making a previously nullable column non-nullable without a default. For these, Django's documentation recommends multi-step migrations: deploy code that's compatible with both the old and new schema, then migrate, then deploy the cleanup. For high-traffic sites, pg_repack or PostgreSQL's native ALTER TABLE ... ADD COLUMN non-blocking mode can help with large table migrations.

What Django security settings do I need to configure in production?

At minimum: set DEBUG = False, populate ALLOWED_HOSTS with your domain, move SECRET_KEY to an environment variable (never hardcode it), and set SECURE_SSL_REDIRECT = True, SESSION_COOKIE_SECURE = True, and CSRF_COOKIE_SECURE = True. For HTTP Strict Transport Security, add SECURE_HSTS_SECONDS = 31536000 once you've confirmed your SSL setup is correct - HSTS is difficult to reverse. Run python manage.py check --deploy on your production server before going live; it checks your settings against Django's security requirements and reports any misconfiguration. Store sensitive settings in environment variables and load them in settings.py using os.environ.get() or a library like python-decouple.

Can I use Django REST Framework on Bitfoo VPS?

Yes, without any hosting-specific configuration. Django REST Framework is a Python package that installs into your virtual environment (pip install djangorestframework) and integrates with Django's standard request/response cycle. Your DRF API runs through the same Gunicorn server as the rest of your application - no separate process, no additional service. The hosting considerations are identical to any Django application. DRF's throttling, pagination, and authentication classes are all application-level configuration that requires no server-side changes.

How do I use Redis as Django's cache backend?

Install django-redis in your virtual environment (pip install django-redis), install Redis on your VPS (sudo apt install redis-server), and configure the CACHES setting in your Django settings to use django_redis.cache.RedisCache with your Redis instance URL. With this in place, Django's cache framework APIs - cache.get(), cache.set(), cache.delete() - store and retrieve from Redis rather than in-memory. Per-view caching (@cache_page), per-site caching, and session storage via Redis all use the same configuration. The same Redis instance can serve as both the cache backend and the Channels layer backend if you're using Django Channels.

Can I use PostgreSQL-specific Django features like ArrayField and PostGIS?

Yes. ArrayField, JSONField, HStoreField, and Django's full-text search fields are all PostgreSQL-specific and work as documented once PostgreSQL is installed and configured on your VPS. PostGIS - the spatial database extension that powers Django's GeoDjango geographic features - installs via sudo apt install postgis alongside PostgreSQL on Ubuntu and Debian. Configure your DATABASES setting to use django.contrib.gis.db.backends.postgis as the engine instead of the standard PostgreSQL backend. These features require PostgreSQL; they're not available with MySQL or SQLite.

Which plan should I choose for Django?

VPS-1 suits low-traffic sites, development environments, or staging servers where you want a close approximation of production without the cost. VPS-2 is the recommended starting point for most production Django applications - it handles Django, PostgreSQL, Redis, and a moderate Celery setup with comfortable headroom. If you're running Django Channels with concurrent WebSocket connections, VPS-2 handles modest real-time workloads; VPS-4 gives you more room for a larger number of concurrent connections and Celery workers. VPS-6 suits high-traffic REST APIs, large-scale Channels deployments, or servers running multiple Django applications. The Python hosting page's Gunicorn worker formula (2 x vCPU + 1) applies here - factor your per-worker memory footprint, PostgreSQL, and Redis into your total RAM calculation.