-
-
Save jesperronn/ebc945796138163b216d to your computer and use it in GitHub Desktop.
Sample cap setup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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/chruby' | |
require 'capistrano/bundler' | |
# require 'capistrano/rails/assets' | |
require 'capistrano/rails/migrations' | |
require 'capistrano/git-submodule-strategy' | |
require 'capistrano/puma' | |
require 'capistrano/puma/workers' # if you want to control the workers (in cluster mode) | |
require 'capistrano/puma/jungle' # if you need the jungle tasks | |
# require 'capistrano/puma/monit' # if you need the monit tasks | |
require 'capistrano/puma/nginx' # if you want to upload a nginx site template | |
# Load custom tasks from `lib/capistrano/tasks` if you have any defined | |
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# config valid only for current version of Capistrano | |
lock '3.4.0' | |
set :application, 'xxx' | |
set :repo_url, '[email protected]:troelskn/xxx.git' | |
set :ssh_options, { | |
user: "ubuntu", | |
forward_agent: true, | |
keys: "~/.ssh/aws-xxx.pem" | |
} | |
# To see verbose output from bundler | |
# set :bundle_flags, '--deployment' | |
# Default branch is :master | |
# ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp | |
# Default deploy_to directory is /var/www/my_app_name | |
# set :deploy_to, '/var/www/my_app_name' | |
# Default value for :scm is :git | |
# set :scm, :git | |
set :git_strategy, Capistrano::Git::SubmoduleStrategy | |
# Default value for :format is :pretty | |
# set :format, :pretty | |
# Default value for :log_level is :debug | |
# set :log_level, :debug | |
# Default value for :pty is false | |
# set :pty, true | |
# Default value for :linked_files is [] | |
# set :linked_files, fetch(:linked_files, []).push('config/database.yml', 'config/secrets.yml') | |
# Default value for linked_dirs is [] | |
# set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system') | |
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system') | |
# Default value for default_env is {} | |
# set :default_env, { path: "/opt/ruby/bin:$PATH" } | |
# Default value for keep_releases is 5 | |
# set :keep_releases, 5 | |
task :setup do ; end | |
after 'deploy:finished', 'puma:jungle:restart' | |
before 'setup', 'setup:apt:upgrade' | |
before 'setup', 'setup:apt:install' | |
before 'setup', 'setup:ruby' | |
before 'setup', 'setup:nginx:install' | |
before 'setup', 'puma:jungle:install' | |
before 'setup', 'puma:jungle:add' | |
before 'setup', 'puma:nginx_config' | |
after 'puma:nginx_config', :puma_post_setup do | |
on roles(fetch(:puma_nginx)) do | |
execute "mkdir -p #{shared_path}/tmp/pids" | |
execute "mkdir -p #{shared_path}/tmp/sockets" | |
execute "mkdir -p #{shared_path}/log" | |
end | |
invoke 'setup:nginx:restart' | |
end | |
before 'setup', 'git:check' | |
set_if_empty :setup_roles, :app | |
set :apt_packages, %w(build-essential openssl libmysqlclient-dev libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev autoconf libc6-dev libncurses5-dev automake libtool bison nodejs subversion) | |
set :puma_user, -> { fetch(:ssh_options)[:user] } | |
set :puma_nginx, -> { fetch(:setup_roles) } | |
set :nginx_server_name, -> { fetch(:domain) } | |
set :nginx_cache_path, "/var/cache/nginx" | |
# TODO Need a letsencrypt task first | |
# set :nginx_use_ssl, true | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
source 'https://rubygems.org' | |
gem 'rails', '>= 5.0.0.beta1.1', '< 5.1' | |
gem 'mysql2', '>= 0.3.18', '< 0.5' | |
gem 'puma' | |
group :development do | |
gem 'spring' | |
gem 'capistrano' | |
gem 'capistrano-git-submodule-strategy' | |
gem 'capistrano-rails' | |
gem 'capistrano3-puma' | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'setup_helpers' | |
namespace :setup do | |
# TODO: Not currently used, but probably should be | |
namespace :user do | |
desc "Create deploy user" | |
task :create do | |
on roles(fetch(:setup_roles)) do | |
name = 'deploy' | |
deploy_keys = Dir.glob("config/deploy/keys/*.pub") | |
groups = ['www-data', 'sudo'].join(",") | |
unless test :sudo, "id -u #{name} > /dev/null" | |
execute :sudo, "useradd --create-home --shell /bin/bash --user-group --groups #{groups} #{name}" | |
end | |
if deploy_keys.any? | |
sudo "mkdir -p /home/#{name}/.ssh" | |
sudo "touch /home/#{name}/.ssh/authorized_keys" | |
sudo "chmod 0700 /home/#{name}/.ssh" | |
sudo "chown -R #{name}:#{name} /home/#{name}/.ssh" | |
sudo "chmod 0700 /home/#{name}/.ssh/authorized_keys" | |
path = "/home/#{name}/.ssh/authorized_keys" | |
[deploy_keys].flatten.each do |keyname| | |
key = File.open(keyname).read.strip | |
execute "echo #{key.shellescape}|sudo tee -a #{path}" unless file_contains?(path, key, sudo: true) | |
end | |
end | |
# passwdless sudo | |
execute :echo, "#{name} ALL=(ALL) NOPASSWD:ALL\n".shellescape, "|sudo tee /etc/sudoers.d/90-#{name}-user" | |
end | |
end | |
end | |
namespace :apt do | |
desc "Updates apt index" | |
task :update do | |
on roles(fetch(:setup_roles)) do | |
sudo "apt-get update -y -qq" | |
end | |
end | |
desc "Upgrades apt-installed packages" | |
task upgrade: :update do | |
on roles(fetch(:setup_roles)) do | |
noninteractive = "env DEBCONF_TERSE='yes' DEBIAN_PRIORITY='critical' DEBIAN_FRONTEND=noninteractive" | |
sudo "#{noninteractive} apt-get upgrade --assume-yes --force-yes" | |
end | |
end | |
desc "Installs system level packages with apt" | |
task install: :update do | |
on roles(fetch(:setup_roles)) do | |
apt_install fetch(:apt_packages) | |
end | |
end # task :install_apt | |
end # namespace :apt | |
desc "Installs ruby from source" | |
task :ruby do | |
on roles(fetch(:setup_roles)) do | |
version = fetch(:ruby_version, "2.3.0") | |
major_version = version.gsub(/(\d+\.\d+)\.\d+/, "\\1") | |
unless capture("which ruby && ruby -v ; echo ''").match(version) | |
within "/usr/src/" do | |
sudo :wget, "https://cache.ruby-lang.org/pub/ruby/#{major_version}/ruby-#{version}.tar.gz" | |
sudo :tar, "xvfz", "ruby-#{version}.tar.gz" | |
within "ruby-#{version}" do | |
sudo "./configure" | |
sudo :make | |
sudo :make, "install" | |
end | |
end | |
sudo "gem update --system" | |
sudo "gem install bundler" | |
end | |
end | |
end # task :ruby | |
namespace :nginx do | |
desc "Installs nginx server" | |
task :install do | |
on roles(fetch(:setup_roles)) do | |
apt_install "nginx" | |
["/var/www", fetch(:nginx_cache_path, "/var/cache/nginx")].each do |path| | |
unless test "[ -d #{path.shellescape} ]" | |
sudo :mkdir, "-p #{path.shellescape}" | |
sudo :chown, "www-data:www-data #{path.shellescape}" | |
end | |
end | |
if test "[ -L '/etc/nginx/sites-enabled/default' ]" | |
sudo :rm, "/etc/nginx/sites-enabled/default" | |
end | |
end | |
end # task :install | |
desc "Restarts nginx service" | |
task :restart do | |
on roles(fetch(:setup_roles)) do | |
# TODO: This fails silently - verify | |
sudo "service nginx restart" | |
end | |
end | |
end # namespace :nginx | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module SetupHelpers | |
def template(from, to) | |
[ | |
"config/deploy/assets/#{from}.#{fetch(:stage)}.erb", | |
"config/deploy/assets/#{from}.erb", | |
].each do |path| | |
if File.file?(path) | |
erb = File.read(path) | |
upload! StringIO.new(ERB.new(erb).result(binding)), to | |
break | |
end | |
end | |
end | |
def file_contains?(path, text, options = {}) | |
options = {:mode => :text}.merge(options) | |
if options[:mode] == :text | |
command = Array(text.strip.split("\n")).flatten.map {|line| "grep --fixed-strings #{line.shellescape} #{path.shellescape}" }.join(" && ") | |
elsif options[:mode] == :perl | |
command = [:grep, "--perl-regexp #{text.shellescape} #{path.shellescape}"] | |
else | |
command = [:grep, "grep --basic-regexp #{text.shellescape} #{path.shellescape}"] | |
end | |
if options[:sudo] | |
test(:sudo, *command) | |
else | |
test(*command) | |
end | |
end | |
def apt_install(packages) | |
[packages].flatten.each do |package_name| | |
unless test(:sudo, "dpkg --status #{package_name.to_s.shellescape} | grep 'ok installed'") | |
noninteractive = "env DEBCONF_TERSE='yes' DEBIAN_PRIORITY='critical' DEBIAN_FRONTEND=noninteractive" | |
execute :sudo, "#{noninteractive} apt-get --assume-yes --force-yes --show-upgraded --quiet install #{package_name.to_s.shellescape}" | |
end | |
end | |
end | |
def with_verbosity(verbosity, &block) | |
old_output_verbosity = SSHKit.config.output_verbosity | |
SSHKit.config.output_verbosity = verbosity | |
yield | |
ensure | |
SSHKit.config.output_verbosity = old_output_verbosity if old_output_verbosity | |
end | |
end | |
SSHKit::Backend::Abstract.send :include, SetupHelpers |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment