Issue
This is an edit of my original question, which was how to successfully deploy a Django app to a server, because this was my first time. The following links are what I tried:
- https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-16-04
- https://simpleisbetterthancomplex.com/tutorial/2016/10/14/how-to-deploy-to-digital-ocean.html
- https://www.digitalocean.com/community/tutorials/how-to-serve-django-applications-with-uwsgi-and-nginx-on-ubuntu-16-04
- https://www.linode.com/docs/web-servers/nginx/deploy-django-applications-using-uwsgi-and-nginx-on-ubuntu-14-04
- http://uwsgi-docs.readthedocs.io/en/latest/tutorials/Django_and_nginx.html
I followed these to the letter, I got upto the part with ~/myproject/manage.py runserver 0.0.0.0:8000
but then where they show that navigating to the servers ip address on port 8000 shows an 'It worked' page, I get no response. I also ran
# test.py
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [b"Hello World"] # python3
#return ["Hello World"] # python2
with uwsgi --http :8000 --wsgi-file test.py
, and still no response.
So after a while of banging my head against a wall, I decided to give up and skip past that part, and go straight for combining NGINX, uWSGI and my Django app. I just managed to get it working, so I will post a detailed solution below of exactly how I did that, hopefully it may help somebody else, as I found most of the instructions on the internet didn't explain somethings that I felt needed explaining to fully understand what was happening. That will suffice as a question and answer,...
although on a side note, I'm still interested in as to why without the installation of a webserver, I was still not able to visit the Django app ran with the command runserver
, if you know, please comment.
Solution
So after a while of scratching my head, I managed to successfully deploy my Django application to a server hosted on Digitalocean, with NGINX and uWSGI. I'm not going to post the IP of my actual server here, so in this answer I will use 10.11.12.13 as the IP address of my ubuntu server, . I did my best to backtrace my steps, the following is in chronological order:
- Created a droplet on Digitalocean with Ubuntu 16.04.3 x64 with no 'additional options', then by email received the password for the root login:
- Log into the new server and setup a new password
➜ ssh [email protected]
Update the system:# sudo apt-get update
- Add a new user jupiar and give it superuser privilege
# sudo adduser jupiar && usermod -aG sudo jupiar
- Switch to user jupiar
# su - jupiar
- Install NGINX webserver
$ sudo apt-get install nginx
- I do a lot with data science, and my Django app uses alot of these features, so I prefer to work with Anaconda python as it's more complete from the start, so here download and install Anaconda python:
$ wget https://repo.continuum.io/archive/Anaconda3-5.0.0.1-Linux-x86_64.sh
$ bash Anaconda3-5.0.0.1-Linux-x86_64.sh
Noting that in the installation, Anaconda3 was installed to /home/jupiar/anaconda3, and i chose[yes]
to have the installer prepend the install location to PATH in the.bashrc
- Now to restart bash:
$ . .bashrc
$ source .bashrc
- Now I created a python virtual environment, and then activated it:
$ conda create -n drfprojectenv python=3.6 anaconda
$ source activate drfprojectenv
- Now install Django and then start a new project
(drfprojectenv)$ pip install Django
(drfprojectenv)$ django-admin.py startproject drfproject
- Setup the database:
(drfprojectenv)$ cd drfproject
(drfprojectenv)~/drfproject$ ./manage.py migrate
- Set a static directory:
(drfprojectenv)~/drfproject$ echo 'STATIC_ROOT = os.path.join(BASE_DIR, "static/")' >> drfproject/settings.py
- Collect the static files:
(drfprojectenv)~/drfproject$ ./manage.py collectstatic
- Now to install uWSGI, we need a few packages for the operating system so as to compile C code, for which uWSGI needs:
(drfprojectenv)~/drfproject$ sudo apt-get install build-essential python-dev python3-dev
(drfprojectenv)~/drfproject$ cd
(drfprojectenv)$ pip install uwsgi
Okay, now is where it got a little more interesting: We now need to create an initialization file (.ini) for our Django project:
(drfprojectenv)$ sudo mkdir -p /etc/uwsgi/sites
(The-p
just ables us to make all necessary parent directories)(drfprojectenv)$ sudo nano /etc/uwsgi/sites/drfproject.ini
And inside that file place the following:[uwsgi] project = drfproject base = /home/jupiar chdir = %(base)/%(project) home = %(base)/Env/%(project) module = %(project).wsgi:application master = true processes = 2 socket = %(base)/%(project)/%(project).sock chmod-socket = 666 vacuum = true
Now we need to make a uWSGI service, we can do that by:
(drfprojectenv)$ sudo nano /etc/systemd/system/uwsgi.service
and then inside that file place:[Unit] Description=uWSGI Emperor service After=syslog.target [Service] ExecStart=/home/jupiar/anaconda3/envs/drfprojectenv/bin/uwsgi --emperor /etc/uwsgi/sites/drfproject.ini Restart=always KillSignal=SIGQUIT Type=notify StandardError=syslog NotifyAccess=all [Install] WantedBy=multi-user.target
Now, we want uWSGI to start automatically on a system restart, and activate the service:
(drfprojectenv)$ sudo systemctl uwsgi enable
(drfprojectenv)$ sudo systemctl uwsgi start
Noting, that you may see:Warning: emperor.uwsgi.service changed on disk. Run 'systemctl daemon-reload' to reload units.
Where we would just run:(drfprojectenv)$ sudo systemctl daemon-reload
Check the service is running properly with:
(drfprojectenv)$ sudo systemctl status uwsgi.service
Where we should see something like:uwsgi.service - uWSGI Emperor service Loaded: loaded (/etc/systemd/system/uwsgi.service; enabled; vendor preset: enabled) Active: active (running)
- Start the service with this command too:
(drfprojectenv)$ sudo service uwsgi start
- Now we need to configure NGINX:
(drfprojectenv)$ sudo nano /etc/nginx/sites-available/default
and then place the following
server { listen 80; server_name _;
}location = /favicon.ico { access_log off; log_not_found off; } location /static/ { root /home/drfproject; } location / { include uwsgi_params; uwsgi_pass unix:/home/jupiar/drfproject/drfproject.sock; }
Make sure that Django's ALLOWED_HOSTS have some combination of the following ip addresses:
ALLOWED_HOSTS = ['10.11.12.13', '*', 'localhost', '127.0.0.1']
Now stop and start uWSGI service, and restart nginx:
(drfprojectenv)$ sudo service uwsgi stop
(drfprojectenv)$ sudo service uwsgi start
(drfprojectenv)$ sudo service nginx restart
And that should be roughly it, all the steps I could backtrace are there. One thing you may need to do aswell is to install Django and uwsgi on the global installation of Anaconda, as well as within the virtual environment.
Now that's installed properly, should be pretty effortless to switch it over to the rest framework.
- Start the service with this command too:
Answered By - jupiar
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.