Before deploying a Django application, there are several concepts that need to be understood and several decisions that need to be made.
The prerequisites for deploying a Django application are the following:
- You will need an environment that can run your Django code.
- You will need an environment that can serve static files.
- Run some pre-deployment management commands.
For this guide, we will help you deploy a Django app on a single server using NGINX for handling traffic and serving
static files and gunicorn
to run your Django app.
Setting up the server
First, you need to make sure you have at least Python 3, nginx and postgres installed:
sudo apt update
sudo apt install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx curl
To check that the dependencies were installed successfully, you can run the following commands:
python --version
sudo service postgresql status
sudo service nginx status
Install the Python dependencies
It is a good practice to keep your dependencies in a requirements.txt
file near your code, committed with the rest
of the code. To install the dependencies from a requirements file, run the command
pip install -r requirements.txt
or alternatively, you can install your dependencies one by one:
pip install django psycopg2 ...
Creating the PostgreSQL database and user
Before we setup our Django app, we need to make sure we have a database our app will connect to. By default,
the PostgreSQL installation comes with a single postgres
database, and it is advised to not use it for application
specific data. Instead, we should create a new database and add a new user just for Django to connect with:
# connect with the default postgres user created, with no password.
# it is possible to connect with this user only from the same instance the server
# is installed on (so the connection must come from 127.0.0.1)
sudo -u postgres psql
Then, a postgres command prompt will appear, where we can execute SQL statements directly:
CREATE DATABASE mydjangoapp;
CREATE USER djangouser WITH PASSWORD 'securepassword';
Make sure you setup a secure password for your app. Weak credentials can expose your app to hackers.
Then, we need to update some settings for the created user, to follow the recommendations of the Django project
ALTER ROLE djangouser SET client_encoding TO 'utf8';
ALTER ROLE djangouser SET default_transaction_isolation TO 'read committed';
ALTER ROLE djangouser SET timezone TO 'UTC';
Then, we need to give administration permissions to the new account, because Django will use it to manage the tables (create tables, add/remove columns) through migrations.
GRANT ALL PRIVILEGES ON DATABASE mydjangoapp TO djangouser;
After all the steps are completed, we can exit the postgresql command prompt and continue with our setup.
\q
Preparing the Django project
First, we need to bring the code locally. It is highly recommended to use a version control system such as git
to
manage your app's code. You can use Gitlab or Github to host your code
for free.
After you copy your code locally, you'll need to update your <projct_name>/settings.py
file to instruct the app
to connect to the local postgres database.
Search the DATABASES
section of your settings.py
and add the following configuration:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'mydjangpapp',
'USER': 'djangouser',
'PASSWORD': 'securepassword',
'HOST': 'localhost',
'PORT': '5432',
}
}
Then, you need to synchronize the database by running the migrations:
python manage.py makemigrations
python manage.py migrate
Now the database should be initialized with the tables Django needs to function.
Preparing nginx
We need to prepare nginx to serve our static files from Django and proxy the traffic from the user to our app. We could allow the users to connect directly to our Djano app, but having it behind a nginx reverse proxy has several advantages:
- a single exposed port for serving the Django app traffic and the static files
- the possibility to scale our Django app horizontally (adding more instances) so we can serve more traffic.
For that, we need to add a new file to the path /etc/nginx/sites-available/mydjangoapp
:
server {
listen 80;
server_name server_name_or_ip;
location /static/ {
root <paht_to_the_project>/static;
}
location / {
include proxy_params;
proxy_pass http://localhost:8000/;
}
}
The first location
section will serve the static files directly from our application directory, and the second
block will forward the traffic directly to our Django application.
There are two more commands you need to run:
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
sudo nginx -t
sudo service nginx restart
Configuring static files from Django
Static files are the kind of files that are sent to the client as they are, without going through Django's views.
You need to update the settings.py
file once again to make sure the static files are prefixed correctly:
STATIC_URL = '/static/';
STATICFILES_DIRS = ['media/']
The next step is to gather all the files inside the location specified in STATICFILES_DIRS
:
python manage.py collectstatic
This will copy all the static files from the static
folders inside each app to one central location, from where
nginx will serve them when requested.
Start the Django project
We will use gunicorn
for this, so we need to make sure it is installed
pip instsall gunicorn
To start the django application, we will use the command
gunicorn --workers 3 --bind 0.0.0.0:8000 <project_name>.wsgi:application
If your settings.py is inside a directory called myproject
, the command will become
gunicorn --workers 3 --bind 127.0.0.1:8000 myproject.wsgi:application
After that, the Django server should have started, and serve traffic at localhost:8000. To check, you can
use the curl
tool:
curl http://localhost:8000
Check that everything works fine
Now, everything should be up and running. To check that everything is working as expected, you can access in your
browser the nginx application at http://SERVER_IP_OR_NAME. Make sure the SERVER_IP_OR_NAME you enter in the
browser is the same specified in the server_name
section of the nginx configuration. That's how nginx knows
how to route the requests, and if the server name doesn't match, your traffic is not being forwarded properly
Note: to do that, the server you use should have a public IP. If not, there is no way to access your application from the internet. Most cloud providers such as AWS, Google Cloud or Scaleway offer public IP addresses for your servers.
We are offering a way to deploy your apps without all the configuration steps, but a single amethyst.yaml
file
placed in your project.
Deploy your applications in minutes
If you want to be among the first that can use the service, leave us an email and we'll get right back to you when the private beta starts!
Or contact us directly at contact@amethystplatform.com.