第7回目(11/13)
※タイトル「状況について」は一時的なものでしたので削除
ALBのターゲットグループがうまく行かなかったため、最初から作り直しつつ、何が原因かを探しながらやっていたら結構な時間がかかってしまった。
1.構成図
セキュリティグループ
2.作業手順
1.EC2の構築
- 初期設定
- Ruby・Rails
- mysql・database.yml
2.RDSの構築
- EC2とRDSの接続確認
3.Railsでテストページ作成
- テストページ確認(ポート3000)
4.Nigex・Pumaの設定
- Nigexのようこそ画面確認
- バーチャルサーバの設定
- Pumaの設定
- グローバルIPアドレスでテストページ確認(ポート80)
5.Route53の設定
- 無料ドメインを登録
6.ACMの設定
- 証明書の発行
7.ALBの設定
- EC2にてヘルスチェック用ファイルを作成
- Nigexでヘルスチェック用ファイルを指定
- ターゲットグループの設定
- ロードバランサーの設定
8.ドメイン名でテストページ確認(ポート443)
3.EC2(Nginx+Puma+Rails)
役割
Nginx:Webサーバ
Puma:アプリケーションサーバ
Rails:アプリケーション
参考URL:※概略図と通信の流れを参照
https://serip39.hatenablog.com/entry/2020/12/23/235700
Nginx設定
バーチャルサーバの設定を行なった。
この設定をすることで複数のHTTPサーバを設定できる。
ここで設定する内容:
・Pumaとのソケット通信の設定 ※Puma側とpathが同じであること
・server_nameでグローバルIPを指定
・ヘルスチェック用ファイルの指定
・リバースプロキシの設定
参考URL:
https://qiita.com/HeRo/items/7063b86b5e8a2efde0f4
/etc/nginx/conf.d/todo.conf
upstream rails_app {
# UNIXドメインソケット通信の設定
server unix:/var/RailsApp/Todo/tmp/sockets/puma.sock fail_timeout=0;
}
server {
listen 80;
server_name グローバルIP;
root /var/RailsApp/Todo/public;
index index.html;
# ドキュメントルート配下を以下の先頭から順番に辿る
try_files $uri @rails_app;
# 上記の@rails_appが呼び出された場合のみ以下の設定を読み込む
location @rails_app {
proxy_headers_hash_max_size 512;
proxy_headers_hash_bucket_size 128;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-For $http_x_forwarded_proto;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header origin 'http://kadai-todo.tk';
proxy_redirect off;
proxy_pass http://rails_app;
}
}
Nginx本体のコンフィグ:
・Nginx起動時にこのコンフィグを見に行き、include /etc/nginx/conf.d/*.confでバーチャルサーバを読み込んでいる
ここで設定する内容:
・実行ユーザーがnginxになっているため変更する
/etc/nginx/nginx.conf
※抜粋
#user nginx;
user ec2-user;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
Puma設定
ここで設定する内容:
・デフォルトでポート3000を使うようになっているためコメントアウトする
・Nginxとのソケット通信の設定をしてポート80にする
参考URL:※接続の構成例を参照
https://qiita.com/rubytomato@github/items/44eb173c0111283a418c
※抜粋
#port ENV.fetch("PORT") { 3000 }
bind "unix://#{Rails.root}/tmp/sockets/puma.sock"
4.ALB
ターゲットグループ
・プロトコルバージョンは気を付けないとハマる。ALB側でHTTP2(最近使われるプロトコル?)を指定すると、Nginx側はHTTP1なのでうまく通信ができなくなる。なので、ALB側でHTTP1を指定した。ちなみに、ALB側でHTTP2を使うときは、Nginx側でHTTP2を有効にする設定が必要。
Client → HTTP2 → ALB → HTTP1 → Nginx
ヘルスチェック
・Rails側でヘルスチェックを作ろうと思い、取り掛かったがうまく設定ができなかった。とりあえず、アプリが動くようにするためシンプルにHTMLファイルを作成した
5.Rails
/app/controllers/todo_controller.rb
class TodoController < ApplicationController
def index
@msg = 'Todoリスト'
@data = TodoCore.all
end
def add
if request.post?
TodoCore.create(todo_params)
goback
else
@adddata = TodoCore.new
end
end
def edit
@editdata = TodoCore.find(params[:id])
if request.patch?
@editdata.update(todo_params)
goback
end
end
def delete
TodoCore.find(params[:id]).destroy
goback
end
private
def todo_params
params[:todo_core].permit(:task, :contents, :start_date, :end_date, :image)
end
def goback
redirect_to 'https://kadai-todo.tk/todo'
end
end
/app/views/todo/index.html.erb
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>Todo</title>
</head>
<body>
<h1>Todo#index</h1>
<p><%= @msg %></p>
<table border = "1">
<tr>
<th>id</th>
<th>タスク名</th>
<th>タスク内容</th>
<th>開始日</th>
<th>終了日</th>
<th>画像</th>
<th>編集</th>
<th>削除</th>
</tr>
<% @data.each do |obj| %>
<tr>
<td><%= obj.id %></td>
<td><%= obj.task %></td>
<td><%= obj.contents %></td>
<td><%= obj.start_date %></td>
<td><%= obj.end_date %></td>
<td><%= image_tag obj.image.to_s %></td>
<td><a href="/todo/edit/<%= obj.id %>">編集</a></td>
<td><a href="/todo/delete/<%= obj.id %>">削除</a></td>
</tr>
<% end %>
</table>
<p Class="link"><a href="/todo/add">
<< 追加</a></p>
</body>
</html>
/app/views/todo/add.html.erb
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>Todo add</title>
</head>
<body>
<h1>Todo#add</h1>
<%= form_for(@adddata, url:{controller:'todo',
action:'add'}) do |form| %>
<div class="form-group">
<label for="task">タスク名</label>
<%= form.text_field:task,{class:"form-control"} %>
</div>
<br>
<div class="form-group">
<label for="contents">タスク内容</label>
<%= form.text_area:contents,{class:"form-control"} %>
</div>
<br>
<div class="form-group">
<label for="start_date">開始日</label>
<%= form.date_field:start_date,{class:"form-control"} %>
</div>
<br>
<div class="form-group">
<label for="end_date">終了日</label>
<%= form.date_field:end_date,{class:"form-control"} %>
</div>
<br>
<div class="form-group">
<label for="image">画像</label>
<%= form.file_field:image,{class:"form-control"} %>
</div>
<br>
<%= form.submit "保存" %>
<% end %>
<p Class="link"><a href="/todo">
<< トップページに戻る</a></p>
</body>
</html>
/app/views/todo/edit.html.erb
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>Todo edit</title>
</head>
<body>
<h1>Todo#edit</h1>
<%= form_for(@editdata, url:{controller:'todo',
action:'edit', id:@editdata.id}) do |form| %>
<div class="form-group">
<label for="task">タスク名</label>
<%= form.text_field:task,{class:"form-control"} %>
</div>
<div class="form-group">
<label for="contents">タスク内容</label>
<%= form.text_area:contents,{class:"form-control"} %>
</div>
<div class="form-group">
<label for="start_date">開始日</label>
<%= form.date_field:start_date,{class:"form-control"} %>
</div>
<div class="form-group">
<label for="end_date">終了日</label>
<%= form.date_field:end_date,{class:"form-control"} %>
</div>
<div class="form-group">
<label for="image">画像</label>
<%= form.file_field:image,{class:"form-control"} %>
</div>
<%= form.submit "更新" %>
<% end %>
<p Class="link"><a href="/todo">
<< トップページに戻る</a></p>
</body>
</html>
/config/routes.rb
Rails.application.routes.draw do
get 'todo/index'
get 'todo',to: 'todo#index'
get 'todo/add'
post 'todo/add'
get 'todo/edit/:id',to: 'todo#edit'
patch 'todo/edit/:id',to: 'todo#edit'
get 'todo/delete/:id',to: 'todo#delete'
end
・Railsで「CarrierWave+Fog-AWS」を使ってS3へアップロードする仕組みを作った
・画像をアップロードすると500系のエラーが発生した
Nginxの /var/lib/nginx の所有者をec2-userに変更して解決した
https://qiita.com/rinkun/items/8f8bc19f98754b3b17c7
/config/initializers/carrierwave.rb
CarrierWave.configure do |config|
config.fog_provider = 'fog/aws'
config.fog_directory = 'kadai-webapp'
config.asset_host = 'https://s3-ap-northeast-1.amazonaws.com/kadai-webapp'
config.fog_credentials = {
provider: 'AWS',
# アクセスキー
aws_access_key_id: 'アクセスキー',
# シークレットキー
aws_secret_access_key: 'シークレットキー',
# Tokyo
region: 'ap-northeast-1',
}
# 環境ごとにS3のバケットを指定
config.fog_directory = 'kadai-webapp'
config.cache_storage = :fog
end
/app/models/todo_core.rb
class TodoCore < ApplicationRecord
mount_uploader :image, ImageUploader
end
/app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
# include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
#storage :file
storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url(*args)
# # For Rails 3.1+ asset pipeline compatibility:
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
#
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
# end
# Process files as they are uploaded:
# process scale: [200, 300]
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
# version :thumb do
# process resize_to_fit: [50, 50]
# end
# Add an allowlist of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_allowlist
%w(png jpg)
end
def extension_whitelist
%w(png jpg)
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename
# "something.jpg" if original_filename
# end
def filename
original_filename if original_filename
end
end
/config/environments/development.rb
require "active_support/core_ext/integer/time"
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# In the development environment your application's code is reloaded any time
# it changes. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false
# Do not eager load code on boot.
config.eager_load = false
# Show full error reports.
config.consider_all_requests_local = true
# Enable/disable caching. By default caching is disabled.
# Run rails dev:cache to toggle caching.
if Rails.root.join('tmp', 'caching-dev.txt').exist?
config.action_controller.perform_caching = true
config.action_controller.enable_fragment_cache_logging = true
config.cache_store = :memory_store
config.public_file_server.headers = {
'Cache-Control' => "public, max-age=#{2.days.to_i}"
}
else
config.action_controller.perform_caching = false
config.cache_store = :null_store
end
# Store uploaded files on the local file system (see config/storage.yml for options).
config.active_storage.service = :local
# Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = false
config.action_mailer.perform_caching = false
# Print deprecation notices to the Rails logger.
config.active_support.deprecation = :log
# Raise exceptions for disallowed deprecations.
config.active_support.disallowed_deprecation = :raise
# Tell Active Support which deprecation messages to disallow.
config.active_support.disallowed_deprecation_warnings = []
# Raise an error on page load if there are pending migrations.
config.active_record.migration_error = :page_load
# Highlight code that triggered database queries in logs.
config.active_record.verbose_query_logs = true
# Debug mode disables concatenation and preprocessing of assets.
# This option may cause significant delays in view rendering with a large
# number of complex assets.
config.assets.debug = true
# Suppress logger output for asset requests.
config.assets.quiet = true
# Raises error for missing translations.
# config.i18n.raise_on_missing_translations = true
# Annotate rendered view with file names.
# config.action_view.annotate_rendered_view_with_filenames = true
# Use an evented file watcher to asynchronously detect changes in source code,
# routes, locales, etc. This feature depends on the listen gem.
config.file_watcher = ActiveSupport::EventedFileUpdateChecker
# Uncomment if you wish to allow Action Cable access from any origin.
# config.action_cable.disable_request_forgery_protection = true
config.web_console.whitelisted_ips = '0.0.0.0/0'
config.hosts << "kadai-todo.tk"
end
6.結果
・Todo画面で3つタスクを追加した画面
・Todo画面で1つタスクを削除した画面
・S3バケットの状態(画像ファイルの保存場所)
この記事が気に入ったらサポートをしてみませんか?