It has been very difficult for me trying to deploy to aws EC2 ubuntu server SINCE I'm coming from windows background. I encounter an error while trying to bind django application to gunicorn. The command I'm running is sudo gunicorn --bind 0.0.0.0:8000 logistics.wsgi:application
And the error log is show below:
(venv) ubuntu@ip-172-31-18-196:/var/www/html$ sudo gunicorn --bind 0.0.0.0:8000 logistics.wsgi:application
[2021-09-08 11:21:00 +0000] [29379] [INFO] Starting gunicorn 20.1.0
[2021-09-08 11:21:00 +0000] [29379] [INFO] Listening at: http://0.0.0.0:8000 (29379)
[2021-09-08 11:21:00 +0000] [29379] [INFO] Using worker: sync
[2021-09-08 11:21:00 +0000] [29382] [INFO] Booting worker with pid: 29382
[2021-09-08 11:21:00 +0000] [29382] [ERROR] Exception in worker process
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/gunicorn/arbiter.py", line 589, in spawn_worker
worker.init_process()
File "/usr/local/lib/python3.5/dist-packages/gunicorn/workers/base.py", line 134, in init_process
self.load_wsgi()
File "/usr/local/lib/python3.5/dist-packages/gunicorn/workers/base.py", line 146, in load_wsgi
self.wsgi = self.app.wsgi()
File "/usr/local/lib/python3.5/dist-packages/gunicorn/app/base.py", line 67, in wsgi
self.callable = self.load()
File "/usr/local/lib/python3.5/dist-packages/gunicorn/app/wsgiapp.py", line 58, in load
return self.load_wsgiapp()
File "/usr/local/lib/python3.5/dist-packages/gunicorn/app/wsgiapp.py", line 48, in load_wsgiapp
return util.import_app(self.app_uri)
File "/usr/local/lib/python3.5/dist-packages/gunicorn/util.py", line 359, in import_app
mod = importlib.import_module(module)
File "/usr/lib/python3.5/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 986, in _gcd_import
File "<frozen importlib._bootstrap>", line 969, in _find_and_load
File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 665, in exec_module
File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
File "/var/www/html/logistics/wsgi.py", line 12, in <module>
from django.core.wsgi import get_wsgi_application
File "/usr/local/lib/python3.5/dist-packages/django/core/wsgi.py", line 2, in <module>
from django.core.handlers.wsgi import WSGIHandler
File "/usr/local/lib/python3.5/dist-packages/django/core/handlers/wsgi.py", line 3, in <module>
from django.conf import settings
File "/usr/local/lib/python3.5/dist-packages/django/conf/__init__.py", line 19, in <module>
from django.utils.deprecation import RemovedInDjango40Warning
File "/usr/local/lib/python3.5/dist-packages/django/utils/deprecation.py", line 5, in <module>
from asgiref.sync import sync_to_async
File "/usr/local/lib/python3.5/dist-packages/asgiref/sync.py", line 115
launch_map: "Dict[asyncio.Task[object], threading.Thread]" = {}
^
SyntaxError: invalid syntax
[2021-09-08 11:21:00 +0000] [29382] [INFO] Worker exiting (pid: 29382)
[2021-09-08 11:21:00 +0000] [29379] [INFO] Shutting down: Master
[2021-09-08 11:21:00 +0000] [29379] [INFO] Reason: Worker failed to boot.
When I run gunicorn --bind 0.0.0.0:8000 logistics.wsgi:application
, (that is, without sudo
) I get another error:
(venv) ubuntu@ip-172-31-18-196:/var/www/html$ gunicorn --bind 0.0.0.0:8000 logistics.wsgi:application
Traceback (most recent call last):
File "/home/ubuntu/.local/bin/gunicorn", line 7, in <module>
from gunicorn.app.wsgiapp import run
ModuleNotFoundError: No module named 'gunicorn'
But I have already install gunicorn with the command pip3 install gunicorn --user
. The reason why I added --user
at the end is that running pip3 install gunicorn
within the activated virtual enviroment is throwing back permission error as shown below:
(venv) ubuntu@ip-172-31-18-196:/var/www/html$ pip3 install gunicorn
Collecting gunicorn
Using cached https://files.pythonhosted.org/packages/e4/dd/5b190393e6066286773a67dfcc2f9492058e9b57c4867a95f1ba5caf0a83/gunicorn-20.1.0-py3-none-any.whl
Requirement already satisfied: setuptools>=3.0 in ./venv/lib/python3.6/site-packages (from gunicorn) (40.6.2)
Installing collected packages: gunicorn
Could not install packages due to an EnvironmentError: [Errno 13] Permission denied: '/var/www/html/venv/lib/python3.6/site-packages/gunicorn-20.1.0.dist-info'
Consider using the `--user` option or check the permissions.
You are using pip version 18.1, however version 21.2.4 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
Again, I have already upgraded from python3.5
to python3.6
such that when I run python3 on the terminal I get the following output
(venv) ubuntu@ip-172-31-18-196:/var/www/html$ python3 --version
Python 3.6.13
Yet, I don't know why the error log is making reference to python3.5 instead of python3.6 as shown here: File "/usr/local/lib/python3.5/dist-packages/gunicorn/app/wsgiapp.py"
whenever I run sudo gunicorn --bind 0.0.0.0:8000 logistics.wsgi:application
Please I want to know why I'm getting that error
This answer is courtesy of WOLFx Digital Agency
You have to login as Ubuntu
user and NOT sudo su/root
Stage 1: Binding your Gunicorn to your Django app and checking if the upstream gunicorn is working fine. Please note the deployment is incomplete without other stages
sudo apt-get update
sudo apt-get upgrade
Optional - If it shows a popup/options then just select the pkg maintainer version.
python3 -m venv env
sudo apt-get install python3-venv
source env/bin/activate
pip3 install django
git clone <your-repo-url>
pip3 install gunicorn
sudo apt-get install -y nginx
cd
to your project directory where settings.py
, db.sqlite3
and all those files of your project is stored.
pip3 install -r requirements.txt
gunicorn --bind 0.0.0.0:8000 <project_name>.wsgi:application
Note: your project name is the main app name which you created in the beginning with django-admin startproject <project_name>
command
You will see
[2021-09-08 15:20:17 +0000] [12789] [INFO] Starting gunicorn 20.1.0
[2021-09-08 15:20:17 +0000] [12789] [INFO] Listening at: http://0.0.0.0:8000 (12789)
[2021-09-08 15:20:17 +0000] [12789] [INFO] Using worker: sync
[2021-09-08 15:20:17 +0000] [12791] [INFO] Booting worker with pid: 12791
which means you have successfully bonded your gunicorn to run your Django app and your Django app is now ready to get linked with a webserver (NGINX in our case). This marks the completion of Stage 1.
To test out Stage 1 success you can type in your IP with port :8000
and see your application run (make sure your aws security is allowing port 8000 else you will see a 404) but the above Booting worker with pid confirms that it's working.
Stage 2: Setting up supervisor
so that your Gunicors autostarts your Django app on reboot and after first boot.
sudo apt-get install -y supervisor
cd /etc/supervisor/conf.d/
sudo touch gunicorn.conf
sudo nano gunicorn.conf
This will open up an editor where you have to type in the script for gunicorn (The bind which we did in Stage 1 but now we are telling supervisor to bind gunicorn every time the server/instance start)
[program:gunicorn]
directory = /home/ubuntu/<path to manage.py>
command = /home/ubuntu/env/bin/gunicorn --workers 3 --bind unix:/home/ubuntu/<App Directory>/app.sock <App Name>.wsgi:application
autostart = true
autorestart = true
stderr_logfile = /var/log/gunicorn/gunicorn.err.log
stdout_logfile = /var/log/gunicorn/gunicorn.out.log
[group:guni]
programs:gunicorn
sudo mkdir /var/log/gunicorn
, here we are creating the log folder for our gunicorn out and error logs.
sudo supervisorctl reread
If you see guni:available
here it means your supervisor is all set and you have properly done everything till now.
sudo supervisorctl update
if you see guni: added process group
this is another marker that you have properly done the steps.
sudo supervisorctl status
If you see guni:gunicorn RUNNING
this is the third and final indicator that your gunicorn is now properly set up.
After all these steps it is confirmed that your gunicorn is now bi-directionally communicating to an app.sock
file which is automatically created inside your project directory.
Stage 3: Final step to link your Gunicorn upstream server to your NGINX
cd /etc/nginx/sites-available
sudo touch django.conf
sudo nano django.conf
This will open up your nano editor where you have to type in these exact server settings.
server {
listen 80;
server_name <ipaddress or domain name> ;
#server_name 192.168.0.1 yourdomain.com your_alternate_domain.com; this is how you can add multiple hosts. Do not add any comma just separate it with spaces
location / {
include proxy_params;
proxy_pass http://unix:/home/ubuntu/Appdir/app.sock;
}
}
sudo nginx -t
(This will test the syntax of your config file)
sudo ln django.conf /etc/nginx/sites-enabled/
<---- this is a very crucial step make sure there is not typing mistake here, it creates a symlink
sudo nginx -t
sudo service nginx restart
With this you now have linked your Nginx to your gunicorn upstream on app.sock so head on to your browser and type in the IP address of your instance and you will see your app live.
If you can see your website without any CSS then you have followed everything properly, I will re-edit my answer on how to serve static files of your Django app in Nginx once you confirm that everything works.