Skip to content
This repository has been archived by the owner on Feb 29, 2024. It is now read-only.

Add Docker & Cloud66 Deploy options #43

Open
wants to merge 2 commits into
base: master
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
8 changes: 8 additions & 0 deletions recipes/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,13 @@ def gems

def cook
end

private

def relative_file_content(path)
caller_path = caller_locations.first.path
puts caller_path
File.read(File.join(File.dirname(caller_path), path))
end
end
end
47 changes: 47 additions & 0 deletions recipes/deploy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
module Recipes
class Deploy < Base

is_auto_runnable
askable 'Where are you planning to deploy it?'
optionable %w(Cloud66 Docker None)

def initialize(pathfinder, type: 'none')
super(pathfinder)
end

def cook
case ask!
when 'Docker' then docker_config_files
when 'Cloud66' then cloud66_config_files
end
end

private

def cloud66_config_files
@template.add_file '.cloud66/cache_permissions.sh',
relative_file_content('deploy/cloud66/cache_permissions.sh')
@template.add_file '.cloud66/deploy_hooks.yml',
relative_file_content('deploy/cloud66/deploy_hooks.yml')
end

def docker_config_files
@template.add_file 'docker/rails-env.conf',
relative_file_content('deploy/docker/rails-env.conf')
@template.add_file '.dockerignore',
relative_file_content('deploy/docker/.dockerignore')
@template.append_file 'README.md',
relative_file_content('deploy/docker/README.md')
add_file_and_replace_app_name('docker/fix_permissions.sh',
'deploy/docker/fix_permissions.sh')
add_file_and_replace_app_name('Dockerfile', 'deploy/docker/Dockerfile')
add_file_and_replace_app_name('docker/nginx.conf', 'deploy/docker/nginx.conf')
end

def add_file_and_replace_app_name(target_file, source_file)
@template.add_file target_file, relative_file_content(source_file)
@template.run "sed -i '' 's/app-name/#{@pathfinder.app_name}/g' #{target_file}"
end

end
end
1 change: 1 addition & 0 deletions recipes/deploy/cloud66/cache_permissions.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
chown nginx:app_writers $STACK_BASE/shared/cache && chmod 775 $STACK_BASE/shared/cache && sudo chmod g+s $STACK_BASE/shared/cache
15 changes: 15 additions & 0 deletions recipes/deploy/cloud66/deploy_hooks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
production:
first_thing:
- snippet: cloud66/node
target: rails
execute: true
- snippet: cloud66/newrelic
target: any
execute: true
after_rails:
- source: /.cloud66/cache_permissions.sh
destination: /tmp/cache_permissions.sh
target: rails
run_on: all_servers
execute: true
sudo: true
2 changes: 2 additions & 0 deletions recipes/deploy/docker/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
public/uploads
vendor/bundle
57 changes: 57 additions & 0 deletions recipes/deploy/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
FROM phusion/passenger-ruby24
MAINTAINER MarsBased "hola@marsbased.com"

ENV HOME /home/app/app-name

# Install software dependencies
RUN apt-get update
RUN apt-get install -y imagemagick

# Use baseimage-docker's init system.
CMD ["/sbin/my_init"]

# Expose Nginx HTTP service
EXPOSE 80
EXPOSE 443

# Start Nginx / Passenger
RUN rm -f /etc/service/nginx/down

# Remove the default site
RUN rm /etc/nginx/sites-enabled/default

# Create app home dir
RUN mkdir -p $HOME
WORKDIR $HOME

# Install bundle of gems
ADD Gemfile Gemfile
ADD Gemfile.lock Gemfile.lock
RUN bundle install --without development test

# Add the nginx site and config
ADD docker/nginx.conf /etc/nginx/sites-enabled/app-name.conf
ADD docker/rails-env.conf /etc/nginx/main.d/rails-env.conf

# Add the Rails app
ADD . /home/app/app-name

RUN RAILS_ENV=production SECRET_KEY_BASE=NOT-IMPORTANT bin/rake assets:precompile

# Add a tmp folder for pids
RUN mkdir -p tmp/pids

# Define volumes

VOLUME $HOME/public/uploads
VOLUME $HOME/log

# Configure init scripts
RUN mkdir -p /etc/my_init.d
ADD docker/fix_permissions.sh /etc/my_init.d/fix_permissions.sh
RUN chmod +x /etc/my_init.d/fix_permissions.sh

RUN chown -R app:app $HOME

# Clean up APT and bundler when done.
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*.
17 changes: 17 additions & 0 deletions recipes/deploy/docker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

## Docker

Production deploys are managed with Docker. The Dockerfile makes use of some config files that can be found in the `docker` folder.

- **fix_permissions.sh**: Makes the mountable volumes writable for the
application user.
- **rails-env.conf**: Makes env variables visible to Nginx. As the
application is running on Passenger through Nginx, every ENV variable
that needs to reach the application must be defined here.
- **nginx.conf**: Base nginx configuration. The file contains
instructions to tune the application performance.

It's recommended to use Dockerhub (or a private docker repository) to store the application images and then use docker-compose to orchestrate the deployment.

The docker-compose file is not included in the project and needs to be
configured on a project basis.
3 changes: 3 additions & 0 deletions recipes/deploy/docker/fix_permissions.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh
chown -R app:app /home/app/app-name/public/uploads
chown -R app:app /home/app/app-name/log
30 changes: 30 additions & 0 deletions recipes/deploy/docker/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
server {
listen 80 default_server;
root /home/app/app-name/public;
passenger_enabled on;
passenger_user app;
passenger_ruby /usr/bin/ruby2.4;

## Configure this with the same value of the passenger_max_pool_size
# passenger_min_instances 10;

location ~ ^/assets/ {
expires 1y;
add_header Cache-Control public;
add_header ETag "";
break;
}

location ~ ^/uploads/ {
expires 24h;
add_header Cache-Control public;
add_header ETag "";
break;
}
}

## The number for max_pool_size should be (TOTAL_RAM * 0.75) / RAM_PER_PROCESS
# passenger_max_pool_size 10;

## Configure this option with the app host url to preload app after deploy
# passenger_pre_start https://app-name.com;
3 changes: 3 additions & 0 deletions recipes/deploy/docker/rails-env.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# List here all the ENV variables that need to be available in the application
# Only ENV variable names are expected, not their values.
# env APP_HOST;
15 changes: 14 additions & 1 deletion recipes/simple_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,22 @@ def cook

private

def run_generators
case ask_framework_for_forms
when 'marsman'
@template.initializer 'simple_form.rb',
relative_file_content('simple_form/marsman.rb')
when 'bootstrap'
@template.generate 'simple_form:install --bootstrap'
else
@template.generate 'simple_form:install'
end
end

def add_sample_i18n
@template.run 'rm config/locales/simple_form.en.yml'
@template.append_to_file 'config/locales/en.yml', simple_form_locale('en.yml')
@template.append_to_file 'config/locales/en.yml',
relative_file_content('simple_form/en.yml')
end

def simple_form_locale(filename)
Expand Down