はじめに
添野と申します。プログラミング学習を初めて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でのシェアをよろしくお願いします。

























