diff --git a/.gitignore b/.gitignore index 7d365cc..7d1d517 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ # ignore editor temp files *.swp *~ +.DS_Store diff --git a/production/README.md b/production/README.md index 0df5fc2..b360327 100644 --- a/production/README.md +++ b/production/README.md @@ -1,5 +1,119 @@ -Production environment -====================== +Deploying and initializing TaxonWorks +================================= + +Assumptions/prerequisites +------------------------- +* You have two machines, "deploy" and "server", in this example both are Ubuntu 14.04(+) LTS (not 14.10) +* You are resonably capable with a command line environment* +You have "provisioned" production with the pertinent shell script +* Your "deploy" machine has Ruby, bundler and rubygems installed +* You can ssh without password to your "server" +* We are using [Capistrano.](https://github.com/capistrano/capistrano) to deploy TaxonWorks +* Instructions containing all cap values are variables that you must replace (e.g. USERNAME) +* Configure "Server" first, "Deploy" second + +On "Server" +----------- + +Thanks to [Rob Mclarty's blog post](http://robmclarty.com/blog/how-to-deploy-a-rails-4-app-with-git-and-capistrano) for the general strategy. + +Ensure that you can login via ssh with the user that will deploy taxonworks, you can find many places to describe howto set this up. + +#### Add a group +``` +sudo groupadd deployers +sudo usermod -a -G deployers USERNAME +``` + +``` +sudo mkdir /var/www +sudo mkdir /var/www/taxonworks +sudo mkdir /var/www/taxonworks/shared +sudo mkdir var/www/taxonworks/shared/config/ +sudo chown -R USERNAME:deployers /var/www +sudo chmod -R g+w /var/www +``` + +####Configure postgres +``` +sudo -u postgres psql postgres + +alter user postgres with password 'PASSWORD1'; +create role taxonworks_production login createdb superuser; +alter user taxonworks_production with password 'PASSWORD2'; +``` + +Configure nginx to point to your passenger ruby, in ```/etc/nginx/nginx.conf``` add/edit the line (change USERNAME!): + +``` + passenger_ruby /home/USERNAME/.rbenv/shims/ruby; +``` + +Set permissions for nginx + +``` +sudo chmod g+x,o+x /var/www/taxonworks/current/config.ru +sudo chmod g+x,o+x /var/www/taxonworks +sudo chmod g+x,o+x /var/www +sudo chmod g+x,o+x /var/www/taxonworks/current/public +``` + +Create nginx site + +* Add an an available site to /etc/nginx/sites-enabled (see example here) +* Within /etc/nginx/sites-avaiable create a symbolic link + +``` +sudo ln -ls ../sites-available/taxonworks taxonworks +``` + + +On "Deploy" +----------- + +#### Clone the master branch of TaxonWorks. +``` + git clone https://github.com/SpeciesFileGroup/taxonworks.git +``` + +#### Install capistrano +``` + gem install capistrano +``` + +#### Create a new branch, inside your taxonworks folder: +``` + git branch capistrano +``` + +#### Checkout that branch +``` + git checkout capistrano +``` + +#### Run capistrano to setup "capify" taxonworks +``` + bundle exec cap install +``` +This creates a ```config/deploy``` directory, and some sample files. + +#### Configure the capistrano files +You can copy the examples from this repository: +* config/deploy.rb +* config/capistrano/production.rb + +Minimally, modify ```production.rb``` to point to your machine, and to use your USERNAME. + +#### Copy config files +``` +scp config/database.yml USERNAME@SERVERNAME:/var/www/taxonworks/shared/config/database.yml +scp config/application_settings.yml USERNAME@SERVERNAME:/var/www/taxonworks/shared/config/application_settings.yml +``` + +#### Deploy +Inside your taxonworks directory, with the capistrano branch checkout out +``` +cap production deploy +``` -Stub diff --git a/production/deploy/capistrano/deploy.rb b/production/deploy/capistrano/deploy.rb new file mode 100644 index 0000000..5baa222 --- /dev/null +++ b/production/deploy/capistrano/deploy.rb @@ -0,0 +1,92 @@ + +lock '3.4.0' + +# config/deploy.rb +# set :rbenv_path, '~/.rbenv' +#set :rbenv_type, :user + +set :rbenv_ruby, File.read('.ruby-version').strip + +# set :rbenv_prefix, "RBENV_ROOT=#{fetch(:rbenv_path)} RBENV_VERSION=#{fetch(:rbenv_ruby)} /usr/bin/rbenv exec" +# set :rbenv_map_bins, %w{rake gem bundle ruby rails} +# set :rbenv_roles, :all + +set :application, 'taxonworks' +set :repo_url, 'git@github.com:SpeciesFileGroup/taxonworks.git' + +# Default branch is :master +# ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp } + +# Default deploy_to directory is /var/www/my_app +# set :deploy_to, Settings.capistrano_settings[:deploy_to] # '/var/www/my_app' +# do this in individual environments! + +# Default value for :scm is :git +# set :scm, :git + +# 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, %w{config/database.yml config/application_settings.yml config/secrets.yml} + +# Default value for linked_dirs is [] +set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system public/images/tmp} + +# 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 + +namespace :deploy do + + desc 'Restart application' + task :restart do + on roles(:app), in: :sequence, wait: 5 do + # Your restart mechanism here, for example: + # run "touch #{current_release}/tmp/restart.txt" + execute :touch, release_path.join('tmp/restart.txt') + end + end + + after :publishing, :restart + + after :restart, :clear_cache do + on roles(:web), in: :groups, limit: 3, wait: 10 do + # Here we can do anything such as: + # within release_path do + # execute :rake, 'cache:clear' + # end + end + end +end + +namespace :setup do + + desc "Check that we can access everything" + task :check_write_permissions do + on roles(:all) do |host| + if test("[ -w #{fetch(:deploy_to)} ]") + info "#{fetch(:deploy_to)} is writable on #{host}" + else + error "#{fetch(:deploy_to)} is not writable on #{host}" + end + end + end + + desc "Upload database.yml file." + task :upload_yml do + on roles(:app) do + execute "mkdir -p #{shared_path}/config" + upload! StringIO.new(File.read("config/database.yml")), "#{shared_path}/config/database.yml" + end + end + +end diff --git a/production/deploy/capistrano/deploy/production.rb b/production/deploy/capistrano/deploy/production.rb new file mode 100644 index 0000000..69dbe41 --- /dev/null +++ b/production/deploy/capistrano/deploy/production.rb @@ -0,0 +1,51 @@ +set :stage, :production + +set :deploy_to, '/var/www/taxonworks' + +set :user, fetch(:remote_user) +# Simple Role Syntax +# ================== +# Supports bulk-adding hosts to roles, the primary +# server in each group is considered to be the first +# unless any hosts have the primary property set. +# Don't declare `role :all`, it's a meta role +# +#Originally uncommented: +# role :app, %w{deploy@example.com} +# role :web, %w{deploy@example.com} +# role :db, %w{deploy@example.com} + +# Extended Server Syntax +# ====================== +# This can be used to drop a more detailed server +# definition into the server list. The second argument +# something that quacks like a hash can be used to set +# extended properties on the server. +# + +# EDIT THIS LINE: + +server 'your.server.org', roles: %w{app web db}, user: 'username_from_production', primary: true + +set :use_sudo, false +# you can set custom ssh options +# it's possible to pass any option but you need to keep in mind that net/ssh understand limited list of options +# you can see them in [net/ssh documentation](http://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start) +# set it globally +# set :ssh_options, { +# keys: %w(/home/rlisowski/.ssh/id_rsa), +# forward_agent: false, +# auth_methods: %w(password) +# } +# and/or per server +# 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' +# } +# setting per server overrides global ssh_options diff --git a/production/server/etc/nginx/sites-available/taxonworks b/production/server/etc/nginx/sites-available/taxonworks new file mode 100644 index 0000000..ffe9176 --- /dev/null +++ b/production/server/etc/nginx/sites-available/taxonworks @@ -0,0 +1,7 @@ +server { + listen 80 default_server; + server_name your.server.name.or.ip; + passenger_enabled on; + passenger_app_env production; + root /var/www/taxonworks/current/public; +}