diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 00000000..ed857e57
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,20 @@
+FROM ruby
+
+# NOTE https://yarnpkg.com/en/docs/install#linux-tab
+RUN curl -sL https://deb.nodesource.com/setup_7.x | bash -
+RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
+RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
+
+RUN apt-get update -qq && apt-get install -y build-essential libpq-dev yarn
+RUN yarn global add phantomjs-prebuilt
+
+RUN mkdir /hyper-mesh
+WORKDIR /hyper-mesh
+
+ADD Gemfile.lock .
+ADD Gemfile .
+ADD hyper-mesh.gemspec .
+ADD lib/hypermesh/version.rb lib/hypermesh/
+RUN bundle install --frozen
+
+ADD . .
diff --git a/Gemfile b/Gemfile
index 8fdb0991..d7ad0e79 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,5 +1,7 @@
 source 'https://rubygems.org'
-# Specify your gem's dependencies in synchromesh.gemspec
+
+# NOTE these must be here, and http://stackoverflow.com/questions/41245385/what-are-the-practical-advantages-of-using-add-development-dependency-in-gems in general
 gem 'hyper-trace'
 gem 'opal-browser'
+
 gemspec
diff --git a/codeship.database.yml b/codeship.database.yml
index 66dd6da3..0bbb37b9 100644
--- a/codeship.database.yml
+++ b/codeship.database.yml
@@ -1,18 +1,16 @@
 development:
   adapter: mysql2
-  host: localhost
+  host: <%= ENV['MYSQL_HOST'] || 'localhost' %>
   encoding: utf8
   pool: 10
   username: <%= ENV['MYSQL_USER'] %>
   password: <%= ENV['MYSQL_PASSWORD'] %>
   database: development<%= ENV['TEST_ENV_NUMBER'] %>
-  socket: /var/run/mysqld/mysqld.sock
 test:
   adapter: mysql2
-  host: localhost
+  host: <%= ENV['MYSQL_HOST'] || 'localhost' %>
   encoding: utf8
   pool: 10
   username: <%= ENV['MYSQL_USER'] %>
   password: <%= ENV['MYSQL_PASSWORD'] %>
   database: test<%= ENV['TEST_ENV_NUMBER'] %>
-  socket: /var/run/mysqld/mysqld.sock
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 00000000..4f659705
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,15 @@
+version: '2.1'
+services:
+  mysql:
+    environment:
+      - MYSQL_ALLOW_EMPTY_PASSWORD=1
+    image: mysql
+  spec:
+    build: .
+    depends_on:
+      - mysql
+    volumes:
+      - .:/hyper-mesh
+    environment:
+      - MYSQL_HOST=mysql
+    command: bash -c 'spec/test_app/bin/setup && bundle exec rake spec'
diff --git a/hyper-mesh.gemspec b/hyper-mesh.gemspec
index 0e583b78..ceea21c9 100644
--- a/hyper-mesh.gemspec
+++ b/hyper-mesh.gemspec
@@ -43,7 +43,7 @@ Gem::Specification.new do |s|
 
     s.add_development_dependency 'pusher'
     s.add_development_dependency 'pusher-fake'
-    s.add_development_dependency 'opal-browser'
+    # NOTE see Gemfile, will not work: s.add_development_dependency 'opal-browser'
 
     if RUBY_PLATFORM == 'java'
       s.add_development_dependency 'jdbc-sqlite3'
@@ -77,6 +77,6 @@ Gem::Specification.new do |s|
       s.add_development_dependency 'unparser'
       s.add_development_dependency 'jquery-rails'
       s.add_development_dependency 'pry-byebug'
-      #s.add_development_dependency 'hyper-trace'
+      # NOTE see Gemfile, will not work: s.add_development_dependency 'hyper-trace'
     end
 end
diff --git a/spec/test_app/Gemfile.lock b/spec/test_app/Gemfile.lock
index 36b80898..18804f7d 100644
--- a/spec/test_app/Gemfile.lock
+++ b/spec/test_app/Gemfile.lock
@@ -1,7 +1,7 @@
 PATH
   remote: ../..
   specs:
-    hyper-mesh (0.4.0)
+    hyper-mesh (0.5.3)
       activerecord (>= 0.3.0)
       hyper-react (>= 0.10.0)
 
@@ -70,7 +70,7 @@ GEM
     globalid (0.3.7)
       activesupport (>= 4.1.0)
     hike (1.2.3)
-    hyper-react (0.10.0)
+    hyper-react (0.11.0)
       opal (>= 0.8.0)
       opal-activesupport (>= 0.2.0)
       react-rails
@@ -250,4 +250,4 @@ DEPENDENCIES
   web-console (~> 2.0)
 
 BUNDLED WITH
-   1.12.5
+   1.13.6
diff --git a/spec/test_app/bin/setup b/spec/test_app/bin/setup
index acdb2c13..8071c085 100755
--- a/spec/test_app/bin/setup
+++ b/spec/test_app/bin/setup
@@ -25,5 +25,5 @@ Dir.chdir APP_ROOT do
   system "rm -rf tmp/cache"
 
   puts "\n== Restarting application server =="
-  system "touch tmp/restart.txt"
+  system "mkdir -p tmp && touch tmp/restart.txt"
 end
diff --git a/spec/test_app/config/database.yml b/spec/test_app/config/database.yml
index eab4458b..02102760 100644
--- a/spec/test_app/config/database.yml
+++ b/spec/test_app/config/database.yml
@@ -9,7 +9,7 @@ default: &default
   encoding: utf8
   username: root
   password:
-  host: 127.0.0.1
+  host: <%= ENV['MYSQL_HOST'] || 'localhost' %>
   port: 3306
   pool: 5
   timeout: 10000