Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docker support #242

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .dockeringore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.git
.env
.dockerignore
.byebug_history
log/*
tmp/*
43 changes: 43 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Use the barebones version of Ruby 2.2.3.
FROM ruby:2.2.3-slim

# Optionally set a maintainer name to let people know who made this image.
MAINTAINER Gaurav Koley <[email protected]>

# Install dependencies:
# - build-essential: To ensure certain gems can be compiled
# - nodejs: Compile assets
# - libpq-dev: Communicate with postgres through the postgres gem
# - postgresql-client-9.4: In case you want to talk directly to postgres
# Install essential Linux packages
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev postgresql-client git

# Define where our application will live inside the image
ENV RAILS_ROOT /var/www/bookanook

# Create application home. App server will need the pids dir so just create everything in one shot
RUN mkdir -p $RAILS_ROOT/tmp/pids

# Set our working directory inside the image
WORKDIR $RAILS_ROOT

# Use the Gemfiles as Docker cache markers. Always bundle before copying app src.
# (the src likely changed and we don't want to invalidate Docker's cache too early)
# http://ilikestuffblog.com/2014/01/06/how-to-skip-bundle-install-when-deploying-a-rails-app-to-docker/
COPY Gemfile Gemfile

COPY Gemfile.lock Gemfile.lock

# Prevent bundler warnings; ensure that the bundler version executed is >= that which created Gemfile.lock
RUN gem install bundler

# Finish establishing our Ruby enviornment
RUN bundle install

# Copy the Rails application into place
COPY . .

RUN bundle exec rake assets:precompile
# Define the script we want run once the container boots
# Use the "exec" form of CMD so our script shuts down gracefully on SIGTERM (i.e. `docker stop`)
CMD ["bundle", "exec", "puma", "-C", "config/containers/puma.rb"]
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
source 'https://rubygems.org'


gem 'puma'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.2.5'
gem 'pg'
Expand Down
2 changes: 2 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ GEM
orm_adapter (0.5.0)
pg (0.18.4)
pr_geohash (1.0.0)
puma (3.10.0)
rack (1.6.4)
rack-test (0.6.3)
rack (>= 1.0)
Expand Down Expand Up @@ -330,6 +331,7 @@ DEPENDENCIES
mini_magick
omniauth-google-oauth2 (~> 0.4.1)
pg
puma
rails (= 4.2.5)
remotipart (~> 1.2)
rolify
Expand Down
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,34 @@ Works well with:
Setup
-----

## Setup using Docker & Docker-Compose
1. Clone the repository:

`git clone https://github.com/berkmancenter/bookanook.git`

Or clone down from your own fork of the repository.

2. Go to the application's root directory in terminal: `cd bookanook`

3. Run `cp config/social_keys.yml.sample config/social_keys.yml`. Add your own key and secret for Google authentication by setting up OAuth for your environment [here](https://cloud.google.com/ruby/getting-started/authenticate-users).

4. Create a `.env` file in the project root and populate with the preferred rails environment as follows:
```
RAILS_ENV=production
SECRET_KEY_BASE=<some key>
DEVISE_SECRET_KEY=<some key>
RAILS_SERVE_STATIC_FILES=true
```

5. Run Docker-Compose to build images: `docker-compose build`

6. Setup Docker Database: `docker-compose run app rake db:create db:migrate db:seed`

7. Run the docker images: `docker-compose up -d`

8. To stop the app: `docker-compose stop`

## Regular Setup
1. Clone the repository

`git clone https://github.com/berkmancenter/bookanook.git`
Expand Down
27 changes: 27 additions & 0 deletions config/containers/Dockerfile-nginx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# build from the official Nginx image
FROM nginx

# install essential Linux packages
RUN apt-get update -qq && apt-get -y install apache2-utils

# establish where Nginx should look for files
ENV RAILS_ROOT /var/www/bookanook

# Set our working directory inside the image
WORKDIR $RAILS_ROOT

# create log directory
RUN mkdir log

# copy over static assets
COPY public public/

# copy our Nginx config template
COPY config/containers/nginx.conf /tmp/bookanook.nginx

# substitute variable references in the Nginx config template for real values from the environment
# put the final config in its place
RUN envsubst '$RAILS_ROOT' < /tmp/bookanook.nginx > /etc/nginx/conf.d/default.conf

# Use the "exec" form of CMD so Nginx shuts down gracefully on SIGTERM (i.e. `docker stop`)
CMD [ "nginx", "-g", "daemon off;" ]
58 changes: 58 additions & 0 deletions config/containers/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# From http://chrisstump.online/2016/02/20/docker-existing-rails-application/

upstream puma {
server app:3000;
}

server {
# define your domain
server_name localhost;

# define the public application root
root /app/public;
index index.html;

# define where Nginx should write its logs
access_log $RAILS_ROOT/log/nginx.access.log;
error_log $RAILS_ROOT/log/nginx.error.log;

# deny requests for files that should never be accessed
location ~ /\. {
deny all;
}

location ~* ^.+\.(rb|log)$ {
deny all;
}

# serve static (compiled) assets directly if they exist (for rails production)
location ~ ^/(assets|images|javascripts|stylesheets|swfs|system)/ {
try_files $uri @rails;

access_log off;
gzip_static on; # to serve pre-gzipped version

expires max;
add_header Cache-Control public;

# Some browsers still send conditional-GET requests if there's a
# Last-Modified header or an ETag header even if they haven't
# reached the expiry date sent in the Expires header.
add_header Last-Modified "";
add_header ETag "";
break;
}

# send non-static file requests to the app server
location / {
try_files $uri @rails;
}

location @rails {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://puma;
}
}
18 changes: 18 additions & 0 deletions config/containers/puma.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Where our application lives. $RAILS_ROOT is defined in our Dockerfile.
app_path = ENV['RAILS_ROOT']

workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['RAILS_MAX_THREADS'] || 5)
threads threads_count, threads_count

preload_app!

rackup DefaultRackup
port ENV['PORT'] || 3000
environment ENV['RACK_ENV'] || 'development'

on_worker_boot do
# Worker specific setup for Rails 4.1+
# See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot
ActiveRecord::Base.establish_connection
end
4 changes: 3 additions & 1 deletion config/database.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
default: &default
adapter: postgresql
user: postgres
password: postgres
password: <%= ENV['POSTGRES_PASSWORD'] %>
host: db
port: 5432
pool: 5
timeout: 5000

Expand Down
2 changes: 1 addition & 1 deletion config/initializers/devise.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# The secret key used by Devise. Devise uses this key to generate
# random tokens. Changing this key will render invalid all existing
# confirmation, reset password and unlock tokens in the database.
# config.secret_key = '8109f42647fa2b09a1420ef23e76d520c7dd205cac3d0abd3ef4ddf72d1bfdcc0da5503c18e730fa42e48287031db075eb7603dc8d405c1b4b407dfdd95a84e8'
config.secret_key = ENV['DEVISE_SECRET_KEY']

# ==> Mailer Configuration
# Configure the e-mail address which will be shown in Devise::Mailer,
Expand Down
9 changes: 9 additions & 0 deletions docker-compose.override.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
app:
# map our application source code, in full, to the application root of our container
volumes:
- .:/var/www/bookanook

web:
# use whatever volumes are configured for the app container
volumes_from:
- app
41 changes: 41 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# service configuration for our dockerized Rails app
app:

# use the Dockerfile next to this file
build: .
# sources environment variable configuration for our app
env_file: .env
# rely on the RAILS_ENV value of the host machine
environment:
RAILS_ENV: $RAILS_ENV
# persistent storage across containers for app
volumes:
- assets:/var/www/bookanook/public/assets
# makes the app container aware of the DB container
links:
- db
# expose the port we configured Unicorn to bind to
expose:
- "3000"

# service configuration for our database
db:
# use the preferred version of the official Postgres image
# see https://hub.docker.com/_/postgres/
image: postgres:9.4.5
# persist the database between containers by storing it in a volume
volumes:
- bookanook-postgres:/var/lib/postgresql/data

# service configuration for our web server
web:
# set the build context to the root of the Rails app
build: .
# build with a different Dockerfile
dockerfile: config/containers/Dockerfile-nginx
# makes the web container aware of the app container
links:
- app
# expose the port we configured Nginx to bind to
ports:
- "80:80"