First Railsbox

We’re making a new version of the Food Coop website and I found a few open source options as possible starting points. A php one created in Oklahoma that’s been dormant for a few years, the Oklahoma Food Coop, with whom it had been created, are currently using ASP.NET, which they are hoping to Open Source, potentially with a WordPress front end.

We found a ruby (rails) open source food coop (slash buying club?) package we want to experiment with.

Looked around for some pre-made Vagrant packages, ideally with Chef cookbooks to get a basic Virtual Box up and running Rails on Ruby. Needed something that would work on both Windows and OSX. I had found one that uses Ansible, but that didn’t seem Windows-friendly. Here’s a link to a tutorial that does use Chef, which we may look at again.

For now, running through this tutorial to at least get a basic install up and running.

If (like in a default Windows env) command line ssh isn’t available, might have to use an SSH GUI into which we needed to use vagrant@localhost on port 2222, which we had noticed in the output of vagrant up:

==> default: Forwarding ports...
default: 3000 => 3000 (adapter 1)
default: 22 => 2222 (adapter 1)

At point of running /usr/lib/postgresql/9.1/bin/initdb -D /usr/local/pgsql/data, output included:

WARNING: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the -A option the
next time you run initdb.

Success. You can now start the database server using:

    /usr/lib/postgresql/9.1/bin/postgres -D /usr/local/pgsql/data
or
    /usr/lib/postgresql/9.1/bin/pg_ctl -D /usr/local/pgsql/data -l logfile start

The next command: vagrant@precise32:~$ psql postgres psql gives error:

psql: FATAL:  Peer authentication failed for user "psql"

Tried typing vagrant@precise32:~$ psql and got:

psql: FATAL:  database "vagrant" does not exist`

Changed to user postgres vagrant@precise32:~$ sudo su postgres.

Now:

postgres@precise32:/home/vagrant$ psql
psql (9.1.18)
Type "help" for help.

postgres=# ALTER ROLE vagrant CREATEDB;
ALTER ROLE
postgres=# logout
postgres-# \q

Now if we enter psql we get error:

psql: FATAL:  database "vagrant" does not exist

So let’s create our DB: createdb vagrant and now we can:

vagrant@precise32:~$ psql
psql (9.1.18)
Type "help" for help.

vagrant=# 

Tutorial leaves out a step in installing rvm.

$ sudo apt-get install curl
$ gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
$ \curl -sSL https://get.rvm.io | bash -s stable
$ source /home/vagrant/.rvm/scripts/rvm
$ which rvm
/home/vagrant/.rvm/bin/rvm

And as tutorial explains: The RVM tool has an awesome tool for installing all the various compilers and packages required by Ruby and common libraries: $ rvm requirements.

See which version of ruby are available:

$ rvm list known
# MRI Rubies
[ruby-]1.8.6[-p420] ...

# IronRuby
ironruby[-1.1.3]
ironruby-head

Let’s install the latest stable version of ruby: $ rvm install 2.2.2.

While that downloads and compiles we’ll look at the Docs for getting Foodsoft dev running.

Ruby is installed. Probably don’t need to do this with only one version installed but: rvm use 2.2.2 --default. Checking:

$ which ruby
/home/vagrant/.rvm/rubies/ruby-2.2.2/bin/ruby
vagrant@precise32:~$ ruby -v
ruby 2.2.2p95 (2015-04-13 revision 50295) [i686-linux]

As per above docs, we will want bundler, so: gem install bundler

The rest of that tutorial may not apply to us so logout of Virtaul Box.

Clone the foodsoft repo. I’m going to move our Vagrantfile out of the railsbox directory I’ve been working and clone the Open Source repo into it:

mikekilmer$ mv Vagrantfile ../
mikekilmer$ cd ../
mikekilmer$ rm -rf railsbox
mikekilmer$ mkdir railsbox
mikekilmer$ cd railsbox
mikekilmer$ git clone https://github.com/foodcoops/foodsoft.git .
mikekilmer$ mv ../Vagrantfile .

Now ssh back into guest:

mikekilmer$ vagrant ssh
VM must be created before running this command. Run `vagrant up` first.
jamaaladeen:railsbox mikekilmer$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'hashicorp/precise32'...
==> default: Matching MAC address for NAT networking...
==> default: Checking if box 'hashicorp/precise32' is up to date...
==> default: Setting the name of the VM: railsbox_default_1439161171973_46949
Vagrant cannot forward the specified ports on this VM, since they
would collide with some other application that is already listening
on these ports. The forwarded port to 3000 is already in use
on the host machine.

To fix this, modify your current projects Vagrantfile to use another
port. Example, where '1234' would be replaced by a unique host port:

  config.vm.network :forwarded_port, guest: 3000, host: 1234

Sometimes, Vagrant will attempt to auto-correct this for you. In this
case, Vagrant was unable to. This is usually because the guest machine
is in a state which doesn't allow modifying port forwarding.

Mmmmm. Maybe moving the Vagrantfile and remaking folder not such an awesome idea.

mikekilmer$ vagrant destroy
default: Are you sure you want to destroy the 'default' VM? [y/N] y
==> default: Destroying VM and associated drives...
==> default: Removing hosts

Then still had to open the VirtualBox GUI and remove the old VM. I’m sure there’s a better way of doing this but reconfiguring again will be good for practice with postgres.

Ahh. A few minutes later and where were we…

Okay. Log BACK on to the VM vagrant ssh and install dependencies:

sudo apt-get install libv8-dev libmysqlclient-dev libxml2-dev libxslt1-dev libffi-dev libreadline-dev

vagrant@precise32:~$ sudo apt-get install ruby-bundler
vagrant@precise32:~$ bundle install
Could not locate Gemfile or .bundle/ directory

Somehow we’re not getting folder syncing between host and guest.

vagrant@precise32:~$ ls
postinstall.sh

Wait! Folder syncing occurs within vagrant box under vagrant@precise32:~$ /vagrant directory.

vagrant@precise32:~$ cd /vagrant

I needed to do:

vagrant@precise32:/vagrant$ gem install bundler

That took a little while. Now we’re cookin’ with gas.

vagrant@precise32:/vagrant$ rake foodsoft:setup_development
This task will help you get your foodcoop running in development.
Installing bundler if not installed...
Executing bundle install...
Copying config/app_config.yml...
don't forget to edit config/app_config.yml
Copying config/environments/development.rb...
don't forget to edit config/environments/development.rb
What kind of database do you use?
Options:
(1) MySQL
(2) SQLite

Hey! I thought postgres was an option. Anyway – did some small editing on config/app_config.yml.

$ 1
> don't forget to edit config/database.yml

Hmmm. Looks like we may need to run gem install mysql2. Did so in a new vagrant ssh session.

Also states:

# Ensure the MySQL gem is defined in your Gemfile
#   gem 'mysql2'

vagrant@precise32:~$ cd /vagrant/
vagrant@precise32:/vagrant$ gem 'mysql2'
ERROR:  While executing gem ... (Gem::CommandLineError)
Unknown command mysql2

No, idiot! That’s one of the lines already in the Gemfile. mysql2 was probably already installed.

Not there yet:

#<Mysql2::Error: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)>

Answer on SO?

vagrant@precise32:/vagrant$ mysqladmin variables | grep socket
The program 'mysqladmin' is currently not installed.  You can install it by typing:
sudo apt-get install mysql-client-5.5

Installed above.

vagrant@precise32:/vagrant$ mysqladmin variables | grep socket
mysqladmin: connect to server at 'localhost' failed
error: 'Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)'
Check that mysqld is running and that the socket: '/var/run/mysqld/mysqld.sock' exists!

Wait a minute! Where did I get the idea that this package was set up to use Postgres?

vagrant@precise32:/vagrant$ sudo apt-get install mysql-server

I chose root as the password for the MySQL root user, since we’re just running locally anyway. Matched it in config/database.yml.

Let’s try this again:

vagrant@precise32:/vagrant$ rake foodsoft:setup_development
We found config/app_config.yml!
Options:
(1) Skip step
(2) Force rewrite
1
We found config/environments/development.rb!
Options:
(1) Skip step
(2) Force rewrite
1
We found config/database.yml!
Options:
(1) Skip step
(2) Force rewrite
2

My selections above were: 1, 1, and 2.

More MySql Errors! I think server not running.

vagrant@precise32:/vagrant$ service mysql start
start: Rejected send message, 1 matched rules; type="method_call", sender=":1.3" (uid=1000 pid=25056 comm="start mysql ") interface="com.ubuntu.Upstart0_6.Job" member="Start" error name="(unset)" requested_reply="0" destination="com.ubuntu.Upstart" (uid=0 pid=1 comm="/sbin/init")

vagrant@precise32:/vagrant$ sudo /etc/init.d/mysql start
Rather than invoking init scripts through /etc/init.d, use the service(8)
utility, e.g. service mysql start

Since the script you are attempting to invoke has been converted to an
Upstart job, you may also use the start(8) utility, e.g. start mysql
vagrant@precise32:/vagrant$ start mysql
start: Rejected send message, 1 matched rules; type="method_call", sender=":1.5" (uid=1000 pid=25073 comm="start mysql ") interface="com.ubuntu.Upstart0_6.Job" member="Start" error name="(unset)" requested_reply="0" destination="com.ubuntu.Upstart" (uid=0 pid=1 comm="/sbin/init")

vagrant@precise32:/vagrant$ start mysql
start: Rejected send message, 1 matched rules; type="method_call", sender=":1.5" (uid=1000 pid=25073 comm="start mysql ") interface="com.ubuntu.Upstart0_6.Job" member="Start" error name="(unset)" requested_reply="0" destination="com.ubuntu.Upstart" (uid=0 pid=1 comm="/sbin/init")
vagrant@precise32:/vagrant$ sudo start mysql
start: Job is already running: mysql
vagrant@precise32:/vagrant$ mysql
ERROR 1045 (28000): Access denied for user 'vagrant'@'localhost' (using password: NO)
vagrant@precise32:/vagrant$ 

vagrant@precise32:/vagrant$ mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 47
Server version: 5.5.44-0ubuntu0.12.04.1 (Ubuntu)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> CREATE DATABASE foodsoft_development;
    mysql> exit
    vagrant@precise32:/vagrant$ mysql -h localhost -u root -p foodsoft_development
    mysql> exit

vagrant@precise32:/vagrant$ mysql -h localhost -u root -p foodsoft_development
Couldn't create database for {"adapter"=>"mysql2", "encoding"=>"utf8", "reconnect"=>false, "database"=>"foodsoft_test", "pool"=>5, "host"=>"localhost"}
rake aborted!

(Among other errors) Maybe the database shouldn’t be there.

mysql> DROP DATABASE foodsoft_development;

What does the doc/prompt mean by Setup your database before you continue!

Okay. Wait – the database config file is reset to password password now. Let’s try changing the mysql root password to match it:

mysql> use mysql;
mysql> update user set password=PASSWORD("password") where User='root';
mysql> exit
vagrant@precise32:/vagrant$ rake foodsoft:setup_development

Now I’m force-rewriting everything.
Same errors.

vagrant@precise32:/vagrant$ sudo restart mysql
vagrant@precise32:/vagrant$ rake foodsoft:setup_development --trace
Finished?
Options:
(y) Yes
y
** Invoke db:setup (first_time)
** Invoke db:schema:load_if_ruby (first_time)
** Invoke db:create (first_time)
** Invoke db:load_config (first_time)
** Execute db:load_config
** Execute db:create

Hey wait. That database username and passwd are only set for the production server! Setting username and password in the RIGHT PLACE (and not overwriting it in the rake command solved the problem.

Now to start the rails server:

vagrant@precise32:/vagrant$ bundle exec rails s
=> Booting Thin
=> Rails 4.2.3 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
Exiting
/home/vagrant/.rvm/gems/ruby-2.2.2/gems/polyglot-0.3.5/lib/polyglot.rb:65:in `require': cannot load such file -- /vagrant/config/environment (LoadError)
    from /home/vagrant/.rvm/gems/ruby-2.2.2/gems/polyglot-0.3.5/lib/polyglot.rb:65:in `require'
    from /home/vagrant/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/dependencies.rb:274:in `block in require'

Getting great feedback from Github Repo ower who recommends, “If all else fails, you might try running with Docker instead, which with we have a little more experience.”

In the mean time, what is Rake?

Apparently I had inadvertently deleted the file config/environment.rb.

Next error was because the MySQL database had not been created.

Next thing I did was rm -rf the entire foodsoft repository and do a clean install.

I repeated the process half a dozen times (removing and starting with a clean git clone) and kept getting error:

Mysql2::Error: Access denied for user 'root'@'localhost' (using password: NO)

Even after confirming:

development:
  adapter: mysql2
  encoding: utf8
  reconnect: false
  database: foodsoft_development
  pool: 5
  host: localhost
  username: root
  password: password

Wait a minute… that’s because I hadn’t set a username and password in the test environment, wasn’t it!

So the trick is:

rake foodsoft:setup_development

Get through selecting DB type (MySQL)
NOW set configuration (username, password for ALL environments in config/database.yml)
THEN click yes (y).

Unfortunately, though the rails server is running, I’m getting server not found on:

http://localhost:3000

Ah! Thank you Stack Overflow. It needs to be called slightly differently for Vagrant:

bundle exec rails s -b 0.0.0.0

Up and running!


Now we’ve got to log in as an Administrator to the system. What are the credentials. Let’s look in the MySQL database: $ mysql -uroot -p, SHOW DATABASES;, SHOW TABLES;, USE foodsoft_development;, SHOW TABLES;, SELECT * FROM USERS;.

OK. Find see that admin@foo.test is the admin user. Let’s search the code for where the password is set. It’s declared in three different places:

  • `db/migrate/001_create_users.rb`
  • `db/seeds/minimal.seeds.rb`
  • `db/seeds/small.en.seeds.rb`
  • `db/seeds/small.nl.seeds.rb`