はじめに
添野と申します。プログラミング学習を初めて4か月ほど経過しました。
Railsでメルカリ風フリマアプリを1人で作れたので、ロードマップとして一通りの開発経緯を残します。
序章では、Railsでフリマアプリ開発を行う前にアプリの雛形をAWSへデプロイする方法を解説します。
デプロイには自動デプロイが可能となる便利なgem"capistrano"
を使用します。
制作するアプリ
ユーザ登録、商品出品・購入の機能を備えたフリマアプリです。
メルカリ風、というかほぼメルカリです。メルカリを作ります。
ちなみに、この規模のアプリは単価50万円ほどで取引されることが多いそうです。
通常納期は30日ほどだと思いますが、慣れてくれば1週間くらいで作れたりします。
この記事を使って、Web開発を極める一助にしていただければ幸いです。
OS : macOS Catalina 10.15.3
DB : MySQL
Ruby : 2.5.1
Rails: 5.2.4.2
フリマアプリ開発完全ロードマップ
章 | 内容 | 難易度 | 所要時間 | 主要技術 |
---|---|---|---|---|
序 章 | AWS自動デプロイ | ★☆☆☆☆ | ★★★☆☆ | capistrano |
第一章 | データベース設計 | ★☆☆☆☆ | ★☆☆☆☆ | |
第二章 | マークアップ作業 | ★★☆☆☆ | ★★★★★ | |
第三章 | ユーザ登録/ログイン機能 | ★★★★☆ | ★★☆☆☆ | devise |
第四章 | 商品出品/編集/詳細表示/削除 | ★★★★☆ | ★★★☆☆ | carrierwave |
第五章 | 商品カテゴリ機能 | ★★★★★ | ★★★☆☆ | ancestry |
第六章 | 商品購入機能 | ★★★★★ | ★★★★☆ | Payjp |
1.ディレクトリの作成
早速、アプリ開発を始めていきます。
ディレクトリは~/project
、アプリ名はfrema-app
として作成します。
【注意】
ここでアプリ名をfrema-app
以外にする場合、この後に出てくるアプリ名を全て置換する必要があります。
コピペした時にアプリ名がそのままだとエラーの原因になるのでよく確認して作業することをおすすめします。
1.ターミナルで以下のコマンドを実行
cd projects
rails new frema-app -d mysql
cd frema-app
rails db:create
git init
rails s
2.以下のアドレスでRailsトップページの表示を確認
http://localhost:3000/
2.レポジトリの作成
今回はGithub Desktopを使用します。
「レポジトリって??」という人はこれを読んでください。
1.以下の動画の通りにローカルレポジトリを登録
2.Publish repository
を実行してリモートリポジトリを登録
3.コミット名にinitial commit
と入力してコミット後にPublish branch
3.デプロイ設定
アプリを作り込む前にデプロイしましょう。
インフラは全部最初にやってしまった方がいいです。
1. ここでアカウント作成
2. サービス
をクリック
3. EC2
をクリック
4.インスタンスの作成
をクリック
5. Amazon Linux AMI
を選択
※Amazon Linux 2 AMI
ではないので注意
6. 作成と確認
をクリック
8.新しいキーペアの作成
を選択
9.キーペア名
にfrema-app
と入力
10.キーペアのダウンロード
をクリック
11.インスタンスの作成
をクリック
12.インスタンス
をクリック
13.インスタンスID
をコピーしてメモに保存
14.Elastic IP
をクリック
15.新しいアドレスの割り当て
をクリック
16.割り当て
をクリック
17.Elastic IP
をコピーしてメモに保存
18.閉じるをクリック
19.アクション
をクリック
20.アクションの関連付け
をクリック
21.インスタンス
にメモしたインスタンスID
を選択して入力
22.関連付け
をクリック
24.インスタンス
をクリック
25.メモしたインスタンスID
と一致するものをクリック
26.セキュリティグループ
の欄からlaunch-wizard(数字)
をクリック
27.インバウンド
をクリック
28.編集
をクリック
29.ルールの追加
をクリック
30.タイプ
でHTTP
を選択
31.保存
をクリック
32.ターミナルで以下を実行
cd ~
mkdir ~/.ssh
mv Downloads/frema-app.pem .ssh/
cd .ssh/
chmod 600 frema-app.pem
ssh -i frema-app.pem ec2-user@18.181.6.140
※ssh -i frema-app.pem ec2-user@18.181.6.140
の18.181.6.140
は、メモしたElastic IP
に置き換えて下さい
Are you sure you want to continue connecting (yes/no)?
と出力されるので、yes
と入力してEnterです。
この辺りで一旦休憩したくなりそうですが、この章の最後までは休憩せずに進めるのがおすすめです。
なぜなら、この辺の退屈な作業を早々に終わらせると、後々の作業がかなり楽しくなるからです。
33.EC2ターミナルで以下をすべて実行
深く考える必要はありません。全てをコピペEnterです。
sudo yum -y update
sudo yum -y install git make gcc-c++ patch libyaml-devel libffi-devel libicu-devel zlib-devel readline-devel libxml2-devel libxslt-devel ImageMagick ImageMagick-devel openssl-devel libcurl libcurl-devel curl
sudo curl -sL https://rpm.nodesource.com/setup_6.x | sudo bash -
sudo yum -y install nodejs
git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
source .bash_profile
git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
rbenv rehash
rbenv install 2.5.1
rbenv global 2.5.1
rbenv rehash
sudo yum -y install mysql56-server mysql56-devel mysql56
sudo yum update
sudo service mysqld start
34.EC2ターミナルで以下のPASSWORD
を任意のパスワードに書き換えて実行
sudo /usr/libexec/mysql56/mysqladmin -u root password 'PASSWORD'
コピペで実行するとパスワードが「PASSWORD
」になるので注意。
35.ターミナルで以下を実行し、上記で設定したパスワードを入力
mysql -u root -p
# mysqlが起動するので、exitと入力して終了する
exit
36.EC2ターミナルで以下を実行
ssh-keygen -t rsa -b 4096
Enter file in which to save the key (/home/ec2-user/.ssh/id_rsa):
という表示で止まるので、Enter
を3回押します。
37.EC2ターミナルで以下を実行
cat ~/.ssh/id_rsa.pub
長い文字列が出てくるので、コピーしておきます。
40.Title
に適当な名前、Key
にコピーした長い文字列をペーストしAdd SSH key
をクリック
41.EC2ターミナルで以下のコマンドを実行
ssh -T git@github.com
// yesで進める
ここでHi!
という陽気な挨拶とともに、Githubのユーザ名が表示されれば連携成功です。
42.Gemfile
に以下を追記し、ローカルでbundle install
group :production do
gem 'unicorn', '5.4.1'
end
group :development, :test do
gem 'capistrano'
gem 'capistrano-rbenv'
gem 'capistrano-bundler'
gem 'capistrano-rails'
gem 'capistrano3-unicorn'
end
# 以下は末尾に追記
gem 'pry-rails'
gem 'haml-rails'
gem 'erb2haml'
bundle install
rails haml:replace_erbs
bundle exec cap install
43.Capfile
を以下のように書き換え
require "capistrano/setup"
require "capistrano/deploy"
require 'capistrano/rbenv'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano3/unicorn'
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
44.config/deploy/production.rb
を以下のように書き換え
server '18.181.6.140', user: 'ec2-user', roles: %w{app db web}
18.181.6.140
という文字列(Elastic IP
)はご自身のものに置き換えて下さい。
45.config/deproy.rb
を以下のように書き換える
lock '3.13.0'
set :application, 'frema-app'
set :repo_url, 'git@github.com:Fumiya-Soeno/frema-app.git'
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system', 'public/uploads')
set :rbenv_type, :user
set :rbenv_ruby, '2.5.1'
set :ssh_options, auth_methods: ['publickey'], keys: ['~/.ssh/frema-app.pem']
set :unicorn_pid, -> { "#{shared_path}/tmp/pids/unicorn.pid" }
set :unicorn_config_path, -> { "#{current_path}/config/unicorn.rb" }
set :keep_releases, 5
after 'deploy:publishing', 'deploy:restart'
namespace :deploy do
task :restart do
invoke 'unicorn:restart'
end
end
1行目のlock '3.13.0'
はcapistranoのバージョンに合わせて書き換えて下さい。バージョンはGemfile.lock
に以下のような形で書いてあります。
〜(省略)〜
builder (3.2.4)
byebug (11.1.1)
capistrano (3.13.0) // これです
airbrussh (>= 1.0.0)
i18n
rake (>= 10.0.0)
〜(省略)〜
3行目のset :repo_url, 'git@github.com:Fumiya-Soeno/frema-app.git'
も書き換えが必要です。Fumiya-Soeno/frema-app
の部分を、ご自身のリモートリポジトリのGithub上でのパスに置き換えて下さい。
46.config/unicorn.rb
を新規作成し、以下のように編集
app_path = File.expand_path('../../../', __FILE__)
worker_processes 1
working_directory "#{app_path}/current"
listen "#{app_path}/shared/tmp/sockets/unicorn.sock"
pid "#{app_path}/shared/tmp/pids/unicorn.pid"
stderr_path "#{app_path}/shared/log/unicorn.stderr.log"
stdout_path "#{app_path}/shared/log/unicorn.stdout.log"
timeout 60
preload_app true
GC.respond_to?(:copy_on_write_friendly=) && GC.copy_on_write_friendly = true
check_client_connection false
run_once = true
before_fork do |server, worker|
defined?(ActiveRecord::Base) &&
ActiveRecord::Base.connection.disconnect!
if run_once
run_once = false
end
old_pid = "#{server.config[:pid]}.oldbin"
if File.exist?(old_pid) && server.pid != old_pid
begin
sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
Process.kill(sig, File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH => e
logger.error e
end
end
end
after_fork do |_server, _worker|
defined?(ActiveRecord::Base) && ActiveRecord::Base.establish_connection
end
47.config/environments/production.rb
の以下の行を探し、コメントアウト
# config.assets.js_compressor = :uglifier
48.EC2ターミナルで以下を実行
sudo mkdir /var/www/
sudo chown ec2-user /var/www/
sudo yum -y install nginx
sudo vim /etc/nginx/conf.d/rails.conf
49.vimで以下のようにファイルを編集
upstream app_server {
server unix:/var/www/frema-app/shared/tmp/sockets/unicorn.sock;
}
server {
listen 80;
server_name 18.181.6.140;
client_max_body_size 2g;
root /var/www/frema-app/current/public;
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
root /var/www/frema-app/current/public;
}
try_files $uri/index.html $uri @unicorn;
location @unicorn {
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;
}
error_page 500 502 503 504 /500.html;
}
挿入はiキー
、終了はescキー
→ :wq
と入力→Enterキー
です。
6行目にserver_name 18.181.6.140;
とありますが、
ここはご自身のElasticIP
を入れて下さい。
50.EC2ターミナルで以下を実行
cd /var/lib
sudo chmod -R 775 nginx
cd /var/www/
51.これまでの変更をmasterにプッシュ
今回はGithub Desktopで行います。
52.アプリをEC2にクローン
cd /var/www/
git clone https://github.com/Fumiya-Soeno/frema-app.git
2行目Fumiya-Soeno
の部分はご自身のGithubユーザ名を入れて下さい。
コマンド入力後、Githubユーザ名とパスワードを要求されるので入力して下さい。
53.EC2ターミナルで以下のコマンドを実行
cd ~
sudo dd if=/dev/zero of=/swapfile1 bs=1M count=512
sudo chmod 600 /swapfile1
sudo mkswap /swapfile1
sudo swapon /swapfile1
sudo sh -c 'echo "/swapfile1 none swap sw 0 0" >> /etc/fstab'
54.ローカルで以下のコマンドを実行
cd projects/frema-app/
bundler -v
// 出力 Bundler version 2.1.4
このとき出力された 2.1.4
のような数字をコピーしておきます。
55.EC2ターミナルで以下を実行
cd /var/www/frema-app
gem install bundler -v 2.1.4
bundle install
// 結構時間がかかります(3分くらい)。ここで一瞬休憩しましょう。
2.1.4
のところに上でコピーした数字をペーストです。
55.EC2ターミナルで以下を実行
rake secret
長い文字列が出力されるので、コピーします。
sudo vim /etc/environment
vimが起動するので下記のように編集します。
DATABASE_PASSWORD=PASSWORD
SECRET_KEY_BASE=先程コピーした長い文字列
1行目の=
の後のPASSWORD
にはmysqlで設定したパスワードを書いておきましょう。
56.EC2ターミナルからexit
してログインし直す
exit
↓ログアウトされるので、下記を実行してec2にログインし直す
ssh -i frema-app.pem ec2-user@18.181.6.140
18.181.6.140
の部分はご自身のElasticIPに置き換えます。
57.config/database.yml
を修正
Railsのコードを一部修正です。
produbtion:
と記述のある部分を以下のように書き換えます。
production:
<<: *default
database: frema-app_production
username: root
password: <%= ENV['DATABASE_PASSWORD'] %>
socket: /var/lib/mysql/mysql.sock
58.変更をmasterにプッシュ
Github Desktopで行います。
59.EC2ターミナルで以下を実行
cd /var/www/frema-app/
git pull origin master
sudo service mysqld start
sudo service nginx start
rails db:create RAILS_ENV=production
rails db:migrate RAILS_ENV=production
rails assets:precompile RAILS_ENV=production
60.ローカルで以下を実行
cd ~/.ssh/
ssh-add -K ~/.ssh/frema-app.pem
61.表示用のトップページを作成
cd ~/projects/frema-app/
rails g controller products
Rails.application.routes.draw do
$date = Time.now.in_time_zone('Tokyo').to_s
root "products#index"
resources :products, only: :index
end
app/views/products/
にindex.html.haml
を作成して適当に文字を配置
下記の時間にデプロイが成功しました
%br
= $date
app/assets/stylesheets/application.css
を
app/assets/stylesheets/application.scss
にrenameして、適当なCSSを書く
body{
background-color: #f5f5f5;
}
62.変更をmasterにプッシュ
63.ターミナル(ローカル)で以下を実行
bundle exec cap production deploy
お疲れ様でした。ひとまずここで自動デプロイまで設定完了です。
下記のアドレスを、ご自身のElasticIPに置き換えたものにしてアクセスして下さい。
http://18.181.6.140/
上記コマンドでエラーで止まる場合は、ここに書いてあることを何かしら飛ばしている可能性が高いです。確認してみて、解決できなければ、エラーコードや起きている現象をググって解決しましょう。
無事成功していれば、下記のようにproducts#index
が表示できます。
背景が若干グレーがかっていれば、CSSの適用にも成功しています。
これでようやく、開発のスタートラインに立つことができました。
お疲れ様でした。ここまでが序章になります。
ここからようやくアプリ制作に入っていきます。頑張りましょう!
第一章 データベース設計に続きます。
章 | 内容 | 難易度 | 所要時間 | 主要技術 |
---|---|---|---|---|
序 章 | AWS自動デプロイ | ★☆☆☆☆ | ★★★☆☆ | capistrano |
第一章 | データベース設計 | ★☆☆☆☆ | ★☆☆☆☆ | |
第二章 | マークアップ作業 | ★★☆☆☆ | ★★★★★ | |
第三章 | ユーザ登録/ログイン機能 | ★★★★☆ | ★★☆☆☆ | devise |
第四章 | 商品出品/編集/詳細表示/削除 | ★★★★☆ | ★★★☆☆ | carrierwave |
第五章 | 商品カテゴリ機能 | ★★★★★ | ★★★☆☆ | ancestry |
第六章 | 商品購入機能 | ★★★★★ | ★★★★☆ | Payjp |
あとがき
この記事のここをもっと解説してほしい!などありましたら、コメント欄でお伝えください。
また、コメント欄での暴言や誹謗中傷の書き込み等はご遠慮ください。凹むので。
いつも記事を読んで頂いている皆さま、LGTMを押していただいている皆さま、本当にありがとうございます!!
有益な記事を執筆するモチベーションに繋がりますので、この記事が役に立ったなと思って頂けたら、
是非LGTMボタンのクリックやSNSでのシェアをよろしくお願いします。