Skip to content
Nhat Le edited this page Jan 12, 2016 · 123 revisions

We try to automate as much as possible to avoid mistakes or repetitive work. With that in mind, there are a few things that need to be done to get the various environments set up.

Development Environment: Vagrant

The Vagrant Box runs like the production server on localhost using nginx and uwsgi. This is probably the easiest way to get up and running.

###1. Setting up

  1. Install dependencies:

    • Download and install Vagrant
    • Download and install VirtualBox (or whatever virtual machine you'd like)
    • Download and install pip
    • Install Ansible using sudo pip install ansible
  2. Setup up the git repository:

    • Create a folder where the repository will be & navigate to it
    • Clone git repo:
    git clone git@github.com:Willet/SecondFunnel.git
    
  3. Run the environment:

    • Navigate to the Second Funnel directory with the Git repo, and run the following commands in terminal:
    vagrant init
    
    • Replace the newly created Vagrantfile in /SecondFunnel with this: Vagrantfile
    • Ask for your public SSH key be added to the git repo as a role, then run:
    vagrant up 
    vagrant ssh
    
    • The first vagrant up will take a long time, subsequent times will be fast.
    • Note: If you are using the Intern computer the following alias' exist (can be edited in ~/.zshrc):

alias secondfunnel="cd /Users/Intern/Documents/Willet/Github/Secondfunnel" - Once you have ssh'ed into vagrant, activate virtualenv (located in /opt/secondfunnel/venv): navigate to /opt/secondfunnel/app, then run . ../venv/bin/activate ```` 4. Install required environment dependencies - In /opt/secondfunnel/app run `sudo pip install -r requirements/dev.txt` - Go grab lunch, this could take over an hour.

  1. Import Postgres database:

    • Download the db .txt dump (a co-worker will provide it) & put it in the Second Funnel directory
    • Back in the Vagrant environment, navigate to /opt/secondfunnel/app, change the db .txt file permissions to something permissive (ex: chmod 777 [name of db text file]), then run the following commands in terminal:
    sudo su postgres
    psql sfdb < [name of db text file]
    
    • Note: afterwards, remember to log out of postgres with exit
  2. Enable static page generation:

  3. Add local environment variables

    • in /secondfunnel/settings/ create local.py
    • add your slack username: SLACK_USERNAME = '_your_username_'
  4. Enable Fabric database updates:

    • Get Fabric using sudo pip install fabric
    • Generate ssh key using ssh-keygen -t rsa
    • Ask for your public key, located at /home/user/.ssh/id_dsa.pub, to be added to Ansible roles
    • Note: it may take a couple of days for the AMI to update before you can use Fabric

###2. Usage

  • Every time, boot up the environment by running:
vagrant up 
vagrant ssh
cd /opt/secondfunnel/app
. ../venv/bin/activate
  • Things to know:
    • The app is located on the VM in /opt/secondfunnel/app (this is also /vagrant)
    • Files in the project can be accessed from within the vagrant box (which has the full environment) or outside of it (since the directory that the Vagrantfile is in is mounted in the VM).
    • Every time after changing static files, you will have to run gulp (otherwise changes will not be seen). From /opt/secondfunnel/app/apps/light run either sudo gulp build to do a simple build, or sudo gulp vagrant-dev to set gulp running continuously (should notice any changes as soon as they are saved).
    • Update database data with fab production database.remote_to_local
    • These aliases will save you a lot time (add to /home/vagrant/.profile):
alias setup-env="cd /opt/secondfunnel/app; . ../venv/bin/activate;"
alias gulp-dev="sudo gulp --cwd '/opt/secondfunnel/app/apps/light' vagrant-dev;"
alias gulp-build="sudo gulp --cwd '/opt/secondfunnel/app/apps/light' build-collect;"
alias runserver="cd /opt/secondfunnel/app; sudo python manage.py runserver_plus 0.0.0.0:80;"
alias shell-plus="cd /opt/secondfunnel/app; python manage.py shell_plus;"
alias clean-pyc="sudo find . -name '*.pyc' -exec rm -rf {} \;"
alias runtests="python manage.py test --settings=secondfunnel.settings.nosetests_runner -v 2; printf '\a\a\a';"

###3. Debugging: ####Useful commands for debugging

  • Show hidden files:
    • Open a terminal window and type: defaults write com.apple.finder AppleShowAllFiles YES
    • Hold the Option/Alt key then right click Finder and choose Relaunch
  • Hide hidden files
    • Open a terminal window and type: defaults write com.apple.finder AppleShowAllFiles NO
    • Hold the Option/Alt key then right click Finder and choose Relaunch

####vagrant up

  • Vagrant unable to SSH connect with VM (message: default: Warning: Connection timeout. Retrying...) or freezes during vagrant up (message: default: Configuring and enabling network interfaces...)

    • Some network routers will not allow IP assignment to the bridged VM. In the Vagrantfile disable the public_network and enable the private_network.
  • Vagrant unable to connect using private_network configuration with type: "dhcp", error message:

    A host only network interface you're attempting to configure via DHCP already has a conflicting host only adapter with DHCP enabled. The DHCP on this adapter is incompatible with the DHCP settings. Two host only network interfaces are not allowed to overlap, and each host only network interface can have only one DHCP server. Please reconfigure your host only network or remove the virtual machine using the other host only network.

    • Last VM is possibly running in a headless state. See Headless VM instructions below.
  • Vagrant fails on: db | Install Postgres latest authentication with message: SSH Error: Permission denied (publickey,password).

    • There is an issue with the default ssh key, so you have to point vagrant to your own key (the one you added to the roles in step 3). After running vagrant up (which will copy the ssh keys to the VM), add this line to the Vagrantfile and then run vagrant provision:

config.ssh.private_key_path = ['~/Github/SecondFunnel/.vagrant/machines/default/virtualbox/private_key', '~/.ssh/yourprivatekey']

  • If the above doesn't work change the private_key_path to the following: config.ssh.private_key_path = "~/.ssh/yourprivatekey"

  • Install mac-ssh-askpass by following the instructions here: https://github.com/markcarver/mac-ssh-askpass (use the manual option)

  • Check that the your private key is added to local ssh-agent by running ssh-add -L, if not run ssh-add ~/.ssh/yourprivatekey

    • Add your public key to ~/.ssh/authorized_keys on the VM by doing the following:
      • Linux:
        • ssh-copy-id -i ~/.ssh/yourpublickey "vagrant@localhost -p 2222"
      • Mac OS:
        • curl -L https://raw.githubusercontent.com/beautifulcode/ssh-copy-id-for-OSX/master/install.sh | sh
        • ssh-copy-id -i ~/.ssh/yourpublickey "vagrant@localhost -p 2222"
  • Rerun vagrant provision and it should work properly now

  • If you have to reformat the VM and restart for some reason, don't forget to remove the insecure_private_key file in /users/USERNAME/.vagrant.d/ or you will get default: Warning: Authentication failure. Retrying...

####localhost

  • localhost is unavailable
    • Check port is correct
    • Check from within the VM the server is running with curl localhost/admin/. Sometimes the Django server does not start up automatically. In secondfunnel/app/apps/light run sudo python manage.py runserver_plus 0.0.0.0:80
    • Check the ports and ip's match (Vagrantfile, ifconfig in VM, VBoxManage list dhcpservers in host)
    • Check for any a firewall blocking the port: iptables, ipfw, ipfilter, ufw...
  • python manage.py runserver_plus errors with message: python socket.error: [Errno 98] Address already in use
    • Last VM is possibly running in a headless state taking the socket. See Headless VM instructions below to kill it.
    • Restart VM
  • localhost responds with Nginx 404
    • Restart VM

####Postgres

  • Postgres commands (pg_dump, pg_restore, etc) failing with access denied. (pg_dump: [archiver (db)] query failed: ERROR: permission denied for relation assets_category)
    • The database was restored without setting the database owner to sf. In the VM, switch to postgres user and set permission:
sudo -u postgres -i
psql sfdb -c "GRANT ALL ON ALL TABLES IN SCHEMA public TO sf;"
psql sfdb -c "GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO sf;"
psql sfdb -c "GRANT ALL ON ALL FUNCTIONS IN SCHEMA public TO sf;"
psql sfdb -c "GRANT ALL ON DATABASE sfdb TO sf;"
exit
  • psql sfdb < db.dump error psql: FATAL: database "sfdb" does not exist
    • The database needs to be created first: createdb -O sf sfdb
  • psql sfdb < db.dump error ERROR: role "willet" does not exist
    • The db.dump needs to be recreated with flags --no-owner and --no-privileges:
pg_dump --no-owner --no-privileges sfdb > db.dump

####Headless VM

  • How to kill a running Headless VM: A) Check Activity Monitor and kill the Virtualbox daemon (VBoxSVC) B) Get PID of headless VBoxSVC (VBoxSVC), then terminate the process:
$ /bin/ps aux|grep VBoxSVC
username    19931   0.0  0.1  2484532   4568   ??  S    Wed12pm   3:16.04 /Applications/VirtualBox.app/Contents/MacOS/VBoxSVC --auto-shutdown
$ sudo kill -9 19931
  • If that doesn't work, run this command in Terminal: VBoxManage dhcpserver remove --netname HostInterfaceNetworking-vboxnet0

####Gulp Dev If gulp dev runs out of memory and crashes every time you use it, you might not have a swap space enabled on your machine. Some errors that were solved included ENOMEM and JS: allocation failed. To check if you have swap space enabled, free -g. To add a swap space:

  1. sudo fallocate -l 4G /swapfile Create a 4 gigabyte swapfile
  2. sudo chmod 600 /swapfile Secure the swapfile by restricting access to root
  3. sudo mkswap /swapfile Mark the file as a swap space
  4. sudo swapon /swapfile Enable the swap

Deployment

To Production

Create a pull request that merges branch dev into branch master. Please refrain from merging other branch's into master. Also try not to delete master (although that gets the achievement "The only winning move is not to play").

To Stage

Create a pull request to merge into dev. This can be done with any branch after it undergoes code review.

Other (may still be useful?)

###1. AMQP broker for Celery

In production, we're currently using Amazon SQS. In development, use something like RabbitMQ.

See notes on installing RabbitMQ, and if you're on OSX, see this OSX installation guide.

See notes on working with Celery, brokers and tasks.

  • Ensure RabbitMQ is running: sudo rabbitmqctl status
    • if not running, start it: sudo rabbitmq-server
    • to stop it, use this (never kill the process): sudo rabbitmqctl stop
  • Run celery worker to execute async tasks: python manage.py celery worker --loglevel=info

###2. Memcached

You need to have memcached up and running on your dev machine in order to test caching. Default development settings point to the standard memcached port (11211). It's recommended to run memcached in verbose mode, so that you see what's going on: memcached -vv.

Clone this wiki locally