EC2でインスタンスを立ち上げてCapistranoでGithubからWordpressをデプロイするまで

Heroku以外を使い出したらいきなり使うツールが増えてしまってちょっと大変。
EC2でWordpressを運営するのにあたって、シンプルだけどちゃんとメンテナンスができる構成を考えてみた。

できるだけシンプルに

概念図
Screen Shot 2016-01-24 at 2.10.07 PM

AWS

  • EC2 t2.nano
    • Apache
    • MySQL
  • Elastic IP
  • Route53

開発環境

  • MacBook
  • Vagrant (CentOS)

デプロイ

Gitの操作やデプロイはMacから行います。

  • Github
  • Capistrano

TODO

  • プロビジョニング

itamae使ってここまで自動化したいけど、今回は手動でやります。


1. まずはAWS

EC2

Launch Instance から新しいEC2インスタンスを立ち上げます。
EC2インスタンス
  
Amazon Linuxで良いと思います。
OS選択
  
一番安い t2.nano を選びました。
インスタンス選択
  
Configure Instance Details をクリックして詳細設定をします。
Protect against accidental termination にチェックを入れときます。
うっかりインスタンスを消しちゃった!という可能性が低くなる。
Screen Shot 2016-01-23 at 10.29.35 AM
  
Nameに分かりやすい名前を。
Screen Shot 2016-01-23 at 10.31.50 AM
  
Security Groupをつくります。
SSHとHTTPが下のようになるように設定。
Screen Shot 2016-01-23 at 10.33.24 AM
  
名前をつけてKey pairをダウンロードできます。
これはEC2にSSH接続するのに必要です。
Screen Shot 2016-01-23 at 10.34.49 AM
  
起動するまでちょっと時間がかかるので待ちましょう。
Screen Shot 2016-01-23 at 10.39.47 AM
  
画面上部の Connect* を押すとこんな画面。
ssh i で始まるコマンドを自分のコンソールで実行すればこのインスタンスに接続できます。
Screen Shot 2016-01-23 at 10.39.56 AM


EC2にSSH接続するときにこんなエラーがでたら。

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

$ sudo vim /Users/sawada/.ssh/known_hosts を編集する。
:set number で行数を表示して、
ec2-user@ec2-00-00-0-00 の行を dd で削除する。と直ります。

 
あと、.pemファイルのパーミッションがゆるゆるだとダメです。
変更しましょう。

sudo chmod 400 yourkey.pem

接続できたら必要なソフトウェアのイントールをしていきます。

# まず初めに。
$ sudo yum update

### Apache ###

# インストール
$ sudo yum install httpd

# 再起動時に自動的に立ち上がるように
$ sudo chkconfig httpd on

# 設定ファイルを編集(コメントアウトされてたら有効にする)
$ sudo vim /etc/httpd/conf/httpd.conf

  ServerTokens Prod
  ServerSignature Off
  Options -Indexes FollowSymLinks
  NameVirtualHost *:80

# 起動
$ sudo service httpd start

### Virtual Host ###

# ステージング用のディレクトリ作成
$ sudo mkdir /var/www/html-staging

# 設定ファイルを作成
$ vi /etc/httpd/conf.d/virtualhost.conf

こんな感じで保存。
上が本番環境で、下がステージングです。
VirtualHostを使うことで、1つのサーバーで複数ドメインのサイトを管理できます。

DocumentRootの "current" については はCapistranoで後述します。
"setEnv"で環境変数をセットしています。

<VirtualHost *:80>
  ServerName example.com
  ServerAlias www.example.com
  DocumentRoot "/var/www/html/current"
  DirectoryIndex index.html index.php
  ErrorLog /var/log/httpd/production_error_log
  CustomLog /var/log/httpd/production_access_log combined
  AddDefaultCharset UTF-8
  <Directory "/var/www/html/current">
    AllowOverride All
  </Directory>
  setEnv DB_NAME your_db
  setEnv DB_USER root
  setEnv DB_PASS your_pass
  setEnv WP_HOME http://example.com
  setEnv WP_SITEURL http://example.com
</VirtualHost>

<VirtualHost *:80>
  ServerName staging.example.com
  DocumentRoot "/var/www/html-staging/current"
  DirectoryIndex index.html index.php
  ErrorLog /var/log/httpd/staging_error_log
  CustomLog /var/log/httpd/staging_access_log combined
  AddDefaultCharset UTF-8
  <Directory "/var/www/html-staging/wordpress">
    AllowOverride All
  </Directory>
  setEnv DB_NAME your_db_staging
  setEnv DB_USER root
  setEnv DB_PASS your_pass
  setEnv WP_HOME http://staging.example.com
  setEnv WP_SITEURL http://staging.example.com
</VirtualHost>

  
で、おもむろにApache再起動しようとすると current が存在しないとエラーがでるはず。
あとでつくるので、気にせず進みます。

$ sudo service httpd restart

  

次はPHPとMySQLのインストール


### PHP ###

$ sudo yum install php php-devel php-mysql php-mbstring php-gd

$ sudo vim /etc/php.ini

   error_log = /var/log/php_errors.log
   mbstring.language = Japanese
   mbstring.internal_encoding = UTF-8
   mbstring.http_input = auto
   mbstring.detect_order = auto
   expose_php = Off
   date.timezone = Asia/Tokyo

###MySQL###

$ sudo yum install mysql-server

$ sudo vim /etc/my.cnf

# こんな感じにしてみる
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Settings user and group are ignored when systemd is used.
# If you need to run mysqld under a different user or group,
# customize your systemd unit file for mysqld according to the
# instructions in http://fedoraproject.org/wiki/Systemd

character-set-server=utf8
default-storage-engine=InnoDB
innodb_file_per_table

[mysql]
default-character-set=utf8

[mysqldump]
default-character-set=utf8

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid


# 起動
$ sudo service mysqld start

# パスワード設定 パスワード以外はデフォルトでOK
# => 起動する前にこれやったらエラーでてハマった
# => 結局 MySQLをアンインストールしてやりなおしたら上手く行ったけど…。
$ mysql_secure_installation

# 再起動でも自動で立ち上がるように
$ sudo chkconfig mysqld on

# データベース作成
# あとでWordpressの設定で使うのでメモ。
$ mysql -u root -p
mysql> create database your_db;
mysql> create database your_db_staging;
mysql> exit

  

次はWordpressのインストール

ちなみに日本語版をインストールしてvimで中身をひらいた所、
文字化けしていたので設定変えました。

$ vi ~/.bash_profile

下記を追加
export LC_ALL=en_US.UTF-8

# ひとまず本番環境にインストールします
$ cd /var/www/html
$ wget http://ja.wordpress.org/latest-ja.tar.gz

# 解凍
$ tar zxvf latest-ja.tar.gz -C ./
# 所有者をapacheに変更
$ sudo chown -R apache ./wordpress/


# 後ほどCapistranoでデプロイするためにはこれもやっとく。
$ sudo chown -R ec2-user:ec2-user /var/www/

Github

Githubにレポジトリを作ってPushするまで。

鍵をつくります。
この時、keyphraseを設定するとCapistranoでデプロイできなかったので、
ひとまず無しで鍵を作成しました。

$ ssh-keygen

# ... 作成

$ cat ~/.ssh/id_rsa.pub
=> 出力された文字列をコピーします。

  
Githubの設定にいって Add SSH Key から先ほどの文字列を貼り付けて保存。
Screen Shot 2016-01-24 at 12.48.15 PM

そのままGithubで新規レポジトリを作成してください。
で、SSHの Clone URL をコピーしておきます。
こういうやつです。
git@github.com:your_github_account/your_app.git

注意
将来、インスタンスをコピーして他のインスタンスを立ち上げる場合、この鍵の仮定はやり直す必要があります。IP変わってくるので。

  
EC2に戻って、


# gitをインストール
$ sudo yum install git

# 設定
$ git config --global user.name your_github_account
$ git config --global user.email your_github_email
$ sudo git remote add origin git@github.com:your_github_account/your_app.git

# これが成功すればOK!
$ git push origin master

この例だと、

  • EC2にWordpressをインストール
  • ローカルでpull
  • 変更をcommit / Githubにpush
  • CapistranoでGithubからデプロイ

という流れだけども、
別にEC2にWordpressをインストールしないといけないわけではない。
ローカルで開発したものをGitにcommitしてそれをデプロイしてもOK。

  

Elastic IPs

IPをひも付けましょう。
IPなくてもいいんですが、EC2インスタンスと紐付いているIPは1つまで無料です。
左メニューの Elastic IPs をクリックして Allocate New Address で新しいIPを取得します。
取得したら Associate で先ほど立ち上げたインスタンスとひも付けましょう。
Screen Shot 2016-01-24 at 11.39.39 AM

Route 53

今度はドメインをひも付けます。
画面上部の Services メニューから Route 53 が見つけられるかと思います。
Screen Shot 2016-01-24 at 11.43.54 AM

Create Hosted Zone をクリックして自分のドメインを入力。
Screen Shot 2016-01-24 at 11.47.28 AM

Create Record Set を押して値を入力。

  • Type A - IPv4 address
  • Value 先ほどElastic IPsで取得したIPアドレス Screen Shot 2016-01-24 at 11.48.54 AM

似たような作業をあと2回行います。
www〜 でアクセスしてきても繋がるようにするのと、今回はステージング環境も整える予定。

Type CNAME
Name www
Value Create Hosted Zoneで入力したドメイン e.g. example.com

Type CNAME
Name staging 
Value Create Hosted Zoneで入力したドメイン e.g. example.com

2.Vagrant

やっとローカル開発環境です。

vagrant upvagrant ssh が完了している状況からです。

ローカル開発環境もapacheの VirtualHost の設定をしておいてください。
環境変数も使えようにセットアップしておきます。
そうすれば同じ wp-config.pho ファイルでWordpressが動くので。

ちなみに Vagrantfile はこんな感じです。

# -*- mode: ruby -*-
# vi: set ft=ruby :

# Download VirtualBox before run "vagrant up"
# https://www.virtualbox.org/wiki/Downloads

Vagrant.configure(2) do |config|
  # Box
  config.vm.box = "centos64box"

  # Network
  config.vm.network :forwarded_port, guest: 80, host: 8080
  config.vm.network :private_network, ip: "192.168.33.66"
  config.vm.synced_folder ".", "/vagrant", nfs: true

  # VirtualBox setting
  # https://www.vagrantup.com/docs/virtualbox/configuration.html
  config.vm.provider "virtualbox" do |v|
    v.memory = "2048"
  end
end

Githubのレポジトリをコピーして持ってきます。

Vagrant上での Apache / MySQL などの設定は省略します。
基本的にはEC2でやったことと同じです。

データベースを作成して、
問題なくWordpressが動いていることを確認してください。

$ git clone git@github.com:your_github_account/your_app.git

3.デプロイ

開発はVagrantでやって、デプロイはMac(ホストPC)でやっています。
そのままVagrant上でやればいいかと思ったのですが、
デプロイツールやSSHキーをVagrantごとに準備しなければいけないのでやめました。

Vagrant <===> Mac のシェアディレクトを利用しています。
Vagrantfileの config.vm.synced_folder ".", "/vagrant", nfs: true です。

なので、Macにもrbenvとかイントールする必要があります。
自分はRails開発してたから既に入ってたけど、Wordpressだけ開発する人は入ってないね…。 書いてて気付きました。すみませんが こういった記事 を参考にしてみてください。

Wordpressディレクトリの中にGemfileをつくります。


source 'https://rubygems.org'
gem "capistrano", "~> 3.4"

bundle install したら下のコマンドでCapistranoの初期ファイルを作成。

# Wordpressのルートで実行
$ bundle exec cap install

  
作成されたファイルに変更を加えていく。
config/deploy.rb

# config valid only for current version of Capistrano
lock '3.4.0'

# あなたのEC2インスタンス
server 'ec2-00-00-0-00.ap-northeast-1.compute.amazonaws.com',
        user: 'ec2-user'

role :web, 'ec2-00-00-0-00.ap-northeast-1.compute.amazonaws.com'

set :application, 'your_app'

set :repo_url, 'git@github.com:your_github_account/your_app.git'

set :ssh_options, {
      user: 'ec2-user',
      # EC2のインスタンスを取得したときに作成したキーです。
      keys: %w(/Users/you/Vagrant/php/your_app/your_key.pem),
      forward_agent: true,
      auth_methods: %w(publickey)
    }

namespace :deploy do
  after :restart, :clear_cache do
    on roles(:web), in: :groups, limit: 3, wait: 10 do
      # Here we can do anything.
    end
  end
end

after 'deploy:finished', :change_owner do
  puts "=" * 40
  puts "Deployed to #{release_path}"
  puts "=" * 40
  # http://theadmin.org/articles/capistrano-variables/
  on roles(:web) do
    # 所有者をapacheに変更します。これをしないとプラグインとかインストールできません。
    execute "sudo chown -R apache #{release_path}"
  end
end

  
EC2で /var/www/ の所有者を変更しておいてください。
そうしないとデプロイできない。
sudo chown -R ec2-user:ec2-user /var/www/

下記の2つはEC2上のデプロイ先を指定してあげるだけ。

config/deploy/production.rb

set :deploy_to, '/var/www/html'

  
config/deploy/staging.rb

set :deploy_to, '/var/www/html-staging'

  
そして Wordpressのルートディレクトリ から下記を実行します。
Gitのルートとも言えるかな。

$ bundle exec cap production deploy
$ bundle exec cap staging deploy

これでEC2にデプロイされるはず!

var/www/html/releases/201601...

みたいな感じでEC2上にファイルが転送されます。
そして最新のものに current のシンボリックリンクが貼られます。
VirtualHostの設定で、DocumentRootを var/www/html/current にしたのはそのためなのです。

  
configフォルダはMac上でしか使わないので、
.gitignoreに追加した方が良いかと思います。

config/deploy.rb
config/deploy/*

  
以上です。お疲れ様でした。

色んなことが絡まってて、チュートリアルって難しいな… と書いてて思いました。

何かありましたらコメントをどうぞ

comments powered by Disqus

人気の記事

950 Points チリ出身のギタリストが弾くドラゴンボールZがむちゃくちゃかっこいい…
774 Points Wordpress + Heroku + PostgreSQL + Amazon S3 = ¥0 / 無料でサイト運営
700 Points Rubyのチートシート 変数 / クラス / モジュール
524 Points Rubyのチートシート / アクティブサポート
451 Points 紙のデザイナーがウェブ開発できるようになるまでに必要なこと
435 Points Rails / Google Analyticsのデータを使って分析や管理画面のためのグラフをつくる
323 Points RailsとHerokuでノーティフィケーションをプッシュする / PusherとTurbolinksの兼ね合い
222 Points Rails / RSpec テスト書いたことない メンドクサイ(n´Д`)という時のチートシート
193 Points Rails / Ajaxを使って画面遷移しない一時保存機能をつける
193 Points Protractorでスクレイピングしてみた