How to Build an App Part 1: Setting up the Development Server with Vagrant, Ubuntu and Salt (Mac OS X Version)
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.
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: https://www.vagrantup.com/docs/providers/). 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: https://www.virtualbox.org/wiki/Downloads. If you are using Mac OS X (like me) the package will be “VirtualBox 5.0.16 for OS X hosts”.
Once downloaded, double click the icon to load the installer:
Double click on the VirtualBox.pkg icon.
On the This package will run a program to determine if the software can be installed message, click Continue.
On the Welcome to Oracle VM VirtualBox Installer screen, click Continue.
On the Standard Install on “SSD” screen, click Install.
Enter your password if prompted and click Install Software.
VirtualBox will now install…
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 https://www.vagrantup.com/downloads.html 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.
Double click the installer to start the installation.
On the Vagrant window, double click on Vagrant.pkg.
On the Welcome to the Vagrant Installer screen, click Continue.
On the Standard Install on “SSD” screen, click Install.
If prompted, enter your password and click Install Software.
Vagrant will begin installing. When it’s done, click Close.
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.
To test that Vagrant is installed, type “vagrant” and hit enter. You should see something like this:
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.
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 Atom.io 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.
Then navigate to the Workspace folder, click devenv and click Open:
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: https://github.com/LondonAppDev/miab-devenv.
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: https://docs.saltstack.com/en/latest/topics/tutorials/walkthrough.html.
Start by creating a directory to hold our Salt States. We will call this “salt”:
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”.
base:
'*':
- 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".
dev_packages:
pkg.installed:
- pkgs:
- python3-dev
- python-pip
- libmysqlclient-dev
# Install "virtualenvwrapper" with pip.
dev_pip_packages:
pip.installed:
- pkgs:
- virtualenvwrapper
# Create the directory for our virtual env.
/usr/local/virtualenvs:
file.directory:
- user: vagrant
- group: vagrant
# Create the virtual environment.
/usr/local/virtualenvs/env:
virtualenv.managed:
- system_site_packages: False
- python: python3.4
- user: vagrant
# Setup virtualenvwrapper.
virtualenvwrapper_configuration:
file.append:
- name: /home/vagrant/.bashrc
- text: |+
WORKON_HOME=/usr/local/virtualenvs
PROJECT_HOME=/project
source /usr/local/bin/virtualenvwrapper.sh
# Setup virtualenvwrapper for root.
virtualenvwrapper_root_configuration:
file.append:
- name: /root/.bashrc
- text: |+
WORKON_HOME=/usr/local/virtualenvs
PROJECT_HOME=/project
source /usr/local/bin/virtualenvwrapper.sh
# Install the MySQL server using the root password of 'password'.
mysql_server_installed:
debconf.set:
- name: mysql-server
- data:
'mysql-server/root_password': {'type': 'string', 'value': 'password'}
'mysql-server/root_password_again': {'type': 'string', 'value': 'password'}
pkg.installed:
- pkgs:
- mysql-server
# Enable the service so MySQL starts when the server boots.
mysql_service_enabled:
service.running:
- name: mysql
- enable: True
# Create a database in MySQL called 'miab_db'
create_database:
mysql_database.present:
- 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
fileserver_backend:
- 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.
config.vm.box = "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.
config.vm.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
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.
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.
Leave a Reply
Want to join the discussion?Feel free to contribute!