WDTUTORIALS
Web & Game Development Tutorials
Unity, Django, Drupal, C#, Python…
menu
Samuli Natri 2017.08.17
Entrepreneur. Software developer since the 90's.
Attended Helsinki University Of Technology (Computer Science) and Helsinki University (Social Sciences).

Django - How To Setup A Development Environment With Vagrant

Tutorial on how to setup a development environment with Vagrant, Ubuntu and PostgreSQL.

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.

Visit Ubuntu Releases to see current status of Ubuntu releases.

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

If you haven't used this box before it will be downloaded. This might take some time.

SSH To The System

vagrant ssh

You might get a warning like this: "WARNING! Your environment specifies an invalid locale.". One reason for this could be that you are using SendEnv in ssh_config.

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

Hyphen (-) after su will switch the folder to the home directory of the new user and changes environmental variables to those of the new user.

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

Check How To Create Virtual Environments tutorial for more info on how to manage virtual environments.

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.

Because we defined the host_ip, this means that we can only access the guest machine from that specific address (localhost). Otherwise we would potentially give an open access to the machine from the network.

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

The deepest mysite folder at this point is in /home/mysite/mysite/mysite.

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....

Use q to exit links.

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.

127.0.0.1 is not accessible outside the virtual machine. 0 makes the development server available from all IPs your computer responds to (0 is shortcut for 0.0.0.0).

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.

SQLite is a serverless database contained in a single file. For Django production sites you should use something like PostgreSQL.

sudo apt install postgresql postgresql-contrib

postgresql-contrib contains bunch of extra functionality.

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

-P prompts for password for the user to be created.

Create the database and set owner as mysite:

sudo -u postgres createdb mysite -O mysite

-O sets the owner of the database.

Install Psycopg2 And Configure Settings file

pip install psycopg2

Psycopg is a PostgreSQl adapter for Python.

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.

Psql is an interactive terminal for PostgreSQL.

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.