Create Python3 virtual environment in Ubuntu and Mac


To install python3.6 in Ubuntu, follow this link

Now to create virtual environment first we need to install virtualenv using pip, run below command to do the same:

pip install virtualenv

Run the below command to create virtual environment in the folder venv:

virtualenv -p python3.6 venv

You can activate the virtual environment and check the python version by running below commands:

source venv/bin/activate
python --version

Deactivate virtual env by:



To install python3 on mac follow this link

In mac it’s very easy to create the virtual environment, just run below command to create it in the folder venv:

python3 -m venv venv

You can activate the virtual environment and check the python version by running below commands:

source venv/bin/activate
python --version

Deactivate virtual env by:




If you are using fish instead of bash, then to activate virtual environment run the below command:

source venv/bin/

How to map domain to Amazon EC2 instance without using Route 53

As you know Amazon’s Route 53 isn’t free and it costs you money to even map your domain to your server. And it is also a little complex than the usual domain mapping process, i.e. you have to change the DNS of your domain.

In this guide I am going to show you how to map your domain to your Amazon EC2 without using Route 53 in a very simple way.

Step 1:

Get the public ip address of your EC2 instance.

If you don’t know your instance’s public ip address then open your aws console, go to EC2 Dashboard, then click on ‘Running instance’, then you will see a list of all the instances you have. Scroll horizontally untill you see ‘IPv4 Public IP’ section, the value at that section will be your public ip address.

Step 2:

Open your Domain Registrar’s site and go to DNS Management then to Manage Zones. If you can’t find it then a quick google search of “how to add A record in {your domain registrar name here}” will get you there.

There you will see a list of Records, namely ‘A’, ‘CNAME’, ‘NS’, ‘MX’, etc. We don’t have to touch those existing records, we will create new record for our server.

There will be an option to add new record. We have to add new ‘A’ record, so if there is explicitly mentioned ‘ADD A Record’, then click on that.

Then a form will open up, like below:


Note: If you have enabled the IPv6 then you have to use that one. Follow the process below but instead of ‘A’ record you have to add new ‘AAAA’ record.

If there is a dropdown for Type, then select ‘A’ from that list. Insert ‘@’ (without quotes) at the ‘Host’ input field and your server’s ip address at the ‘Points to’ input field. If the ‘TTL’ value is set already then don’t change it, if it is not set then set it to 1 Hour. Now save it.


Now, we have to add another ‘A’ record. Open up new form. This time in ‘Host’ field insert ‘*’ (without quotes) and in the ‘Points to’ field your ip address as before. This will allow you to map your sub-domain to your server i.e., your domain with ‘www’.


Step 3:

Set the domain name in your Nginx or Apache configuration file, as server name.

For Nginx it is:


And for Apache it is:


Note: if you have created new server files (i.e. virtual hosts) for your set up then add domain there.

Don’t forget to map both www and non-www variant of the domain.

Restart your server. And you are done!

How to host Django application and LEMP site on the same server using Nginx and Gunicorn on Ubuntu 16.04

You can host django application and PHP site on the same VPS. This is easy to set up and you don’t need to be an expert to do this.

* At least one domain name (i.e.

You must have a domain in order to host both django and php site. You cannot do this with just ip address.

Suppose you have one domain i.e., ‘’, then for the django app we will use ‘’ and ‘’. And for php site we will use ‘’.
To do this your domain’s ‘A’ record must be pointing towards the IP address of your server and in the host field you must have ‘*’. As shown below:


Ok, let’s do it!

First we will start with Django site

Install required packages:

$ sudo apt-get update

for python2:

$ sudo apt-get install python-pip python-dev libpq-dev postgresql postgresql-contrib nginx gunicorn

for python3:

$ sudo apt-get install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx gunicorn

Install python virtual environment:

for python2:

$ sudo -H pip install --upgrade pip
$ sudo -H pip install virtualenv

for python3:

$ sudo -H pip3 install --upgrade pip
$ sudo -H pip3 install virtualenv

Set up Postgresql Database and User

You can skip this step if you are using sqlite or some other DBMS system.

Log into the postgresql interactive session in order to create new database and user.

$ sudo -u postgres psql

Now create database for your project:

postgres=# CREATE DATABASE project;

Now create new database user:

postgres=# CREATE USER projectuser WITH PASSWORD 'password';

Grant the user access to his database:

postgres=# GRANT ALL PRIVILEGES ON DATABASE project TO projectuser;

Now quit from PostgreSQL session

postgres=# \q

Initialize django project

Now its time we initialize our django projects and set it up.

First go to home directory and make directory for our django project.

$ cd ~
$ mkdir project
$ cd project

Now we will initialize virtual environment and install required python packages:

$ virtualenv venv
$ source venv/bin/activate
(venv) $ pip install django gunicorn psycopg2

Now, we will create our project and set it up.

(venv) $ django-admin startproject project .

Don’t forget to type the period at last, it will tell django to create project at the current location.

By now your directory structure would be like:

| ---project/

Now we will edit our to add ALLOWED_HOSTS and DATABASE credentials:

(venv) $ nano project/

Add your domain or sub-domain or IP address to the allowed host:

ALLOWED_HOSTS = ['your_server_domain_or_IP', ]

and your database credentials (not required if you are using sqlite):

'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'project',
'USER': 'projectuser',
'PASSWORD': 'password',
'HOST': 'localhost',
'PORT': '',

and set your static root directory:

STATIC_ROOT = os.path.join(BASE_DIR, 'static/')

Now migrate the database:

(venv) $ python makemigrations
(venv) $ python migrate

collect all the static files into root directory by typing:

(venv) $ python collectstatic

We will now test the server by running it:

(venv) $ python runserver

Go to http://domain_or_ip:8000 you will see default django index page or your project’s index page.


If you are unable to see the page and if your firewall is enabled then you have to run following commands:
$ sudo ufw allow 8000
$ sudo ufw allow ‘Nginx Full’

Moving forward we will test our site with gunicorn. To do so run the below command:

(venv) $ gunicorn --bind project.wsgi

Replace the project.wsgi with your project’s name or with the name of the folder which contains
You must see the same page as before, however without css and js as gunicorn does not have their location.

Deactivate the virtual environment:

(venv) $ deactivate

Now, we will create gunicorn systemd service file to start the application server.

$ sudo nano /etc/systemd/system/gunicorn.service

In gunicorn service file we will specify the dependencies of the django application, so that gunicorn would be able to execute them correctly.
Copy the code snippet below and paste it on the service file. Change the path relative to your django app.

Description=gunicorn daemon

WorkingDirectory=/home/user/project # location of directory which contains your file (remove this comment)
ExecStart=/home/user/project/venv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/home/user/project/project.sock project.wsgi:application


Replace user with the name of the user you logged in as (Note: it should not be root). Be careful with the path you have provided. Make sure that the user you are using must be able to access that path with using ‘sudo’.

Now we will start gunicorn service:

$ sudo systemctl start gunicorn
$ sudo systemctl enable gunicorn

Print the list of content on the project directory.

$ ls /home/user/project

There must be a socket file with the name of your project i.e., project.sock, if it is not there then restart the gunicorn.

$ sudo systemctl daemon-reload
$ sudo systemctl restart gunicorn

Check for socket file again, if the problem persist, check the status of gunicorn

$ sudo systemctl status gunicorn

If gunicorn is not running then check the error log with:

$ sudo journalctl -u gunicorn

These type of errors occur because of:
* the wrong path provided in the gunicorn service file,
* user does not have permission to access the project directory
* gunicorn is not installed correctly

After changing the gunicorn system file, always run the below command and check for socket file:

$ sudo systemctl daemon-reload
$ sudo systemctl restart gunicorn

Configure Nginx to serve django app

First create a server block for our django app

$ sudo nano /etc/nginx/sites-available/project

In the server block paste the following code and change it according to your project:

server {
listen 80;
server_name; #replace with your domain

location =  /favicon.ico { access_log off; log_not_found off; }

location /static/ { #if you are using amazon s3, then skip this block
root /home/user/project;

location / {
include proxy_params;
proxy_pass http://unix:/home/user/project/project.sock; #path to your socket file

Now enable the file by linking it to sites-enabled directory:

$ sudo ln -s /etc/nginx/sites-available/project /etc/nginx/sites-enabled

Test the nginx configuration:

$ sudo nginx -t

If test failed then check the socket path and make sure socket file is there and check the nginx error log:

$ sudo tail -F /var/log/nginx/error.log

Make corrections and test again until test is passed.

If test is passed then restart the nginx:

$ sudo systemctl restart nginx

Go to your domain i.e. and you will see your site up and running.

Set up LEMP

Install mysql server

$ sudo apt-get install mysql-server

and then complete the mysql set up with

$ sudo mysql_secure_installation

Follow the instruction and you are done.

Install php

$ sudo apt-get install php-fpm php-mysql php-curl php-gd php-mbstring php-mcrypt php-xml php-xmlrpc nginx

There is a flaw in php that will allow attackers to exploit php site. So, to fix this, open php configuration file:

$ sudo nano /etc/php/7.0/fpm/php.ini

and add


at the end of the file.

Now, restart the php processor:

$ sudo systemctl restart php7.0-fpm

Configure Nginx to use php

Open the default server block configuration file:

$ sudo nano /etc/nginx/sites-available/default

and replace the code with the following one:

server {
listen 80 default_server;
listen [::]:80 default_server;

root /var/www/html; #directory path where your php files must be located
index index.php index.html index.htm index.nginx-debian.html;

server_name; #your domain or sub-domain or server's ip address

location / {
try_files $uri $uri/ =404;

location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;

location ~ /\.ht {
deny all;

Test the server block configuration file:

$ sudo nginx -t

If test failed then recheck your file and re-run the test.

If test is passed, then restart the nginx:

$ sudo systemctl reload nginx

Test the LEMP installation

Go to /var/www/html

$ cd /var/www/html

Create the file index.php

$ sudo nano index.php

Paste the following code in it:


Go to or whatever domain you have set. You must see information about your server and php installation. After checking the site, remove the file, it is not safe to show server information.