Minimum RAM Requirement: 2GB
Note: Before proceeding with this instruction, it may be helpful to replace all occurrences of "example.com" with your actual domain.
-
Update System
apt-get update apt-get upgrade
-
Install Required Packages
apt-get install -y git make gcc g++ postgresql postgresql-client libpq-dev \ libjpeg-dev libpng-dev libwebp-dev libgif-dev libtiff-dev zlib1g-dev \ libxml2-dev libxslt1-dev redis-server redis-tools nginx curl
-
Install Python 3.7
apt-get install -y build-essential gdb lcov pkg-config libbz2-dev libffi-dev libgdbm-dev \ libgdbm-compat-dev liblzma-dev libncurses5-dev libreadline6-dev libsqlite3-dev libssl-dev \ lzma lzma-dev tk-dev uuid-dev zlib1g-dev
mkdir -p ~/.local/opt export VERSION=3.7.17 wget -qO "/tmp/python-$VERSION.tar.gz" "https://www.python.org/ftp/python/$VERSION/Python-$VERSION.tgz" tar -xzf "/tmp/python-$VERSION.tar.gz" -C ~/.local/opt/ cd ~/.local/opt/Python-$VERSION/ ./configure --with-pydebug make -j $(nproc) make altinstall
-
Install SASS
cd ~/.local/opt/ git clone https://github.com/sass/libsass cd ./libsass git checkout tags/3.3.3 make && make install cd .. git clone https://github.com/sass/sassc cd ./sassc git checkout tags/3.3.0 export SASS_LIBSASS_PATH=~/.local/opt/libsass make cp ./bin/sassc /usr/bin/
-
Create User for Web Application
adduser webapp adduser webapp sudo
-
Create Project Directory
mkdir /var/www/ chown webapp:webapp /var/www/
-
Upload Archive to the Server (via FTP or SCP, for example):
# example: scp ./example.com.tar [email protected]:/var/www/
-
Extract Files into Project Directory
su - webapp cd /var/www/ mkdir example.com tar -xf ./example.com.tar -C ./example.com cd example.com
-
Create PostgreSQL user
sudo -u postgres createuser --createdb --pwprompt webapp
-
Restore Database
createdb example.com gunzip -c ./backup/example.com.2023-07-31.sql.gz \ | grep -v -E '(DROP\ EXTENSION|CREATE\ EXTENSION|DROP\ SCHEMA|CREATE\ SCHEMA|COMMENT\ ON)' \ | psql -v ON_ERROR_STOP=on --single-transaction --dbname=example.com
-
Create Virtual Environment
python3.7 -m venv --prompt=env .venv . .venv/bin/activate pip install -r requirements/dev.txt
-
Configure
EMAIL_*
settings in thesrc/settings/common.py
. -
Ensure that the
PROJECT_ROOT
variable in thesrc/settings/production.py
file corresponds to the absolute path of the project directory. -
Install uWSGI.
pip install uwsgi
Create a basic uWSGI configuration file at
/var/www/uwsgi.ini
:[uwsgi] http-socket = 0.0.0.0:%(app_port) module = project.wsgi master = true autoload = true protocol = uwsgi procname-master = %(app_name)-master procname = %(app_name) pidfile = /run/uwsgi/%(app_name).pid enable-threads = true so-keepalive = true tcp-nodelay = true processes = 2 threads = 2 listen = 512 http-timeout = 300 socket-timeout = 300 limit-as = 768 post-buffering = 204800 buffer-size = 16384 max-requests = 5000 max-worker-lifetime = 3600 harakiri = 30 harakiri-verbose = true single-interpreter = true die-on-term = true vacuum = true no-orphans = true thunder-lock = true log-date = true log-slow = 3000 log-zero = true log-4xx = true log-5xx = true log-ioerror = true log-sendfile = true
-
Compile static files.
export DB_HOST=localhost DB_NAME=example.com DB_USER=webapp DB_PASS=password python3 src/manage.py collectstatic --noinput python3 src/manage.py compilejsi18n # (if django_statici18n installed)
Note: Replace the
password
placeholder with the actual password for thewebapp
user inDB_PASS
. -
Create a systemd unit file for uWSGI.
sudo systemctl edit --full --force uwsgi-example.com.service
[Unit] Description=uWSGI for example.com [Service] User=webapp WorkingDirectory=/var/www/example.com Environment=DB_HOST=localhost DB_NAME=example.com DB_USER=webapp DB_PASS=password ExecStart=/var/www/example.com/.venv/bin/uwsgi --ini /var/www/uwsgi.ini --chdir "/var/www/example.com/src" --set-placeholder app_name="example.com" --set-placeholder app_port=8001 RuntimeDirectory=uwsgi Restart=always Type=notify NotifyAccess=all [Install] WantedBy=multi-user.target
Note: Replace the
password
placeholder with the actual password for thewebapp
user inDB_PASS
. -
Start uWSGI Service.
sudo systemctl daemon-reload sudo systemctl enable uwsgi-example.com.service sudo systemctl start uwsgi-example.com.service
Check uWSGI Service Status:
sudo systemctl status uwsgi-example.com.service
Test the uWSGI Service Response:
curl 'http://127.0.0.1:8001/' -H 'Host: example.com'
Note: If you have Django 1.11 or higher, and you are using HTTPS, you may encounter the error that occurs when submitting forms:
Referer checking failed - https://example.com/ does not match any trusted origins.
To resolve this issue, add the following line to the
src/settings/production.py
file:CSRF_TRUSTED_ORIGINS = ["example.com"]
-
Create Nginx Configuration File.
sudo cp ./nginx.example.conf /etc/nginx/sites-available/example.com.conf sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/example.com.conf
Check nginx configuration:
sudo nginx -t
-
Create a Default Nginx Configuration
To enhance security, you can create an Nginx configuration that blocks unwanted requests and incorrect routes.
Create the file
/etc/nginx/sites-available/default.conf
with the following content:server { listen 80 default_server; listen [::]:80 default_server; listen 443 default_server http2; listen [::]:443 default_server http2; ssl_reject_handshake on; server_name _; return 444; }
Activate the configuration:
sudo ln -s /etc/nginx/sites-available/default.conf /etc/nginx/sites-enabled/
Check nginx configuration:
sudo nginx -t
Restart nginx:
sudo service nginx restart
-
(Optional) Install and Configure
ufw
Firewallsudo apt-get install -y ufw
Allow SSH connections so you don’t lose access to the server:
sudo ufw allow ssh
Allow access to HTTP and HTTPS ports for web applications:
sudo ufw allow http sudo ufw allow https
Enable the firewall:
sudo ufw enable