Deploying a Django app involves more than just your Python code. You need to configure a WSGI server, manage static files, and provision a production-grade database. This guide demonstrates how to deploy a Django app with a managed PostgreSQL database, moving from a GitHub repository to a live, production-ready URL in under five minutes.
We will configure a Django project for a PaaS environment, connect it to a managed PostgreSQL database, and automate the entire build and deployment process using Miget.
Preparing Your Django App for Production
To ensure your application runs correctly in a containerized PaaS environment, a few adjustments are necessary. These changes help your app handle database connections, serve static files, and receive web traffic properly.
1. Configure the Database Connection
Hardcoding database credentials in settings.py is not secure or flexible. The best practice is to read connection details from an environment variable. The dj-database-url library makes this trivial.
First, add it to your project's dependencies.
Here is your requirements.txt:
Django>=4.2
gunicorn
dj-database-url
psycopg2-binary
whitenoise
Next, modify your settings.py to use it. This code looks for a DATABASE_URL environment variable and uses a local SQLite database for development if it's not found.
Here is the update for settings.py:
import os
import dj_database_url
# ... other settings
# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases
DATABASES = {
'default': dj_database_url.config(
default='sqlite:///db.sqlite3',
conn_max_age=600
)
}
2. Set Up Static File Serving
In production, Django's development server doesn't serve static files. WhiteNoise is a popular and effective solution that allows your web application to serve its own static files without relying on a separate web server like Nginx.
Add whitenoise to your requirements.txt (as shown above). Then, configure it in your settings.py.
Update your MIDDLEWARE setting:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware', # Add this line
'django.contrib.sessions.middleware.SessionMiddleware',
# ... other middleware
]
And configure the static files settings:
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/
STATIC_URL = 'static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STORAGES = {
"staticfiles": {
"BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
},
}
3. Define a Procfile
A Procfile is a text file in your repository's root that tells the platform which commands to run to start your application. For a typical Django deployment, you need a web process to start the Gunicorn server and a release process to run database migrations.
Create a file named Procfile in your project's root directory:
release: python manage.py migrate
web: gunicorn myproject.wsgi
Replace myproject.wsgi with the path to your project's wsgi.py file. The release command runs once after each new version is deployed but before it goes live, ensuring your database schema is always up to date.
How to Deploy Your Django App on Miget
With the app configured, you can deploy it in a few steps. This process requires a free Miget account and your Django project hosted on GitHub.
Step 1: Create a Project and Resource
Log into the Miget dashboard and create a Project. A Project is a way to group related applications and services. Next, create a Resource, which provides the compute power (CPU, RAM, disk) for your apps. You can deploy unlimited apps inside one Resource.
Step 2: Create the Application
- Inside your Project, click "Create New App".
- Choose the
githubdeployment method and connect your GitHub account. - Select the repository containing your Django application.
- Miget's
migetpackswill automatically detect the Python project and configure the build process. You don't need a Dockerfile.
The initial deployment will start automatically. It may fail because the database isn't configured yet, but that's expected.
Step 3: Add a PostgreSQL Addon
Once the app exists, you can provision a database.
- Navigate to your app's dashboard and select the "Addons" tab.
- Click "Create Addon" and choose "PostgreSQL".
- Select a plan and confirm.
Miget automatically provisions the database and injects the connection string as the DATABASE_URL environment variable into your Django app. Your settings.py configuration will pick this up on the next deploy.
Step 4: Configure Production Environment Variables
Navigate to your app's "Environment" tab and add the following variables. These are crucial for security and proper operation in a production environment.
| Key | Value | Description |
|---|---|---|
SECRET_KEY | your-super-secret-key-here | A long, random string for cryptographic signing. |
DJANGO_DEBUG | False | Disables debug mode in production. |
ALLOWED_HOSTS | your-app.migetapp.com,www.yourdomain.com | A comma-separated list of hostnames your app can serve. |
After adding these variables, trigger a new deployment from the app dashboard. The migetpacks will build your application, the release command in your Procfile will run database migrations against your PostgreSQL addon, and the web process will start.
Your Django app is now live and connected to a production-ready PostgreSQL database.
Advanced Django Deployment Topics
Once your app is running, you can enhance its functionality and management.
Adding a Custom Domain
Miget provides a default *.migetapp.com subdomain, but you can attach your own custom domain.
- Go to the "Domains" tab in your app's dashboard.
- Add your domain name (e.g.,
www.example.com). - Follow the instructions to add the provided CNAME record to your DNS provider's settings.
Miget automatically provisions and renews SSL certificates for all custom domains.
Running Background Workers
Many Django apps need to run background tasks using tools like Celery. With Miget's fixed-capacity model, you can run a Celery worker in the same Resource as your web app without paying for an additional service.
Add another process to your Procfile:
release: python manage.py migrate
web: gunicorn myproject.wsgi
worker: celery -A myproject worker -l info
Miget will automatically start and manage both the web and worker processes.
Running Scheduled Tasks
For periodic tasks like cleanup jobs or data processing, you can use Miget's built-in cronjobs. Instead of configuring Celery Beat or system cron, you can define a cronjob in the dashboard.
- Navigate to the "Cronjobs" tab.
- Create a new cronjob.
- Set the schedule (e.g.,
0 0 * * *for daily at midnight). - Set the command to run, such as a Django management command:
python manage.py cleanup_sessions.
Why Miget is a Great Fit for Django
Miget simplifies the Django deployment workflow by handling the infrastructure so you can focus on your code.
- Automatic Builds: Open-source
migetpacksdetect Python, install dependencies fromrequirements.txt, collect static files, and set up Gunicorn. No Dockerfiles or build configuration is needed. - Managed PostgreSQL: Add a production-ready database with one click. Connection strings, backups, and maintenance are handled for you.
- Predictable Pricing: A single fixed monthly price for a Resource covers your Django app, PostgreSQL database, and any background workers. You never have to worry about per-app or per-database charges.
- Efficient Resource Use: The Fair Scheduler ensures that CPU is allocated dynamically. Your Celery worker can use idle CPU from your web process, maximizing the value of your compute plan.
Next Steps
You have successfully deployed a production-ready Django application with a PostgreSQL database. The combination of Django's robust framework and Miget's simplified platform operations lets you build and ship applications faster.
- Read the Miget Documentation for more details.
- Explore the Python migetpack on GitHub.
- Learn more about Miget's fixed-capacity pricing model.
What to read next
- How to Deploy Python to Docker Without Writing a Dockerfile - Containerize any Python app with migetpacks
- PostgreSQL HA Clusters Are Now Available - Add high-availability to your Django database
- Free PostgreSQL Hosting with Public Access - Start with a free PostgreSQL database on Miget