It is useful to make your development environment similar to the production environment. In this tutorial we create an environment that is pretty close to something you could use in production except we will be using the Django development server instead of something like Nginx + Gunicorn to serve the pages.

Install Vagrant And Virtualbox

Go to Vagrant Boxes Search and search for Ubuntu.

You can see that there is a box called Official Ubuntu 16.04 LTS (Xenial Xerus) Daily Build, let's use that.

In the Vagrant Boxes Search you can see that the provider for the box is VirtualBox.

Download and install latest Vagrant and VirtualBox releases:

Create The Environment

Create a folder somewhere and install the box:

cd ~/Projects
mkdir mysite
cd mysite
vagrant init ubuntu/xenial64
vagrant up

SSH To The System

vagrant ssh

Try to comment it out in the local machine like this:

sudo vim /etc/ssh/ssh_config
#   SendEnv LANG LC_*

Run updates:

sudo apt-get update && sudo apt-get dist-upgrade

Create A User For The Site

Create a new user for the site and add it to the sudo group to grant superuser privileges:

sudo adduser mysite
sudo adduser mysite sudo

Switch to the new user:

su - mysite

Create A Virtual Environment

Create a virtual environment with venv, activate it and install Django.

It prompted to upgrade pip so I did that too:

sudo apt install python3-venv
python3 -m venv venv
source venv/bin/activate
pip install django
pip install --upgrade pip

Forward Port

Go to your host machine project folder, create a folder called mysite inside it (we will map it to the Django project root inside the virtual machine):

cd ~/Projects/mysite
mkdir mysite

You should now have this kind of folder structure:

mysite
├── Vagrantfile
├── mysite
└── ubuntu-xenial-16.04-cloudimg-console.log

Edit the Vagrantfile.

Uncomment this line:

# config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"

And change the guest port to 8080:

config.vm.network "forwarded_port", guest: 8080, host: 8080, host_ip: "127.0.0.1"

This means that we can now access the Django development server in http://127.0.0.1:8080 from the host machine browser.

Sync A Folder

Write the following uncommented line under the example line:

# config.vm.synced_folder "../data", "/vagrant_data"
config.vm.synced_folder "mysite", "/home/mysite/mysite", owner: "mysite", group: "mysite", mount_options:["dmode=775,fmode=664"]

This will sync the host folder mysite to the /home/mysite/mysite inside the box.

Reload the box:

vagrant reload

The folder ~/Projects/mysite/mysite should be now synced to the folder /home/mysite/mysite.

Create Django Project

Login to the virtual machine, change to the user mysite, activate the virtual environment and create a new Django project:

vagrant ssh
su - mysite
source venv/bin/activate
cd mysite
django-admin.py startproject mysite .

Now you should have this kind of folder structure inside the mysite home folder:

mysite
├── manage.py
└── mysite
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

Run Development Server

python3 manage.py runserver

Development server should now be available in http://127.0.0.1:8000/. You can test it locally with a command line browser like links.

Open a new terminal tab and connect to the server again:

vagrant ssh
su - mysite
source venv/bin/activate
cd mysite
sudo apt install links
links http://127.0.0.1:8000/

Now you should see the default text: Congratulations on your first Django-powered page....

But since we setup the port forwarding, we can access the development server also from the host machine. Stop the development server with ctrl + c and run it with this command:

python3 manage.py runserver 0:8080

Access the server from the host with http://localhost:8080 or http://127.0.0.1:8080.

Create PostgreSQL User And Database

The default project uses SQLite as database. You might have noticed the database file that was created in /home/mysite/mysite/db.sqlite3.

sudo apt install postgresql postgresql-contrib

The installation created a new user account called postgres. Let's use that to create a new role (database user) and a database:

sudo -u postgres createuser mysite -P

Create the database and set owner as mysite:

sudo -u postgres createdb mysite -O mysite

Install Psycopg2 And Configure Settings file

pip install psycopg2

Edit the settings.py file:

vim mysite/settings.py

Comment out the default DATABASES settings and add new for PostgreSQL:

#DATABASES = {
#    'default': {
#        'ENGINE': 'django.db.backends.sqlite3',
#        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
#    }
#}

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'mysite',
        'USER': 'mysite',
        'PASSWORD': 'mysite',
        'HOST': 'localhost',
        'PORT': '',
    }
}

You can now delete the SQLite file and run Migrate:

rm db.sqlite3
python3 manage.py migrate

You can examine the database to see that the tables are actually created:

sudo -u postgres psql mysite
\d
\q

Psql connects to the database. \d shows tables. \q quits the terminal.

Create A Superuser

Create a superuser so we can access the admin area:

python3 manage.py createsuperuser

Visit http://127.0.0.1:8080/admin/

Editing The Files

Because we shared the mysite folder, you can edit the files also from the host machine.