Browse Source

Setup deployment

pull/3/head
Angel Aviel Domaoan 4 years ago
parent
commit
ad9d7cd1ed
  1. 38
      Capfile
  2. 20
      Gemfile
  3. 72
      Gemfile.lock
  4. 130
      config/deploy.rb
  5. 64
      config/deploy/production.rb
  6. 64
      config/deploy/staging.rb
  7. 37
      docker-compose.production.yml

38
Capfile

@ -0,0 +1,38 @@
# Load DSL and set up stages
require "capistrano/setup"
# Include default deployment tasks
require "capistrano/deploy"
# Include tasks from other gems included in your Gemfile
#
# For documentation on these, see for example:
#
# https://github.com/capistrano/rvm
# https://github.com/capistrano/rbenv
# https://github.com/capistrano/chruby
# https://github.com/capistrano/bundler
# https://github.com/capistrano/rails
# https://github.com/capistrano/passenger
#
# require 'capistrano/rvm'
# require 'capistrano/rbenv'
# require 'capistrano/bundler'
# require 'capistrano/chruby'
# require 'capistrano/rails/assets'
# require 'capistrano/rails/migrations'
# require 'capistrano/passenger'
require "capistrano/docker"
require "capistrano/docker/assets"
require "capistrano/docker/migration"
require "capistrano/safe_deploy_to"
require "capistrano/ssh_doctor"
require "capistrano/file-permissions"
require "capistrano/sentry"
require "figaro"
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }

20
Gemfile

@ -99,3 +99,23 @@ group :rubocop do
end
gem "sentry-ruby", "~> 4.8"
# Remote Development
group :development do
gem "capistrano", "~> 3.6.0"
gem "capistrano-bundler", require: false
gem "capistrano-docker", github: "netguru/capistrano-docker", require: false
gem "capistrano-file-permissions", require: false
gem "capistrano-nc", require: false
gem "capistrano-pending", require: false
gem "capistrano-rails", require: false
gem "capistrano-rvm", require: false
gem "capistrano-safe-deploy-to", require: false
gem "capistrano-sidekiq", require: false
gem "capistrano-ssh-doctor", require: false
gem "capistrano3-puma", require: false
gem "capistrano-sentry", require: false
gem "bcrypt_pbkdf", "~> 1.1"
gem "ed25519", "~> 1.3"
end

72
Gemfile.lock

@ -1,3 +1,10 @@
GIT
remote: https://github.com/netguru/capistrano-docker.git
revision: 873aa5fdce66c6962dad555a914d31d4fdc77f5c
specs:
capistrano-docker (0.2.11)
capistrano (>= 3.3)
GIT
remote: https://github.com/state-machines/state_machines.git
revision: 6a9bb977e0b599eef49fc1fea31b12af113905da
@ -70,10 +77,13 @@ GEM
activerecord (>= 4.2)
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
airbrussh (1.4.0)
sshkit (>= 1.6.1, != 1.7.0)
ancestry (4.1.0)
activerecord (>= 5.2.6)
ast (2.4.2)
bcrypt (3.1.16)
bcrypt_pbkdf (1.1.0)
better_errors (2.9.1)
coderay (>= 1.0.0)
erubi (>= 1.0.0)
@ -89,6 +99,40 @@ GEM
rails (>= 5.2)
thread-local (>= 1.1.0)
cancancan (1.17.0)
capistrano (3.6.1)
airbrussh (>= 1.0.0)
capistrano-harrow
i18n
rake (>= 10.0.0)
sshkit (>= 1.9.0)
capistrano-bundler (2.0.1)
capistrano (~> 3.1)
capistrano-file-permissions (1.0.0)
capistrano (~> 3.0)
capistrano-harrow (0.5.3)
capistrano-nc (0.2.0)
capistrano (~> 3.0)
terminal-notifier (~> 2.0)
capistrano-pending (0.2.0)
capistrano (>= 3.2.0)
capistrano-rails (1.6.1)
capistrano (~> 3.1)
capistrano-bundler (>= 1.1, < 3)
capistrano-rvm (0.1.2)
capistrano (~> 3.0)
sshkit (~> 1.2)
capistrano-safe-deploy-to (1.1.1)
capistrano (>= 3.0)
capistrano-sentry (0.4.2)
capistrano (~> 3.1)
capistrano-sidekiq (0.10.0)
capistrano
sidekiq (>= 3.4)
capistrano-ssh-doctor (1.0.0)
capistrano (>= 3.1)
capistrano3-puma (1.2.1)
capistrano (~> 3.0)
puma (>= 2.6)
capybara (3.36.0)
addressable
matrix
@ -101,6 +145,7 @@ GEM
childprocess (4.1.0)
coderay (1.1.3)
concurrent-ruby (1.1.9)
connection_pool (2.2.5)
crass (1.0.6)
debug_inspector (1.1.0)
devise (4.8.1)
@ -109,6 +154,7 @@ GEM
railties (>= 4.1.0)
responders
warden (~> 1.2.3)
ed25519 (1.3.0)
erubi (1.10.0)
faraday (2.0.1)
faraday-net_http (~> 2.0)
@ -151,6 +197,9 @@ GEM
mini_mime (1.1.2)
minitest (5.15.0)
msgpack (1.4.2)
net-scp (3.0.0)
net-ssh (>= 2.6.5, < 7.0.0)
net-ssh (6.1.0)
nio4r (2.5.8)
nokogiri (1.13.0-x86_64-darwin)
racc (~> 1.4)
@ -272,6 +321,10 @@ GEM
sentry-ruby-core (4.8.1)
concurrent-ruby
faraday
sidekiq (6.4.0)
connection_pool (>= 2.2.2)
rack (~> 2.0)
redis (>= 4.2.0)
spring (4.0.0)
sprockets (4.0.2)
concurrent-ruby (~> 1.0)
@ -280,6 +333,9 @@ GEM
actionpack (>= 5.2)
activesupport (>= 5.2)
sprockets (>= 3.0.0)
sshkit (1.21.2)
net-scp (>= 1.1.2)
net-ssh (>= 2.8.0)
state_machines-activemodel (0.8.0)
activemodel (>= 5.1)
state_machines (>= 0.5.0)
@ -306,6 +362,7 @@ GEM
sunspot (= 2.5.0)
sunspot_solr (2.5.0)
sunspot_submodel_index (0.0.5)
terminal-notifier (2.0.0)
thor (1.2.1)
thread-local (1.1.0)
tilt (2.0.10)
@ -348,13 +405,28 @@ PLATFORMS
DEPENDENCIES
acts_as_list
ancestry
bcrypt_pbkdf (~> 1.1)
better_errors
binding_of_caller
bootsnap (>= 1.4.4)
byebug
cancancan (~> 1.17.0)
capistrano (~> 3.6.0)
capistrano-bundler
capistrano-docker!
capistrano-file-permissions
capistrano-nc
capistrano-pending
capistrano-rails
capistrano-rvm
capistrano-safe-deploy-to
capistrano-sentry
capistrano-sidekiq
capistrano-ssh-doctor
capistrano3-puma
capybara (>= 3.26)
devise (>= 4.7.1)
ed25519 (~> 1.3)
figaro
foreman
jbuilder (~> 2.7)

130
config/deploy.rb

@ -0,0 +1,130 @@
# config valid only for current version of Capistrano
lock "3.6.1"
set :application, "cdao-pjet"
set :repo_url, "[email protected]:CDAsia/cdao-pjet.git"
set :branch, "master"
set :deploy_to, -> { "/var/www/#{fetch(:application)}" }
# Default value for :linked_files is []
set :docker_copy_data, fetch(:linked_files, []).push(".env",
"config/application.yml")
# Default value for keep_releases is 5
set :keep_releases, 5
set :log_level, :info
set :bundle_flags, "--deployment --quiet"
set :docker_role, :web
set :docker_compose, true
set :docker_compose_up_services, "--remove-orphans --scale web=3 load_balancer"
set :docker_compose_project_name, -> { fetch(:application) }
set :docker_assets_precompile_command, -> {
["bundle exec rake assets:precompile",
"bundle exec rake assets:non_digested",
"bundle exec rake assets:clean"].join(" && ")
}
set :docker_migrate_command, -> { "bundle exec rake db:migrate" }
set :docker_compose_path, -> { release_path.join(fetch(:docker_compose_file)) }
namespace :deploy do
desc "Fix repo"
task :set_origin_url do
on roles(:all) do
if File.directory?(deploy_path.join("repo"))
execute "cd #{fetch(:deploy_to)}/repo && git remote set-url origin #{fetch(:repo_url)}"
end
end
end
desc "Load ENV on figaro"
before :starting, :set_figaro_env do
run_locally do
opts = {
environment: fetch(:rack_env, fetch(:rails_env, "production")),
path: "config/application.yml"
}
Figaro.application = Figaro::Application.new(opts)
Figaro.load
end
end
end
namespace :docker do
namespace :rails do
def docker_compose_execute(exec)
cmd = ["run --rm"] # --rm, Remove container after run
cmd.unshift("-p #{fetch(:docker_compose_project_name)}") unless fetch(:docker_compose_project_name).nil?
cmd.unshift("-f #{fetch(:docker_compose_path)}")
cmd << "web bash -c '#{exec}'"
cmd.join(" ")
end
task :bundle do
on release_roles(fetch(:docker_role)) do
within release_path do
options = []
# options << "--gemfile #{fetch(:bundle_gemfile)}" if fetch(:bundle_gemfile)
# options << "--path #{fetch(:bundle_path)}" if fetch(:bundle_path)
unless test(:'docker-compose', docker_compose_execute("bundle check #{options.join(' ')}"))
# options << "--binstubs #{fetch(:bundle_binstubs)}" if fetch(:bundle_binstubs)
# options << "--jobs #{fetch(:bundle_jobs)}" if fetch(:bundle_jobs)
# options << "--without #{fetch(:bundle_without)}" if fetch(:bundle_without)
# options << fetch(:bundle_flags).to_s if fetch(:bundle_flags)
execute :'docker-compose', docker_compose_execute("bundle install #{options.join(' ')}")
end
end
end
end
namespace :assets do
task :precompile do
on release_roles(fetch(:docker_role)) do
within release_path do
execute :'docker-compose', docker_compose_execute(fetch(:docker_assets_precompile_command))
end
end
end
end
namespace :db do
task :migrate do
on release_roles(fetch(:docker_role)) do
within release_path do
execute :'docker-compose', docker_compose_execute(fetch(:docker_migrate_command))
end
end
end
end
def _compose_option_up_services
opt = fetch(:docker_compose_up_services)
opt.nil? ? "" : opt
end
def compose_start_command
cmd = %w[up -d --remove-orphans]
cmd << _compose_option_up_services
cmd.unshift _compose_option_project_name
cmd.unshift _compose_option_compose_path
cmd.join(" ")
end
end
end
# Sentry deployment notificationt
set :sentry_api_token, ENV["SENTRY_API_TOKEN"]
set :sentry_organization, ENV["SENTRY_ORGANIZATION"]
set :sentry_project, ENV["SENTRY_PROJECT"]
before "deploy:starting", "sentry:validate_config"
after "deploy:published", "sentry:notice_deployment"
after "deploy:check:directories", "deploy:set_origin_url"
after "docker:deploy:compose:build", "docker:rails:bundle"
after "docker:rails:bundle", "docker:rails:db:migrate"
after "docker:rails:bundle", "docker:rails:assets:precompile"

64
config/deploy/production.rb

@ -0,0 +1,64 @@
# server-based syntax
# ======================
# Defines a single server with a list of roles and multiple properties.
# You can define all roles on a single server, or split them:
# server 'example.com', user: 'deploy', roles: %w{app db web}, my_property: :my_value
# server 'example.com', user: 'deploy', roles: %w{app web}, other_property: :other_value
# server 'db.example.com', user: 'deploy', roles: %w{db}
server "002-app.cdasia.com", user: "deploy", roles: %w[web app db worker]
# role-based syntax
# ==================
# Defines a role with one or multiple servers. The primary server in each
# group is considered to be the first unless any hosts have the primary
# property set. Specify the username and a domain or IP for the server.
# Don't use `:all`, it's a meta role.
# role :app, %w{[email protected]}, my_property: :my_value
# role :web, %w{[email protected] [email protected]}, other_property: :other_value
# role :db, %w{[email protected]}
# Configuration
# =============
# You can set any configuration variable like in config/deploy.rb
# These variables are then only loaded and set in this stage.
# For available Capistrano configuration variables see the documentation page.
# http://capistranorb.com/documentation/getting-started/configuration/
# Feel free to add new variables to customise your setup.
# Custom SSH Options
# ==================
# You may pass any option but keep in mind that net/ssh understands a
# limited set of options, consult the Net::SSH documentation.
# http://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start
#
# Global options
# --------------
# set :ssh_options, {
# keys: %w(/home/rlisowski/.ssh/id_rsa),
# forward_agent: false,
# auth_methods: %w(password)
# }
#
# The server-based syntax can be used to override options:
# ------------------------------------
# server 'example.com',
# user: 'user_name',
# roles: %w{web app},
# ssh_options: {
# user: 'user_name', # overrides user setting above
# keys: %w(/home/user_name/.ssh/id_rsa),
# forward_agent: false,
# auth_methods: %w(publickey password)
# # password: 'please use keys'
# }
set :rails_env, "production"
set :docker_compose_file, -> { "docker-compose.production.yml" }

64
config/deploy/staging.rb

@ -0,0 +1,64 @@
# server-based syntax
# ======================
# Defines a single server with a list of roles and multiple properties.
# You can define all roles on a single server, or split them:
# server 'example.com', user: 'deploy', roles: %w{app db web}, my_property: :my_value
# server 'example.com', user: 'deploy', roles: %w{app web}, other_property: :other_value
# server 'db.example.com', user: 'deploy', roles: %w{db}
server "002-app.cdasia.com", user: "deploy", roles: %w[web app db worker]
# role-based syntax
# ==================
# Defines a role with one or multiple servers. The primary server in each
# group is considered to be the first unless any hosts have the primary
# property set. Specify the username and a domain or IP for the server.
# Don't use `:all`, it's a meta role.
# role :app, %w{[email protected]}, my_property: :my_value
# role :web, %w{[email protected] [email protected]}, other_property: :other_value
# role :db, %w{[email protected]}
# Configuration
# =============
# You can set any configuration variable like in config/deploy.rb
# These variables are then only loaded and set in this stage.
# For available Capistrano configuration variables see the documentation page.
# http://capistranorb.com/documentation/getting-started/configuration/
# Feel free to add new variables to customise your setup.
# Custom SSH Options
# ==================
# You may pass any option but keep in mind that net/ssh understands a
# limited set of options, consult the Net::SSH documentation.
# http://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start
#
# Global options
# --------------
# set :ssh_options, {
# keys: %w(/home/rlisowski/.ssh/id_rsa),
# forward_agent: false,
# auth_methods: %w(password)
# }
#
# The server-based syntax can be used to override options:
# ------------------------------------
# server 'example.com',
# user: 'user_name',
# roles: %w{web app},
# ssh_options: {
# user: 'user_name', # overrides user setting above
# keys: %w(/home/user_name/.ssh/id_rsa),
# forward_agent: false,
# auth_methods: %w(publickey password)
# # password: 'please use keys'
# }
set :rails_env, "production"
set :docker_compose_file, -> { "docker-compose.production.yml" }

37
docker-compose.production.yml

@ -0,0 +1,37 @@
version: "2"
services:
data:
image: busybox
volumes:
- .:/var/www
- ./../../shared/bundle:/bundle
- ./../../shared/.bundle:/var/www/.bundle
- ./../../shared/public/assets:/var/www/public/assets
- ./../../shared/public/system:/var/www/public/system
- ./../../shared/storage:/var/www/storage
- ./../../shared/tmp:/var/www/tmp
- ./../../shared/tmp/pids:/var/www/tmp/pids
- ./../../shared/vendor/bundle:/var/www/vendor/bundle
- ./../../shared/node_modules:/var/www/node_modules
solr:
image: tenshiamd/solr:5-alpine
ports:
- ${SOLR_PORT}:8983
volumes:
- ./../../shared/solr:/var/lib/solr
web:
restart: ${WEB_RESTART_MODE}
image: tenshiamd/ruby:2.6-alpine
command: |
bash -c 'bash -s <<EOF
bundle check || bundle install
bundle exec rake db:migrate
bundle exec foreman start -f Procfile
EOF'
volumes_from:
- data
environment:
- RAILS_ENV=${WEB_RAILS_ENV}
- RAILS_MASTER_KEY=${WEB_RAILS_MASTER_KEY}
- RAILS_LOG_TO_STDOUT=true
- PORT=80
Loading…
Cancel
Save