├── uwsgi.conf ├── uwsgi.service ├── uwsgi-example.ini ├── nginx-example ├── start.sh └── README.md /uwsgi.conf: -------------------------------------------------------------------------------- 1 | description "uWSGI application server in Emperor mode" 2 | 3 | start on runlevel [2345] 4 | start on runlevel [!2345] 5 | 6 | setuid MY_USER 7 | setgid www-data 8 | 9 | exec /usr/local/bin/uwsgi --emperor /etc/uwsgi/sites 10 | 11 | -------------------------------------------------------------------------------- /uwsgi.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=uWSGI Emperor service 3 | After=syslog.target 4 | 5 | [Service] 6 | ExecStart=/usr/local/bin/uwsgi --emperor /etc/uwsgi/sites 7 | Restart=always 8 | KillSignal=SIGQUIT 9 | Type=notify 10 | StandardError=syslog 11 | NotifyAccess=all 12 | 13 | [Install] 14 | WantedBy=multi-user.target 15 | -------------------------------------------------------------------------------- /uwsgi-example.ini: -------------------------------------------------------------------------------- 1 | [uwsgi] 2 | project = PROJECT_NAME 3 | base = /home/MY_USER 4 | 5 | chdir = %(base)/%(project) 6 | home = %(base)/Env/%(project) 7 | module = %(project).wsgi:application 8 | 9 | master = true 10 | processes = 5 11 | 12 | socket = /tmp/%(project).sock 13 | chmod-socket = 664 14 | vacuum = true 15 | 16 | logto = %(base)/logs/uwsgi-error.log 17 | -------------------------------------------------------------------------------- /nginx-example: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | server_name IP_OR_DOMAIN; 4 | 5 | location = /favicon.ico {access_log off; log_not_found off;} 6 | location /static/ { 7 | root /home/MY_USER/PROJECT_NAME/; 8 | } 9 | 10 | location / { 11 | include uwsgi_params; 12 | uwsgi_pass unix:/tmp/PROJECT_NAME.sock; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Global variables 4 | PROJECT_NAME=$1 5 | USER=$2 6 | 7 | # Test if the user is root. This script can't run as root. 8 | if [ "$EUID" -eq 0 ]; then 9 | echo "Do not run this script as root!!" 2>&1 10 | exit 1 11 | fi 12 | 13 | # Check is the names was given. 14 | if [ "$PROJECT_NAME" == "" ] || [ "$USER" == "" ]; then 15 | echo "Give the project's name as the first argument and your user name as second." 2>&1 16 | exit 1 17 | fi 18 | 19 | # Update system 20 | echo 'yes' | sudo apt-get update 21 | echo 'yes' | sudo apt-get upgrade 22 | 23 | 24 | # Install dependencies 25 | sudo apt-get -y install python3-pip python3-dev nginx libpq-dev postgresql postgresql-contrib 26 | 27 | # It is needed if the project is using pillow. 28 | sudo apt-get -y install libjpeg8-dev 29 | 30 | ## Now that we have pip installed, we can install virtualenv, virtualenvwrapper and uwsgi 31 | sudo pip3 install virtualenv virtualenvwrapper uwsgi 32 | 33 | ## Add user to wwww-data group (required to uwsgi) 34 | sudo usermod -a -G www-data $USER 35 | 36 | ## Setting uwsgi up 37 | mkdir $HOME/logs 38 | touch "/tmp/$PROJECT_NAME.sock" 39 | 40 | ## Add permissions 41 | chmod u+rw /tmp/$PROJECT_NAME.sock 42 | chmod g+rw /tmp/$PROJECT_NAME.sock 43 | 44 | sudo mkdir -p /etc/uwsgi/sites 45 | sudo cp uwsgi-example.ini "/etc/uwsgi/sites/$PROJECT_NAME.ini" 46 | sudo cp uwsgi.conf /etc/init/uwsgi.conf 47 | 48 | ## Setting nginx up 49 | sudo cp nginx-example "/etc/nginx/sites-available/$PROJECT_NAME" 50 | 51 | sudo ln -s "/etc/nginx/sites-available/$PROJECT_NAME" "/etc/nginx/sites-enabled/$PROJECT_NAME" 52 | 53 | # Test if everything is all right 54 | sudo service nginx configtest 55 | 56 | # Force a stop to see the result 57 | echo "Does everything is OK? Then go on! If does not, review the configs files." 58 | echo "Press ENTER to continue" 59 | read 60 | 61 | sudo service nginx restart 62 | 63 | # If uwsgi.service file does not exits, create it. 64 | if [ ! -s /etc/systemd/system/uwsgi.service ]; then 65 | sudo cp uwsgi.service /etc/systemd/system/uwsgi.service 66 | fi 67 | 68 | sudo service uwsgi start 69 | 70 | ## Setting virtualenvwrapper up 71 | echo "export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3" >> ~/.bashrc 72 | echo "export WORKON_HOME=~/Env" >> ~/.bashrc 73 | echo "source /usr/local/bin/virtualenvwrapper.sh" >> ~/.bashrc 74 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Script to Setting up Django with uWsgi and Nginx 2 | 3 | >This script was created following the amazing [Digital Ocean's tutorial](https://www.digitalocean.com/community/tutorials/how-to-serve-django-applications-with-uwsgi-and-nginx-on-ubuntu-14-04). 4 | 5 | ## OS tested: 6 | * Ubuntu 14.04 and 16.04. 7 | 8 | >Was used Python 3.x version. 9 | 10 | ## First: Change the config files to your environment 11 | 12 | * Change all the uppercase word to your data. 13 | 14 | `nginx-example, uwsgi.conf, uwsgi-example.ini` 15 | 16 | 17 | ## Second: Setting uwsgi and nginx up 18 | 19 | * Run `start.sh` (DO NOT run as root) giving the **project's name as the first argument** and your **user name as second**. 20 | 21 | ```sh 22 | $ chmod +x start.sh 23 | $ ./start.sh PROJECT_NAME YOUR_USER 24 | ``` 25 | ## Third: Updating session and create virtual environment 26 | 27 | ### As virtualenvwrapper was installed, it is necessary reload the session. 28 | ```sh 29 | $ source ~/.bashrc 30 | ``` 31 | 32 | #### Create the virtual environment giving the project's name: 33 | ```sh 34 | $ mkvirtualenv PROJECT_NAME 35 | ``` 36 | 37 | ## Four: Configure PostgreSQL 38 | 39 | * Becoming postgres superuser 40 | 41 | `$sudo su - postgres` 42 | 43 | * Connecting to the database server 44 | 45 | `~$ psql` 46 | 47 | * Add new user 48 | 49 | `# create user MY_DB_USER with password 'MY_PASS';` 50 | 51 | * Create database 52 | 53 | `# create database MY_DATABASE;` 54 | 55 | * Grant all privileges 56 | 57 | `# grant all privileges on database MY_DATABASE to MY_DB_USER;` 58 | 59 | * To quit 60 | `\q` 61 | 62 | 63 | ## Five: Now, the Django process... 64 | 65 | #### Create a directory at home with the same name of your project, install django and create a new project: 66 | ```sh 67 | $ mkdir ~/PROJECT_NAME 68 | 69 | $ cd ~/PROJECT_NAME 70 | 71 | $ pip install django 72 | 73 | $ django-admin.py startproject PROJECT_NAME . 74 | ``` 75 | 76 | #### Change SQLlite3(default) to PostgreSQL at `settings.py` 77 | 78 | ```sh 79 | DATABASES = { 80 | 'default': { 81 | 'ENGINE': 'django.db.backends.postgresql_psycopg2', 82 | 'NAME': 'MY_DATABASE', 83 | 'USER': 'MY_DB_USER', 84 | 'PASSWORD': 'MY_PASS', 85 | 'HOST': 'localhost', 86 | 'PORT': '', 87 | } 88 | } 89 | ``` 90 | 91 | #### Setting up static directory which will be serve by nginx. 92 | 93 | * Add to your `settings.py`: 94 | 95 | `STATIC_ROOT = os.path.join(BASE_DIR, "static/")` 96 | 97 | * Then run: 98 | ```sh 99 | python manage.py collectstatic 100 | ``` 101 | 102 | ## Last one: Restart and everything should work. :] 103 | ```sh 104 | $ sudo service uwsgi restart 105 | $ sudo service nginx restart 106 | ``` 107 | 108 | ## If you are getting `505 error Bad Gateway`, run: 109 | `sudo chown YOUR_USER:www-data /tmp/PROJECT_NAME.sock` 110 | 111 | Your sock file must be like this: 112 | ```sh 113 | $ ls -l /tmp 114 | srw-rw-r-- 1 YOUR_USER www-data 0 Mai 18 13:28 PROJECT_NAME.sock= 115 | ``` 116 | --------------------------------------------------------------------------------