Smartphone lying on a wood surface

Using Windows? Click here to view the Windows version of this walk-through.

After my previous post, Android Development for Beginners: 6 Steps to Building Your First App, I received some requests asking me to explain in more detail how to build an app, step-by-step. If you have any experience buildings apps you will know that it can be a complicated process and there are a number of different components that need to work together to have a fully functioning app. This includes creating a database, a REST API and the app front end.

In the next series of posts, I will break down step-by-step these components to create a basic app. The app I’m going to make is called “Message in a Bottle”. It is inspired by the idea of bottling up a message and throwing it out to ocean, and a random person somewhere else in the world finds it and opens it. The problem is, not everyone lives near an ocean, so we are going to apply our technical minds and use technology bring the message in a bottle experience to anyone, anywhere.

The app will work like this… User A submits a message to the app (aka writes a message on a little scroll of paper, bottles it up, and throws it into the ocean). In return, she is permitted to take one existing bottle out of the ocean (just imagine her scouring the beach, and magically finding a bottle washed up on shore, with a message inside).

Once she reads the message, it then disappears from the app.

Along comes User B. He loads the app, and is prompted to submit a message of his own. Once he does this, he is then given the option to read a message. Like User A, once he reads the message, it then disappears from the app, never to be seen again.

Both User A and B are then permitted to submit another message if they choose. Upon doing so, they’ll be given the opportunity to receive another message in a bottle. And so on, and so on.

To make it more exciting and random, we will pre-load the database with a bunch of messages.

Message in a Bottle App Flow

The technologies we are going to use to build this masterpiece are some excellent open source frameworks:

Let’s start by setting up our development environment. For this, we will use Vagrant; an excellent application that allows you to easily create and configure lightweight, reproducible and portable development environments. This is what we’ll use to create our back-end infrastructure locally on our machines.

Vagrant relies on an underlying virtualisation platform. It offers support for VMWare, Hyper-V, Docker and VirtualBox (more details here: For this walk through, we’ll use VirtualBox as it’s free and works on Windows, Linux and Mac.

Download and Install VirtualBox

If you don’t have it already, start by installing VirtualBox on your machine. Download the relevant package from: If you are using Mac OS X (like me) the package will be “VirtualBox 5.0.16 for OS X hosts”.

VirtualBox Download Options

Once downloaded, double click the icon to load the installer:

VirtualBox Installer OS X

Double click on the VirtualBox.pkg icon.

VirtualBox Mac OSX Installer

On the This package will run a program to determine if the software can be installed message, click Continue.

Package will run a program to determine the software can be installed VirtualBox OS X

On the Welcome to Oracle VM VirtualBox Installer screen, click Continue.

Oracle VM VirtualBox for Mac OS X Screenshot

On the Standard Install on “SSD” screen, click Install.

Mac OS X Standard Install on SSD Screenshot

Enter your password if prompted and click Install Software.

Installer is trying to install new software Screenshot

VirtualBox will now install…

Installing Oracle VM VirtualBox Screenshot

Finally, on The installation was completed successfully screen, click Close.

Congratulations! VirtualBox is installed. Now let’s install Vagrant.

Download and Install Vagrant

Go to and download the relevant version of vagrant for your operating system. As we are using Mac OS X, I will choose the Mac OS X Universal (32 and 64-bit) option.

Vagrant Mac OS X Universal (32 and 46-bit) screenshot

Double click the installer to start the installation.

Mac OS X Vagrant 1.8.1 Installer Screenshot

On the Vagrant window, double click on Vagrant.pkg.

Mac OS X Vagrant Installer Window Screenshot

On the Welcome to the Vagrant Installer screen, click Continue.

Welcome to the Vagrant Installer Screenshot

On the Standard Install on “SSD” screen, click Install.

Standard Install on SSD Screenshot

If prompted, enter your password and click Install Software.

Installer is going to install new software password prompt screenshot

Vagrant will begin installing. When it’s done, click Close.

Installation was successful Mac OS X Vagrant Screenshot

Vagrant should be installed. Let’s do a quick test. Go ahead and load up Terminal by clicking Finder > Go > Utilities and then double click on Terminal.

Mac OS X Go Utilities Screenshot
Mac OS X Utilities Terminal Screenshot

To test that Vagrant is installed, type “vagrant” and hit enter. You should see something like this:

Mac OS X Terminal Screenshot

If you see this then Vagrant is installed properly.

Create the Vagrant box

Next we are going to create the development server using Vagrant. In this tutorial I will be doing all the examples from “/User/mark/workspace”. If you don’t already have a “workspace” directory in your home folder, then create on now by running the below commands in terminal:

cd ~
mkdir workspace

Now, create a folder within your workspace called “devenv” which stands for “Development Environment”. This will hold all of our project files:

cd ~/workspace/
mkdir devenv

Next, let’s create the vagrant file, type the following command to change to the correct directory:

cd ~/workspace/devenv/

Now, create the Vagrant config by typing the following:

vagrant init

As the output will say, running “vagrant up” will make Vagrant create the Vagrantfile. The Vagrantfile is a file which contains the configuration of the server we want to create for our development environment.

Mac OS X Terminal Vagrant Screenshot

Next, we are going to make some changes to this file to modify our development environment. Open the “devenv” directory using your favourite code editor. Personally, I like so that’s what I’ll use for this demonstration.

You can open the directory in Atom by loading Atom and clicking File > Add Project Folder.

Atom File Add Project Folder Screenshot

Then navigate to the Workspace folder, click devenv and click Open:

Mac OS X Open Folder Screenshot

Now that you’ve opened the directory, let’s make our development environment. To do this, we will use the following technologies:

  • Vagrant – To manage our development environment.
  • Ubuntu – As our server operating system.
  • MySQL – For our Database Server.
  • Salt Stack – To configure our server and install relevant packages.

To get the most out of this guide, I recommend that you follow the step-by-step instructions below to fully understand how it works. However, if you just want to download the working version, you can find it here:

Let’s start by creating our “Salt States”. Salt States are configuration files which describe what packages and directories we want to be on our server. An in-depth understanding of Salt isn’t required for this walk-through, however if you are interested in learning more, I’d recommend reading the official walk-through:

Start by creating a directory to hold our Salt States. We will call this “salt”:

Atom Salt Directory

Inside the salt directory, create a file called “top.sls” and “dev.sls”.

The “top.sls” file is the first thing that Salt will load to check which other files to load. Our one is simple, as we only have one other file (“dev.sls”). Add the following contents to “top.sls”.

    - dev

Next, let’s populate the “dev.sls” file. This is where the real work happens. This configuration file will tell Salt to do the following on our server:

  • Install the packages: python3-dev and python-pip.
  • Install the pip package: virtualenvwrapper.
  • Create the directory /usr/local/virtualenvs (for our virtual environment).
  • Create the virtual environment /usr/local/virtualenvs/env (with Python3).
  • Configure “virtualenvwrapper” for the vagrant and root users.
  • Install MySQL server and set the root password to “password”.

I’ve added comments which are prefixed by “#” to explain what is happening. If you don’t fully understand, don’t worry, it can be a bit daunting if this is your first time using Salt, but with practise it will become clearer.

Here is the file:

# Install the packages "python3-dev" and "python-pip".
    - pkgs:
    - python3-dev
    - python-pip
    - libmysqlclient-dev

# Install "virtualenvwrapper" with pip.
    - pkgs:
    - virtualenvwrapper

# Create the directory for our virtual env.
    - user: vagrant
    - group: vagrant

# Create the virtual environment.
    - system_site_packages: False
    - python: python3.4
    - user: vagrant

# Setup virtualenvwrapper.
    - name: /home/vagrant/.bashrc
    - text: |+
      source /usr/local/bin/

# Setup virtualenvwrapper for root.
    - name: /root/.bashrc
    - text: |+
      source /usr/local/bin/

# Install the MySQL server using the root password of 'password'.
    - name: mysql-server
    - data:
      'mysql-server/root_password': {'type': 'string', 'value': 'password'}
      'mysql-server/root_password_again': {'type': 'string', 'value': 'password'}
    - pkgs:
    - mysql-server

# Enable the service so MySQL starts when the server boots.
    - name: mysql
    - enable: True

# Create a database in MySQL called 'miab_db'
    - connection_user: root
    - connection_pass: 'password'
    - connection_charset: utf8
    - name: 'miab_db'

Now add the salt minion config. Create a file in the root of the devenv directory called “minion”. We want to tell Vagrant to load the local Salt States file when creating our server:

file_client: local

  - roots

Now that we have added the salt config, let’s write the Vagrantfile, which will tell Vagrant to use our salt states to build our server (among other things). Edit the Vagrantfile and give it the following contents:

# Wrapper for the vagrant config.
Vagrant.configure(2) do |config|

  # Tell vagrant we want an Ubuntu Trusty64 server. = "ubuntu/trusty64"

  # Map our "salt" directory in this project to "/srv/salt" on the
  # server
  config.vm.synced_folder "salt", "/srv/salt"
  # Map our "project" directory in this project to "/project"
  config.vm.synced_folder "salt", "/srv/salt"

  # Create a public network so we can access the server from other devices
  # on our network. "public_network", type: "dhcp"

  # Configure our server to use "Salt"
  config.vm.provision :salt do |salt|

      # Run salt independently without requring a central management
      # "master" server.
      salt.masterless = true

      # Tell it to use our minion config file "minion".
      salt.minion_config = "minion"

      # After the server boots, run the salt states to defined in the
      # "salt" directory.
      salt.run_highstate = true

  end # End of Salt config.

end # End of Vagrant config.

As with the salt states, I’ve added comments on each line to explain what’s happening.

Finally, create an empty directory called “project” in the root of the devenv directory. This is where we are going to store our project files.

Now, go back to your Terminal and type “vagrant up” to load your vagrant box. This may take a while (depending on your internet connection) because Vagrant has to download the Ubuntu image.

vagrant up
Mac OS X Vagrant Up Terminal Screenshot
Mac OS X Terminal Screenshot

If a menu appears asking you to select the network adapter to bridge, select the network you use to connect to your network. In my case I am connected with en1: Wi-Fi (Airport) so I will type 1 and press enter.

After the vagrant box is loaded, type “vagrant ssh” to connect to the server.

Mac OS X Terminal Vagrant Box Screenshot

OK, that’s it, the server is setup and the first part of this tutorial is complete. Now stay tuned for next weeks post for the second part of the tutorial: Setting up the Database and REST API.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published.