How to Deploy a Django Project

In this article, we'll talk about how to deploy a Django project manually on a Linux server using uWSGI and Nginx. Assume you are using Ubuntu 22.4 LTS.

First of all, you must prepare your server like we discussed in this article, so that it is secure and safe to use. And also make sure your software is up to date by running the following commands.

cmd
sudo apt update
cmd
sudo apt upgrade

Clone your project using Git

After you've set up the server, you'll need to upload the Django project to the server. Git is an ideal tool for this purpose. Git is an open-source version control software that can track the changes in the source code. It is designed for coordinating work among programmers.

Git should be preinstalled on your system by default, but just in case it is not there, you can install it using the following command:

cmd
sudo apt install git

And then, go to the home directory, and clone our project from GitHub to the server.

cmd
cd ~
cmd
git clone https://github.com/ericsdevblog/django-tutorial.git

This command will create a django-tutorial directory and put our project in it. Here is a small Linux trick, you can check the content of a directory using the following command:

cmd
ls

If you need to list the hidden items as well:

cmd
ls -a

Next time, when you make changes to our project, instead of uploading the entire project again, you only need to run the git pull command.

Create virtual environment & install requirements

Now that you have cloned your Django project, you need to create an isolated virtual Python environment for it. However, on Debian based systems, the venv package, which you'll need to create a virtual environment, is not included by default, but you can install it using the following command:

cmd
sudo apt install python3.10-venv

Go to the application's root directory:

cmd
cd <path_to_root_directory>

Create a virtual environment:

cmd
python3 -m venv env

Run the ls command again, and you should see an env directory. The virtual environment is created inside. Now, all you need to do is activate the environment and install all the necessary requirements for this project.

Activate the virtual environment:

cmd
source env/bin/activate

Remember, if you install required packages without activating the virtual environment, the packages will be installed globally, instead of in the virtual environment we just created.

If the activation is successful, your terminal prompt should look like this.

text
(env) eric@djangoDeployDemo:~/django-tutorial/djangoTutorial$

(env) means you are currently working inside a virtual environment called env.

You can also deactivate virtual environment using the following command:

cmd
deactivate

Install requirements:

cmd
pip install -r requirements.txt

Install uWSGI

uWSGI is a software application that "aims at developing a full stack for building hosting services". It is named after the Web Server Gateway Interface (WSGI), which was the first plugin supported by the project.

uWSGI is often used for serving Python web applications in conjunction with web servers such as Cherokee and Nginx, which offer direct support for uWSGI's native uWSGI protocol.

Before you can install uWSGI, you need to install the Python development package first.

cmd
sudo yum groupinstall "Development Tools"
sudo yum install python-devel

Next, install the latest stable version of uWSGI:

cmd
pip install uwsgi

Test Your Django Project

Now, we can test our Django project with uWSGI. First, make sure our site actually works:

cmd
python manage.py runserver 0.0.0.0:8000

And if that works, run it with uWSGI:

cmd
uwsgi --http :8000 --module django_blog.wsgi

module mysite.wsgi: load the specified wsgi module.

Visit the server IP from your browser, if the site appears, it means uWSGI is able to serve your Django application from your virtualenv, and this stack operates correctly:

text
the web client <-> uWSGI <-> Django

Now, normally we won’t have the browser speaking directly to uWSGI. That’s a job for the web server, which will act as a go-between.

Install Nginx

Nginx is an open-source high-performance web server. Compared to Apache, it is much more flexible and lightweight.

First, we need to add the Nginx repository:

cmd
sudo yum install epel-release

Install Nginx using yum command:

cmd
sudo yum install nginx

After this, we can start the Nginx server by typing:

cmd
sudo systemctl start nginx

Now we need to check if the Nginx server is working properly by visiting it in a web browser on port 80. You should get a message from Nginx: “Welcome to Nginx!”. If not, it is probably because something else is running on port 80, and you need to reconfigure Nginx to serve on a different port. For this tutorial, we'll use port 8000.

Configure Nginx for Your Site

To configure Nginx so that it works for our Django site, we need to edit the uwsgi_params file, which is available in the nginx directory of the uWSGI distribution, or from GitHub.

We need to copy this file to the Django project directory, and later we'll need to tell Nginx to use this file.

Now create a file called django_blog_nginx.conf in the /etc/nginx/sites-available/ directory, and add the following configurations:

text
# django_blog_nginx.conf
 
# the upstream component nginx needs to connect to
 
upstream django {
    # server unix:///<path_to_your_site>/mysite.sock; # for a file socket
    server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}
 
# configuration of the server
 
server {
    # the port your site will be served on
    listen      8000;
    # the domain name it will serve for
    server_name example.com; # substitute your machine's IP address or FQDN
    charset     utf-8;
 
    # max upload size
    client_max_body_size 75M;   # adjust to taste
 
    # Django media
    location /media  {
        alias <path_to_your_site>/media;  # your Django project's media files - amend as required
    }
 
    location /static {
        alias <path_to_your_site>/static; # your Django project's static files - amend as required
    }
 
    # Finally, send all non-media requests to the Django server.
    location / {
        uwsgi_pass  django;
        include     <path_to_your_site>/uwsgi_params; # the uwsgi_params file you installed
    }
 
}

This configuration file tells Nginx to serve the site on port 8000. Nginx will handle the static file and media files, as well as requests that require Django's intervention. For a large project, it is always better to let one server handle static/media files, and another handle Django applications. But for now, this is all we need to do.

Symlink to this file from /etc/nginx/sites-enabled so Nginx can use it:

cmd
sudo ln -s /etc/nginx/sites-available/django_blog_nginx.conf /etc/nginx/sites-enabled/

Deploy Static Files

Before running Nginx, we have to collect all Django static files in the static folder. First of all, we have to edit settings.py adding:

python
STATIC_ROOT = os.path.join(BASE_DIR, "static/")

and then run

cmd
python manage.py collectstatic

Test Nginx Server

Since we made changes to the Nginx server configuration, we need to restart the server so that these changes can take effect:

cmd
sudo systemctl restart nginx

Upload a new image (media.png) to the /media directory, can then visit http://<your_domain>:8000/media/media.png in the browser to see if Nginx is serving the media files correctly. If it doesn't work, try stopping and starting the Nginx server again. This will inform you if there is a problem and where it is.

Run the Django Application with Nginx and uWSGI

Now that we have uWSGI and Nginx properly installed and configured, we can start our Django application:

cmd
uwsgi --socket django_blog.sock --module django_blog.wsgi --chmod-socket=664

Configuring uWSGI to run with a .ini file

We can put relevant uWSGI configurations into a file, and then ask uWSGI to parse the configurations on start up.

Create a file called django_blog_uwsgi.ini:

ini
# django_blog_uwsgi.ini file
 
[uwsgi]
 
# Django-related settings
 
# the base directory (full path)
 
chdir           = /path/to/your/project
 
# Django's wsgi file
 
module          = project.wsgi
 
# the virtualenv (full path)
 
home            = /path/to/virtualenv
 
# process-related settings
 
# master
 
master          = true
 
# maximum number of worker processes
 
processes       = 10
 
# the socket (use the full path to be safe
 
socket          = /path/to/your/project/mysite.sock
 
# ... with appropriate permissions - may be needed
 
# chmod-socket    = 664
 
# clear environment on exit
 
vacuum          = true

And run uwsgi using this file:

cmd
uwsgi --ini mysite_uwsgi.ini # the --ini option is used to specify a file

Install uWSGI System-Wide

So far, uWSGI is only installed in our virtual environment, and we’ll need it installed system-wide for deployment purposes.

Deactivate your virtual environment:

cmd
deactivate

and install uWSGI system-wide:

cmd
sudo pip3 install uwsgi

The uWSGI wiki describes several installation procedures. Before installing uWSGI system-wide, it’s worth considering which version to choose and the most appropriate way of installing it.

Check again that we can still run uWSGI just like we did before:

cmd
uwsgi --ini mysite_uwsgi.ini # the --ini option is used to specify a file

Learn, Build & Launch

With Our Full Stack Dev Roadmap with Next.js Boilerplate

Start for FREE 🎉

Subscribe below to grab our free Full-Stack Web Developer Starter Kit 👇

Also follow us onorwhere we share coding tips daily.

Course Outline
Introduction+
  • 1.Course Introduction
HTML & CSS+
  • 1.Preparations
  • 2.HTML Elements
  • 3.Text Elements
  • 4.Layout Elements
  • 5.Cascading Style Sheet
  • 6.Basic Selectors
  • 7.Advanced Selectors
  • 8.Colors
  • 9.Loading Font
  • 10.Font Customization
  • 11.Text Customization
  • 12.Text Spacing
  • 13.Text Alignment
  • 14.Functions
  • 15.@ Rules
  • 16.Links
  • 17.Lists
  • 18.Tables
  • 19.Forms
  • 20.Form Fields
  • 21.Media Files
  • 22.Aspect Ratio
  • 23.Object Fit
  • 24.Cursor Behavior
  • 25.Scroll Behavior
  • 26.Visibility & Opacity
  • 27.Box Shadow
  • 28.Color Background
  • 29.Image Background
  • 30.Background Attachment
  • 31.Gradient
  • 32.Blend Modes
  • 33.The Box Model
  • 34.Border
  • 35.Padding & Margin
  • 36.Element Size
  • 37.Display Types
  • 38.Overflow
  • 39.Float
  • 40.Position
  • 41.Z index
  • 42.The Column Layout
  • 43.The Grid Layout
  • 44.Grid Flow
  • 45.Grid Gap
  • 46.Grid Spanning
  • 47.Grid Alignment
  • 48.The Flexbox Layout
  • 49.Flex Gap
  • 50.Flex Order
  • 51.Basis, Grow & Shrink
  • 52.Flexbox Alignment
  • 53.Calculator
  • 54.Filters
  • 55.Transforms
  • 56.Transition
  • 57.Transition Timing Functions
  • 58.Transition Delay
  • 59.Animations
  • 60.Animation Iteration Count
  • 61.Animation Direction
  • 62.Animation Fill Mode
  • 63.Responsive Design
  • 64.Viewport
  • 65.Media Query
  • 66.Responsive Media
  • 67.Responsive Text
  • 68.Responsive Layout (Flexbox)
  • 69.Responsive Layout (Grid)
  • 70.Responsive Layout (Legacy)
  • 71.Layout Without Media Query
  • 72.Recreating YouTube
  • 73.Building the Layout
  • 74.Building the Navbar
  • 75.Building the Sidebar
  • 76.Building the Main Section
JavaScript Fundamentals+
  • 1.Introduction
  • 2.Basic Syntax
  • 3.Variables
  • 4.Data Types
  • 5.Numbers & BigInt
  • 6.Strings
  • 7.Boolean Values
  • 8.Undefined & Null
  • 9.Type Conversion
  • 10.If Statements
  • 11.Switch Statements
  • 12.While Loops
  • 13.For Loops
  • 14.Introducing Functions
  • 15.Variable Scope
  • 16.Arrays
  • 17.Mutating Array
  • 18.Searching Array
  • 19.Sorting Array
  • 20.Looping Array
  • 21.Objects
  • 22.Looping Object
  • 23.JSON
  • 24.Symbols
  • 25.Maps
  • 26.Sets
  • 27.Define Functions
  • 28.Function Arguments
  • 29.Rest Parameter & Spread Syntax
  • 30.Error Handling
  • 31.Pure Functions
  • 32.Functions as Value
  • 33.Higher Order Functions
  • 34.Function Factory
  • 35.Function Currying
  • 36.Function Wrapper
  • 37.Recursion
  • 38.Closure
  • 39.Methods
  • 40.Investigating "this"
  • 41.Losing "this"
  • 42.Constructor Functions
  • 43.Getters & Setters
  • 44.Prototypes Introduction
  • 45.Creating Prototypes
  • 46.Inspecting Prototypes
  • 47.Constructor with Prototype
  • 48.The Class Notation
  • 49.Class Inheritance
  • 50.Static Properties
  • 51.Private Properties
  • 52.Object Oriented Programming
  • 53.A Banking App
  • 54.Working with Date
  • 55.The Math Object
  • 56.JavaScript Modules
  • 57.Throwing Errors
  • 58.Asynchronous Programming
  • 59.Promise
  • 60.Resolve Promise
  • 61.Promise Chaining
  • 62.Async & Wait
  • 63.Best Practices
JavaScript in the Frontend+
  • 1.The DOM Tree
  • 2.Selecting Elements in the DOM
  • 3.DOM Navigation
  • 4.Changing Elements
  • 5.Adding Elements
  • 6.Removing Elements
  • 7.Event Handling
  • 8.Event Propagation
  • 9.Some Common Events
  • 10.Image Slider: Creating HTML
  • 11.Image Slider: Adding Styles
  • 12.Image Slider: Adding Scripts
  • 13.Image Slider That "Slides"
  • 14.Regular Expressions
  • 15.Regex Flags
  • 16.Regex Matching Character Sets
  • 17.Regex Boundary
  • 18.Regex Groups & Quantifiers
  • 19.Regex Lookahead & Lookbehind
  • 20.Regex Related Methods
  • 21.Calculator
  • 22.Canvas
JavaScript in the Backend+
  • 1.Setting Up a Dev Environment
  • 2.Network & HTTP
  • 3.A Basic Web App
  • 4.Express.js
  • 5.Routing
  • 6.MVC Architecture
  • 7.The Model Layer
  • 8.CRUD Operations
  • 9.The Controller Layer
  • 10.The View Layer
  • 11.Blog
  • 12.ORM Integration
  • 13.Creating a Post
  • 14.Uploading Files
  • 15.Showing a Post
  • 16.Updating a Post
  • 17.Deleting a Post
  • 18.Database Relations
  • 19.CRUD Tags
  • 20.Adding & Removing Tags
  • 21.Showing Tags & Posts
  • 22.Middleware
  • 23.Browser Data Storage
  • 24.User Registration
  • 25.User Authentication
  • 26.User Authorization
  • 27.User Management
  • 28.Going to Production
React.js+
  • 1.Introducing React.js
  • 2.Setting Up React Project
  • 3.React Project Structure
  • 4.JSX
  • 5.Conditional Rendering
  • 6.List Rendering
  • 7.Adding Styles
  • 8.Components
  • 9.Import & Export Component
  • 10.Variables in Components
  • 11.Props
  • 12."children" Prop
  • 13.Event Handlers
  • 14.Event Handlers & Props
  • 15.Event Propagation
  • 16.Event Prevent Default
  • 17.Introducing State
  • 18.States are Local
  • 19.Object States
  • 20.Multiple States
  • 21.Shared States
  • 22.Form Handling
  • 23.Component Lifecycle
  • 24.Built-In Components
  • 25.Todo List
  • 26.Add New Task
  • 27.Remove Task
  • 28.Edit Task
  • 29.Complete a Task
  • 30.View Pending Tasks
  • 31.Organize State with Reducer
  • 32.The Reducer Function
  • 33.Dispatch Actions
  • 34.Passing Data with Context
  • 35.Context Provider
  • 36.Access Context
  • 37.Use Context with State
  • 38.Manipulate DOM with Refs
  • 39.Side Effects
  • 40.Side Effect Dependencies
  • 41.Side Effect Clean Up
  • 42.Weather App
  • 43.Get Weather by Coordinate
  • 44.Get Weather by City
  • 45.Display Weather by User Location
  • 46.Creating Custom Hooks
  • 47.Other React Hooks
  • 48.Rules of React
  • 49.Building a Full-Stack Blog App
  • 50.Project Setup
  • 51.React Router
  • 52.List Posts
  • 53.Create a New Post
  • 54.Show a Single Post
  • 55.Update a Post
  • 56.Delete a Post
  • 57.Implement Dark Theme
Full-Stack with Next.js+
  • 1.Next.js Basics
  • 2.Routing
  • 3.Pages & Layout
  • 4.Server vs. Client Components
  • 5.API Routes
  • 6.Server Actions
  • 7.Database Integration
  • 8.Data Fetching
  • 9.Error Handling
  • 10.Middleware
  • 11.Links, Navigation & Redirection
  • 12.Images
  • 13.Scripts
  • 14.Fonts
  • 15.Lazy Loading
  • 16.Caching
  • 17.Loading UI
  • 18.SaaS Platform
  • 19.User Authentication
  • 20.Magic Link
  • 21.Custom Emails
  • 22.Protecting Routes
  • 23.OAuth Providers
  • 24.Dashboard
  • 25.Role Based Access Control
  • 26.Payment Integration
  • 27.Pricing Page
  • 28.Stripe Checkout
  • 29.Payment Webhook
AI for Full-Stack Developers+
  • 1.What Are LLMs?
  • 2.Setting Up OpenAI Account
  • 3.Tokens
  • 4.Context Window
  • 5.Compare LLM Models
  • 6.OpenAI Model Playground
  • 7.Building a Chatbot
  • 8.Send Message to OpenAI
  • 9.Talking to GPT-4
  • 10.Talking to GPT-5
  • 11.Response Streaming
  • 12.Sending Data
  • 13.Receiving Data
  • 14.Streaming with Server Sent Events
  • 15.Chatbot Streaming Backend
  • 16.Chatbot Streaming Frontend
  • 17.Prompt Engineering
  • 18.System Prompt
  • 19.Role Switcher
  • 20.Prompting Techniques
  • 21.Structured Output
  • 22.Get Current Weather
  • 23.Tools & Functions
  • 24.Structured Output vs. Tool Calling
  • 25.What is an Agent
  • 26.What is RAG
  • 27.Chunking & Embedding
  • 28.Building a RAG Agent
  • 29.Setting Up the Database
  • 30.Document Processing
  • 31.Split Text into Chunks
  • 32.Generate Embeddings
  • 33.Listing Processed Documents
  • 34.Chat with RAG Agent
  • 35.Semantic Search
  • 36.Generate a Response
Recent Community Articles
  • The Ultimate Guide to Becoming an AI Engineer
  • How to Learn Full-Stack Web Development in 2025 (With Projects)
  • Top Website Optimization Methods in 2025
  • How to Build Interactive Forms Using HTML and CSS
  • How to Create a Modern App with Django and Vue
  • How to Send HTTP Requests Using JavaScript
  • Vue.js Fundamentals
  • How to Reverse a String in JavaScript
  • How to Reverse an Array in JavaScript
  • JavaScript Fundamentals 2025
  • Clone your project using Git
  • Create virtual environment & install requirements
  • Install uWSGI
  • Test Your Django Project
  • Install Nginx
  • Configure Nginx for Your Site
  • Deploy Static Files
  • Test Nginx Server
  • Run the Django Application with Nginx and uWSGI
  • Configuring uWSGI to run with a `.ini` file
  • Install uWSGI System-Wide

Full Stack AI Dev

RoadmapCommunityPricing

SaaS Boilerplate

Next.js BoilerplateDocumentation

Contribute

Write for UsStyle Guide

Free Tools

HTML CompilerJavaScript CompilerNode.js CompilerReact CompilerNext.js Compiler

Legals

Privacy PolicyTerms of ServiceContact Us
© 2026TheDevSpace.io| All Rights Reserved
RoadmapSaaS BoilerplatePricingCommunity
CheatsheetsHTML CompilerJavaScript CompilerNode CompilerReact CompilerNext.js Compiler
Get Started
CourseNext.js BoilerplatePricingCommunity
Freebies
CheatsheetsHTML CompilerJavaScript CompilerNode CompilerReact CompilerNext.js Compiler