parent
c35205c1b0
commit
f5bea41ccf
10 changed files with 0 additions and 338 deletions
6
Gemfile
6
Gemfile
|
@ -85,12 +85,6 @@ group :development do
|
||||||
|
|
||||||
# Hide assets requests in log
|
# Hide assets requests in log
|
||||||
gem 'quiet_assets'
|
gem 'quiet_assets'
|
||||||
|
|
||||||
# Deploy with Capistrano
|
|
||||||
gem 'capistrano', '~> 3.2.0', require: false
|
|
||||||
gem 'capistrano-rvm', require: false
|
|
||||||
gem 'capistrano-bundler', '>= 1.1.0', require: false
|
|
||||||
gem 'capistrano-rails', require: false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
|
|
23
Gemfile.lock
23
Gemfile.lock
|
@ -104,19 +104,6 @@ GEM
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
uniform_notifier (~> 1.10.0)
|
uniform_notifier (~> 1.10.0)
|
||||||
callsite (0.0.11)
|
callsite (0.0.11)
|
||||||
capistrano (3.2.1)
|
|
||||||
i18n
|
|
||||||
rake (>= 10.0.0)
|
|
||||||
sshkit (~> 1.3)
|
|
||||||
capistrano-bundler (1.3.0)
|
|
||||||
capistrano (~> 3.1)
|
|
||||||
sshkit (~> 1.2)
|
|
||||||
capistrano-rails (1.3.0)
|
|
||||||
capistrano (~> 3.1)
|
|
||||||
capistrano-bundler (~> 1.1)
|
|
||||||
capistrano-rvm (0.1.2)
|
|
||||||
capistrano (~> 3.0)
|
|
||||||
sshkit (~> 1.2)
|
|
||||||
capybara (2.13.0)
|
capybara (2.13.0)
|
||||||
addressable
|
addressable
|
||||||
mime-types (>= 1.16)
|
mime-types (>= 1.16)
|
||||||
|
@ -267,9 +254,6 @@ GEM
|
||||||
mono_logger (1.1.0)
|
mono_logger (1.1.0)
|
||||||
multi_json (1.12.2)
|
multi_json (1.12.2)
|
||||||
mysql2 (0.4.9)
|
mysql2 (0.4.9)
|
||||||
net-scp (1.2.1)
|
|
||||||
net-ssh (>= 2.6.5)
|
|
||||||
net-ssh (4.2.0)
|
|
||||||
nokogiri (1.8.1)
|
nokogiri (1.8.1)
|
||||||
mini_portile2 (~> 2.3.0)
|
mini_portile2 (~> 2.3.0)
|
||||||
pdf-core (0.7.0)
|
pdf-core (0.7.0)
|
||||||
|
@ -447,9 +431,6 @@ GEM
|
||||||
activesupport (>= 4.0)
|
activesupport (>= 4.0)
|
||||||
sprockets (>= 3.0.0)
|
sprockets (>= 3.0.0)
|
||||||
sqlite3 (1.3.13)
|
sqlite3 (1.3.13)
|
||||||
sshkit (1.14.0)
|
|
||||||
net-scp (>= 1.1.2)
|
|
||||||
net-ssh (>= 2.8.0)
|
|
||||||
term-ansicolor (1.6.0)
|
term-ansicolor (1.6.0)
|
||||||
tins (~> 1.0)
|
tins (~> 1.0)
|
||||||
therubyracer (0.12.3)
|
therubyracer (0.12.3)
|
||||||
|
@ -508,10 +489,6 @@ DEPENDENCIES
|
||||||
binding_of_caller
|
binding_of_caller
|
||||||
bootstrap-datepicker-rails
|
bootstrap-datepicker-rails
|
||||||
bullet
|
bullet
|
||||||
capistrano (~> 3.2.0)
|
|
||||||
capistrano-bundler (>= 1.1.0)
|
|
||||||
capistrano-rails
|
|
||||||
capistrano-rvm
|
|
||||||
capybara
|
capybara
|
||||||
capybara-webkit
|
capybara-webkit
|
||||||
connection_pool
|
connection_pool
|
||||||
|
|
1
Rakefile
1
Rakefile
|
@ -1,6 +1,5 @@
|
||||||
#!/usr/bin/env rake
|
#!/usr/bin/env rake
|
||||||
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
||||||
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
|
||||||
|
|
||||||
require File.expand_path('../config/application', __FILE__)
|
require File.expand_path('../config/application', __FILE__)
|
||||||
require 'rake'
|
require 'rake'
|
||||||
|
|
16
bin/cap
16
bin/cap
|
@ -1,16 +0,0 @@
|
||||||
#!/usr/bin/env ruby
|
|
||||||
#
|
|
||||||
# This file was generated by Bundler.
|
|
||||||
#
|
|
||||||
# The application 'cap' is installed as part of a gem, and
|
|
||||||
# this file is here to facilitate running it.
|
|
||||||
#
|
|
||||||
|
|
||||||
require 'pathname'
|
|
||||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
|
||||||
Pathname.new(__FILE__).realpath)
|
|
||||||
|
|
||||||
require 'rubygems'
|
|
||||||
require 'bundler/setup'
|
|
||||||
|
|
||||||
load Gem.bin_path('capistrano', 'cap')
|
|
16
bin/capify
16
bin/capify
|
@ -1,16 +0,0 @@
|
||||||
#!/usr/bin/env ruby
|
|
||||||
#
|
|
||||||
# This file was generated by Bundler.
|
|
||||||
#
|
|
||||||
# The application 'capify' is installed as part of a gem, and
|
|
||||||
# this file is here to facilitate running it.
|
|
||||||
#
|
|
||||||
|
|
||||||
require 'pathname'
|
|
||||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
|
||||||
Pathname.new(__FILE__).realpath)
|
|
||||||
|
|
||||||
require 'rubygems'
|
|
||||||
require 'bundler/setup'
|
|
||||||
|
|
||||||
load Gem.bin_path('capistrano', 'capify')
|
|
|
@ -1,48 +0,0 @@
|
||||||
#
|
|
||||||
# Capistrano 3 deployment configuration
|
|
||||||
#
|
|
||||||
# http://www.capistranorb.com/
|
|
||||||
# https://semaphoreapp.com/blog/2013/11/26/capistrano-3-upgrade-guide.html
|
|
||||||
|
|
||||||
# defaults that can be updated from the environment
|
|
||||||
set :branch, ENV["REVISION"] || ENV["BRANCH_NAME"] || "master"
|
|
||||||
|
|
||||||
# you probably want to change these
|
|
||||||
set :application, 'foodsoft' # application name (whatever you like)
|
|
||||||
set :domain, 'order.foodcoop.test' # host
|
|
||||||
set :user, 'deploy' # ssh deploy user
|
|
||||||
set :keep_releases, 10
|
|
||||||
set :repo_url, 'https://github.com/foodcoops/foodsoft.git'
|
|
||||||
set :deploy_to, "/www/apps/#{fetch :application}-#{fetch :stage}"
|
|
||||||
|
|
||||||
# more settings which are probably ok
|
|
||||||
set :log_level, :info
|
|
||||||
set :linked_files, %w{config/database.yml config/app_config.yml config/initializers/secret_token.rb config/initializers/session_store.rb}
|
|
||||||
set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}
|
|
||||||
|
|
||||||
# assuming one server for everything, with one user for deploy and one for resque
|
|
||||||
server fetch(:domain), user: fetch(:user), roles: [:web, :app, :resque, :db]
|
|
||||||
|
|
||||||
# if you use RVM, uncomment the line in Capfile, and optionally uncomment rvm settings
|
|
||||||
# set :rvm_ruby_string, :local
|
|
||||||
|
|
||||||
# task hooks
|
|
||||||
namespace :deploy do
|
|
||||||
|
|
||||||
desc 'Restart application'
|
|
||||||
task :restart do
|
|
||||||
on roles(:app), in: :sequence, wait: 5 do
|
|
||||||
# tell mod_passenger to reload the application
|
|
||||||
execute :touch, release_path.join('tmp/restart.txt')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
after :restart, 'resque:restart'
|
|
||||||
|
|
||||||
after :finishing, 'deploy:cleanup'
|
|
||||||
|
|
||||||
# see lib/capistrano/tasks/plugins.cap
|
|
||||||
#before 'bundler:install', 'enable_plugins:auto'
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
|
@ -58,40 +58,3 @@ In practice, you'd probably want to use docker-compose. If you know Docker well
|
||||||
you'll have no problem to set this up. For inspiration, look at the
|
you'll have no problem to set this up. For inspiration, look at the
|
||||||
[foodcoops.net production setup](https://github.com/foodcoops/foodcoops.net).
|
[foodcoops.net production setup](https://github.com/foodcoops/foodcoops.net).
|
||||||
|
|
||||||
|
|
||||||
## Capistrano
|
|
||||||
|
|
||||||
### Setup
|
|
||||||
|
|
||||||
1. Initialise your [Capistrano](http://capistranorb.com/) setup
|
|
||||||
|
|
||||||
bundle exec cap install
|
|
||||||
sed -i 's|^# \(require.*rails.*\)|\1|' Capfile
|
|
||||||
cp config/deploy.rb.SAMPLE config/deploy.rb
|
|
||||||
|
|
||||||
When you're using [RVM](http://rvm.io/) on the server you may want to
|
|
||||||
uncomment the corresponding line in `Capfile`.
|
|
||||||
|
|
||||||
2. Adapt your configuration in `config/deploy.rb` and `config/deploy/*.rb`
|
|
||||||
|
|
||||||
|
|
||||||
### Deploy
|
|
||||||
|
|
||||||
On your first deploy you should run (choose either staging or production)
|
|
||||||
|
|
||||||
bundle exec cap staging deploy:check
|
|
||||||
|
|
||||||
This will fail, which is ok, because there is no configuration yet. On your
|
|
||||||
server, there is a directory `shared/config` for each installation, which
|
|
||||||
contains the configuration. Create `database.yml`, `app_config.yml` and
|
|
||||||
`initializers/secret_token.rb` and try again.
|
|
||||||
(See `lib/capistrano/tasks/deploy_initial.cap` for a way to automate this.)
|
|
||||||
|
|
||||||
Deploy to staging
|
|
||||||
|
|
||||||
bundle exec cap staging deploy
|
|
||||||
|
|
||||||
Deploy to production
|
|
||||||
|
|
||||||
bundle exec cap production deploy
|
|
||||||
|
|
||||||
|
|
|
@ -1,113 +0,0 @@
|
||||||
# Capistrano tasks for the initial setup
|
|
||||||
|
|
||||||
namespace :deploy do
|
|
||||||
|
|
||||||
desc 'Creates and initialises a new foodsoft instance'
|
|
||||||
task :initial do
|
|
||||||
before 'deploy:check:linked_files', 'deploy:initial:touch_shared'
|
|
||||||
before 'deploy:symlink:linked_files', 'deploy:initial:copy_shared'
|
|
||||||
before 'deploy:updated', 'deploy:initial:secret_token'
|
|
||||||
before 'deploy:updated', 'deploy:initial:app_config'
|
|
||||||
before 'deploy:updated', 'deploy:initial:db:config'
|
|
||||||
before 'deploy:updated', 'deploy:initial:db:create'
|
|
||||||
before 'deploy:migrate', 'deploy:initial:db:load'
|
|
||||||
end
|
|
||||||
after :initial, :deploy
|
|
||||||
|
|
||||||
|
|
||||||
namespace :initial do
|
|
||||||
|
|
||||||
namespace :db do
|
|
||||||
|
|
||||||
desc 'Generate new database.yml with random password'
|
|
||||||
task :config => ['deploy:set_rails_env'] do
|
|
||||||
require 'securerandom'
|
|
||||||
on roles(:app), in: :groups do
|
|
||||||
db_name = fetch(:db_user) || fetch(:application)
|
|
||||||
db_passwd = SecureRandom.urlsafe_base64(24).to_s
|
|
||||||
db_yaml = {
|
|
||||||
fetch(:rails_env).to_s => {
|
|
||||||
'adapter' => 'mysql2',
|
|
||||||
'encoding' => 'utf8',
|
|
||||||
'database' => db_name,
|
|
||||||
'username' => db_name,
|
|
||||||
'password' => db_passwd,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
execute :mkdir, '-p', shared_path.join("config")
|
|
||||||
upload! StringIO.new(db_yaml.to_yaml), shared_path.join("config/database.yml")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# assumes mysql access setup (~/.my.cnf), with permissions
|
|
||||||
desc 'Create database new database'
|
|
||||||
task :create => ['deploy:set_rails_env'] do
|
|
||||||
on roles(:app), in: :sequence do
|
|
||||||
config = capture :cat, shared_path.join("config/database.yml")
|
|
||||||
config = YAML.load(config)[fetch(:rails_env).to_s]
|
|
||||||
# http://www.grahambrooks.com/blog/create-mysql-database-with-capistrano/
|
|
||||||
execute :mysql, "--execute='CREATE DATABASE IF NOT EXISTS `#{config['database']}`';"
|
|
||||||
execute :mysql, "--execute='GRANT ALL ON `#{config['database']}`.* TO \"#{config['username']}\" IDENTIFIED BY \"#{config['password']}\";'"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
desc 'Load database schema'
|
|
||||||
task :load => ['deploy:set_rails_env'] do
|
|
||||||
on roles(:app), in: :groups do
|
|
||||||
# workaround nonexistent release_path on first deploy
|
|
||||||
path = releases_path.join(capture(:ls, releases_path).split("\n").sort.last)
|
|
||||||
within path do
|
|
||||||
with rails_env: fetch(:rails_env) do
|
|
||||||
execute :rake, 'db:schema:load'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
desc 'Writes a new secret token'
|
|
||||||
task :secret_token do
|
|
||||||
require 'securerandom'
|
|
||||||
on roles(:app), in: :groups do
|
|
||||||
secret = SecureRandom.hex(64)
|
|
||||||
text = "Foodsoft::Application.config.secret_key_base = \"#{secret}\""
|
|
||||||
execute :mkdir, '-p', shared_path.join("config/initializers")
|
|
||||||
upload! StringIO.new(text), shared_path.join("config/initializers/secret_token.rb")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
desc 'Creates a default app_config.yml'
|
|
||||||
task :app_config do
|
|
||||||
on roles(:app), in: :groups do
|
|
||||||
execute :mkdir, '-p', shared_path.join("config")
|
|
||||||
# workaround nonexistent release_path on first deploy
|
|
||||||
path = releases_path.join(capture(:ls, releases_path).split("\n").sort.last)
|
|
||||||
execute :cp, path.join("config/app_config.yml.SAMPLE"), shared_path.join("config/app_config.yml")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
desc 'Touches the shared configuration files (for initial deploy)'
|
|
||||||
task :touch_shared do
|
|
||||||
on roles(:app), in: :groups do
|
|
||||||
fetch(:linked_files).each do |file|
|
|
||||||
execute :touch, shared_path.join(file)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
desc 'Copies existing shared configuration files'
|
|
||||||
task :copy_shared do
|
|
||||||
on roles(:app), in: :groups do
|
|
||||||
# workaround nonexistent release_path on first deploy
|
|
||||||
path = releases_path.join(capture(:ls, releases_path).split("\n").sort.last)
|
|
||||||
fetch(:linked_files).each do |file|
|
|
||||||
# TODO copy only if existing destination has zero length
|
|
||||||
execute "if [ -e '#{path.join(file)}' ]; then cp '#{path.join(file)}' '#{shared_path.join(file)}'; fi"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
# Capistrano tasks for enabling/disabling foodsoft plugins in the Gemfile
|
|
||||||
#
|
|
||||||
# Please note that the foodsoft plugins should be present already in the
|
|
||||||
# Gemfile, either commented out or not.
|
|
||||||
#
|
|
||||||
# To automatically enable the desired plugins on deployment, create the
|
|
||||||
# file `config/plugins.yml` in the shared directory, containing the
|
|
||||||
# key `enabled` with a list of enabled plugin names (without foodsoft_).
|
|
||||||
# Then add to your `config/deploy.rb`:
|
|
||||||
# before 'bundler:install', 'enable_plugins:auto'
|
|
||||||
|
|
||||||
desc 'Enable only the foodsoft plugins, cap enable_plugins PLUGINS=wiki,messages'
|
|
||||||
task :enable_plugins do
|
|
||||||
on roles(:app), in: :groups do
|
|
||||||
unless env['PLUGINS'].nil?
|
|
||||||
enable_foodsoft_plugins(ENV['PLUGINS'].split(/,\s*/))
|
|
||||||
else
|
|
||||||
raise 'You need to set the PLUGINS environment variable to enable specific plugins'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
namespace :enable_plugins do
|
|
||||||
|
|
||||||
desc 'Enable the foodsoft plugins specified in shared/config/plugins.yml, if it exists (key `enabled`).'
|
|
||||||
task 'auto' do
|
|
||||||
on roles(:app), in: :groups do
|
|
||||||
text = capture :cat, shared_path.join('config/plugins.yml'), '||true'
|
|
||||||
if text
|
|
||||||
plugins = YAML.load(text)
|
|
||||||
enable_foodsoft_plugins(plugins['enabled']) if plugins && !plugins['enabled'].nil?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
# need to run in role
|
|
||||||
def enable_foodsoft_plugins(plugins)
|
|
||||||
gemfile = capture :cat, release_path.join('Gemfile')
|
|
||||||
gemfile.gsub! /^\s*(#)?\s*(gem\s+(['"])foodsoft_(.*?)\3)/ do |c|
|
|
||||||
(plugins.index($4) ? '' : '#') + $2
|
|
||||||
end
|
|
||||||
upload! StringIO.new(gemfile), release_path.join('Gemfile')
|
|
||||||
# since we updated the Gemfile, we need to run bundler in non-deployment mode
|
|
||||||
new_bundle_flags = fetch(:bundle_flags).split(/\s+/)
|
|
||||||
new_bundle_flags.reject! {|o| o=='--deployment'}
|
|
||||||
new_bundle_flags << '--no-deployment'
|
|
||||||
set :bundle_flags, new_bundle_flags.join(' ')
|
|
||||||
end
|
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
|
|
||||||
# capistrano-resque could be used, but it does not support running resque as another user.
|
|
||||||
# If you want to run resque as another user, setup sudo to allow running commands as that user:
|
|
||||||
# deploy ALL=(foodsoft_user) NOPASSWD: ALL
|
|
||||||
# and set `:run_user` to the foodsoft user.
|
|
||||||
namespace :resque do
|
|
||||||
|
|
||||||
%w{start stop restart}.each do |action|
|
|
||||||
desc "#{action.capitalize} Resque workers"
|
|
||||||
task action => ['deploy:set_rails_env'] do
|
|
||||||
on roles(:resque), in: :groups do
|
|
||||||
|
|
||||||
SSHKit.config.command_map[:rake_as_run_user] =
|
|
||||||
unless fetch(:run_user).nil? || fetch(:run_user) == fetch(:user)
|
|
||||||
"sudo -u '#{fetch(:run_user)}' "
|
|
||||||
else
|
|
||||||
''
|
|
||||||
end + SSHKit.config.command_map[:rake]
|
|
||||||
|
|
||||||
within current_path do
|
|
||||||
execute :rake_as_run_user, "'resque:#{action}_workers'", "RAILS_ENV='#{fetch(:rails_env)}'"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
Loading…
Reference in a new issue