64
61

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AWSはこれで大丈夫|unicorn + nginx + capistrano + slackistrano のコマンド一覧

Last updated at Posted at 2015-09-19

AWSデプロイマスターになって、Herokuで消耗する過去に訣別しよう―。

この記事は単なる一本のログです。
だけれども上から下まで通すだけでAWSにアプリをデプロイすることができます。
コマンドの途中途中で必要なファイルの記述は混ぜてあります。
ただ環境ごとにエラーが出る可能性があるので、何かあったら教えてほしいです。

それでは以下より、「Tomajax」という仮想のRailsアプリを
30分位でデプロイしてみます。あまり親切な解説はないのでご勘弁。


【注意事項】

  1. [*]が先頭にあるコマンドはローカルで実行してください
  2. コピペする際に'=begin'と'=end'は外してください
  3. EC2インスタンスを作成する際はlinuxにしてください
  4. 以下に進む前にAWSのVPCとEC2は作成しておきましょう
    参考動画:AWS講座 - VPC/EC2インスタンスの作成から接続まで
  5. デプロイが終わったらSlack通知に挑戦してみましょう
    参考動画:AWS講座 - capistranoデプロイのSlack通知設定
# connect to ec2
*[ ~ ] $: mv Downloads/tomajax.pem .ssh/
*[ ~ ] $: cd .ssh/
*[ .ssh ] $: chmod 600 tomajax.pem
*[ .ssh ] $: ssh -i tomajax.pem ec2-user@54.92.121.123

-----------------------------------------
# add user
[ec2-user|~]$ sudo adduser tomajax
[ec2-user|~]$ sudo passwd tomajax
[ec2-user|~]$ sudo visudo
[ec2-user|~]$ sudo su - tomajax

-----------------------------------------
# enable to connect as new user
*[ ~ ] $: cd .ssh/
*[ .ssh ] $: ssh-keygen -t rsa
[tomajax|~]$ mkdir .ssh
[tomajax|~]$ chmod 700 .ssh
[tomajax|~]$ cd .ssh
[tomajax|.ssh]$ touch authorized_keys
[tomajax|.ssh]$ chmod 600 authorized_keys
[tomajax|.ssh]$ sudo vi authorized_keys
[tomajax|.ssh]$ exit

-----------------------------------------
# install plugins
[tomajax|~]$ sudo yum install \
git make gcc-c++ patch \
openssl-devel \
libyaml-devel libffi-devel libicu-devel \
libxml2 libxslt libxml2-devel libxslt-devel \
zlib-devel readline-devel \
mysql mysql-server mysql-devel \
ImageMagick ImageMagick-devel \
epel-release

-----------------------------------------
# install nodejs
[tomajax|~]$ sudo yum install nodejs npm --enablerepo=epel

-----------------------------------------
# install rbenv
[tomajax|~]$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
[tomajax|~]$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
"
[tomajax|~]$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
[tomajax|~]$ source .bash_profile
[tomajax|~]$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
[tomajax|~]$ rbenv rehash

-----------------------------------------
# install ruby 2.1.3
[tomajax|~]$ rbenv install -v 2.1.3
[tomajax|~]$ rbenv global 2.1.3
[tomajax|~]$ rbenv rehash
[tomajax|~]$ ruby -v

-----------------------------------------
# add gems
*[ tomajax ] $: vi Gemfile
=begin[Gemfile]
  group :production, :staging do
    gem 'unicorn'
    gem 'capistrano',          require: false
    gem 'capistrano-rails',    require: false
    gem 'capistrano-rbenv',    require: false
    gem 'capistrano-bundler',  require: false
    gem 'capistrano3-unicorn', require: false
    gem 'slackistrano',        require: false
  end
=end
*[ tomajax ] $: bundle

-----------------------------------------
# add unicorn config file
*[ tomajax ] $: touch config/unicorn.conf.rb
*[ tomajax ] $: vi config/unicorn.conf.rb
=begin[config/unicorn.conf.rb]
  # set lets
  $worker  = 2
  $timeout = 30
  $app_dir = "/var/www/tomajax/current"
  $listen  = File.expand_path 'tmp/sockets/.unicorn.sock', $app_dir
  $pid     = File.expand_path 'tmp/pids/unicorn.pid', $app_dir
  $std_log = File.expand_path 'log/unicorn.log', $app_dir
  # set config
  worker_processes  $worker
  working_directory $app_dir
  stderr_path $std_log
  stdout_path $std_log
  timeout $timeout
  listen  $listen
  pid $pid
  # loading booster
  preload_app true
  # before starting processes
  before_fork do |server, worker|
    defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
    old_pid = "#{server.config[:pid]}.oldbin"
    if old_pid != server.pid
      begin
        Process.kill "QUIT", File.read(old_pid).to_i
      rescue Errno::ENOENT, Errno::ESRCH
      end
    end
  end
  # after finishing processes
  after_fork do |server, worker|
    defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
  end
=end

-----------------------------------------
# set config for capistrano
*[ tomajax ] $: bundle exec cap install
*[ tomajax ] $: vi Capfile
=begin[Capfile]
  # 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
  require 'capistrano/rbenv'
  require 'capistrano/bundler'
  require 'capistrano/rails/assets'
  require 'capistrano/rails/migrations'
  # Include slack notifier
  # require 'slackistrano'
  # Load custom tasks from `lib/capistrano/tasks` if you have any defined
  Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r }
=end
*[ tomajax ] $: vi lib/capistrano/tasks/unicorn.cap
=begin[lib/capistrano/tasks/unicorn.cap]
  namespace :unicorn do
    task :environment do
      set :unicorn_pid,    "#{current_path}/tmp/pids/unicorn.pid"
      set :unicorn_config, "#{current_path}/config/unicorn.conf.rb"
    end
    def start_unicorn
      within current_path do
        execute :bundle, :exec, :unicorn, "-c #{fetch(:unicorn_config)} -E #{fetch(:rails_env)} -D"
      end
    end
    def stop_unicorn
      execute :kill, "-s QUIT $(< #{fetch(:unicorn_pid)})"
    end
    def reload_unicorn
      execute :kill, "-s USR2 $(< #{fetch(:unicorn_pid)})"
    end
    def force_stop_unicorn
      execute :kill, "$(< #{fetch(:unicorn_pid)})"
    end
    desc "Start unicorn server"
    task start: :environment do
      on roles(:app) do
        start_unicorn
      end
    end
    desc "Stop unicorn server gracefully"
    task stop: :environment do
      on roles(:app) do
        stop_unicorn
      end
    end
    desc "Restart unicorn server gracefully"
    task restart: :environment do
      on roles(:app) do
        if test("[ -f #{fetch(:unicorn_pid)} ]")
          reload_unicorn
        else
          start_unicorn
        end
      end
    end
    desc "Stop unicorn server immediately"
    task force_stop: :environment do
      on roles(:app) do
        force_stop_unicorn
      end
    end
  end
=end
*[ tomajax ] $: vi config/deploy/production.rb
=begin[config/deploy/production.rb]
  server   '127.0.0.1',
    user:  'tomajax',
    roles: %w{app db web},
    ssh_options: {
      keys: [
        # for ec2
        File.expand_path('~/.ssh/tomajax'),
        # for github
        File.expand_path('~/.ssh/id_rsa')
      ],
      forward_agent: true,
      auth_methods: %w(publickey)
    }
=end
*[ tomajax ] $: vi config/deploy.rb
=begin[config/deploy.rb]
  # config valid only for current version of Capistrano
  lock '3.4.0'
  set :rbenv_ruby,    '2.1.3'
  set :application,   'tomajax'
  set :repo_url,      'git@github.com:Hogeo/tomajax.git'
  set :branch,        'master'
  set :deploy_to,     '/var/www/tomajax'
  set :linked_dirs,   fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system')
  set :keep_releases, 3
  # set values for slackistrano deployment notifier
  # set :slack_webhook,      'https://hooks.slack.com/services/T02B5F7S3/B0ATNSDB6/ERhof0moz0987uLtiXXXXXX'
  # set :slack_icon_url,     'https://s3-ap-northeast-1.amazonaws.com/tomajax/images/tomato3_small.png'
  # set :slack_username,     'Tomajax'
  # set :slack_msg_starting, "#{ENV['USER'] || ENV['USERNAME']} による #{fetch :branch} ブランチの #{fetch :rails_env, 'production'} 環境へのデプロイが始まります。"
  # set :slack_msg_finished, "#{ENV['USER'] || ENV['USERNAME']} による #{fetch :branch} ブランチの #{fetch :rails_env, 'production'} 環境へのデプロイが成功しました!!"
  # set :slack_msg_failed,   "#{ENV['USER'] || ENV['USERNAME']} による #{fetch :branch} ブランチの #{fetch :rails_env, 'production'} 環境へのデプロイが失敗しました..."
  namespace :deploy do
    desc 'Restart application'
    task :restart do
      invoke 'unicorn:restart'
    end
    desc 'Create database'
    task :db_create do
      on roles(:db) do |host|
        with rails_env: fetch(:rails_env) do
          within current_path do
            execute :bundle, :exec, :rake, 'db:create'
          end
        end
      end
    end
    desc 'Run seed'
    task :seed do
      on roles(:app) do
        with rails_env: fetch(:rails_env) do
          within current_path do
            execute :bundle, :exec, :rake, 'db:seed'
          end
        end
      end
    end
    after :publishing, :restart
    after :restart,    :clear_cache do
      on roles(:web), in: :groups, limit: 3, wait: 10 do; end
    end
    after :finished,   :cleanup
  end
=end

-----------------------------------------
# add secret_key_base
*[ tomajax ] $: rake secret
*[ tomajax ] $: vi config/secrets.yml
=begin[config/secrets.yml]
  production:
    secret_key_base: c013ghj7bc1b87xxx0099ace86ca58a9ca000ce3d0000000a4ee86acad7a4ba4f189823xxxxx635326a9b17ecf8fe047a293aa05562be4fec6c544aa4e963xxx
=end

-----------------------------------------
# push to remote repository
*[ tomajax ] $: git add .
*[ tomajax ] $: git commit -m 'set environment for deployment'
*[ tomajax ] $: git push origin master

-----------------------------------------
# install nginx
[tomajax|~]$ sudo yum install nginx
[tomajax|~]$ cd /etc/nginx/conf.d/
[tomajax|conf.d]$ sudo touch tomajax.conf
[tomajax|conf.d]$ sudo vi tomajax.conf
=begin[/etc/nginx/conf.d/tomajax.conf]
  # log directory
  error_log  /var/www/tomajax/current/log/nginx.error.log;
  access_log /var/www/tomajax/current/log/nginx.access.log;
  # max body size
  client_max_body_size 2G;
  upstream app_server {
    # for UNIX domain socket setups
    server unix:/var/www/tomajax/current/tmp/sockets/.unicorn.sock fail_timeout=0;
  }
  server {
    listen 80;
    server_name 127.0.0.1;
    # nginx so increasing this is generally safe...
    keepalive_timeout 5;
    # path for static files
    root /var/www/tomajax/current/public;
    # page cache loading
    try_files $uri/index.html $uri.html $uri @app;
    location @app {
      # HTTP headers
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_redirect off;
      proxy_pass http://app_server;
    }
    # Rails error pages
    error_page 500 502 503 504 /500.html;
    location = /500.html {
      root /var/www/tomajax/current/public;
    }
  }
=end

-----------------------------------------
# make dir for application
[tomajax|~]$ sudo mkdir /var/www
[tomajax|~]$ cd /var
[tomajax|var]$ chown tomajax www
[tomajax|var]$ sudo chown tomajax www

-----------------------------------------
# install bundler
[tomajax|var]$ cd
[tomajax|~]$ gem install bundler

-----------------------------------------
# change settings for production at database.yml
*[ tomajax ] $: vi config/database.yml
=begin[config/database.yml]
  production:
    <<: *default
    database: tomajax_production
    username: root
=end

-----------------------------------------
# change settings for mysql & create database
[tomajax|~]$ mysql --help
[tomajax|~]$ sudo vi /etc/my.cnf
[tomajax|~]$ sudo service mysqld start
[tomajax|~]$ mysql -u root -p
[mysql]> CREATE DATABASE tomajax_production;
[mysql]> SHOW DATABASES;
[mysql]> QUIT;

-----------------------------------------
# remove ec2-user & start to deploy
[tomajax|~]$ sudo userdel -r ec2-user
[tomajax|~]$ sudo service nginx start
[tomajax|~]$ exit
*[ tomajax ] $: bundle exec cap production deploy

64
61
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
64
61

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?