ポートフォリオをデプロイしたときのEC2の設定1(EC2+RDS+NGINX+Puma)

ポートフォリオをAWSのEC2にデプロイした時にやったこと

EC2を作成

無料利用枠で作成する詳しくは

0:EC2に接続する

EC2の接続から例:の部分をコピーしてターミナルで行う。

ssh -i "EC2の秘密鍵.pem" ec2-user@自分のElasticIPアドレス

1:ユーザーとパスワードを作成する

sudo adduser newuser

sudo passwd newuser

2:root権限を付加(rootの↓に追加します)

sudo visudo

root   ALL=(ALL)    ALL
newuser   ALL=(ALL)    ALL

3:今作ったユーザーを変更

続きを読む

Can’t connect to MySQL server on “”(AWS+MySQLエラー対処録)

AWSでEC2にログインしてMySQLに接続するために以下のコマンドをしたところ

mysql -h my-portfolio-web.c*********l.ap-northeast-1.rds.amazonaws.com -u admin -p

ERROR 2003 (HY000): Can’t connect to MySQL server on ‘my-portfolio-web.c*******l.ap-northeast-1.rds.amazonaws.com’ (110)

確認すること

RDSのダッシュボードのデータベースを選択して、データベースが動作しているか(停止中でないか)確認します。

セキュリティーグループを確認する。

EC2ダッシュボードの「セキュリティーグループ」を選択して、「インバウンドルールを編集」をクリックします。

インバウンドルールのタイプがMySQL/Auroraでソースのセキュリティーグループが設定されているか確認します。

ソースのセキュリティーグループのインバウンドルールが↓のようであればOK です。

mysql -h my-portfolio-web.c*********l.ap-northeast-1.rds.amazonaws.com -u admin p

ERROR 1045 (28000): Access denied for user ‘admin’@’10.10.0.10’ (using password: NO)

とエラーが出てしまいました・・・
これは-u admin -pの部分が-u admin pになっていたためでした。

正しいコマンドをします。(****の部分は環境で変わる部分です)

mysql -h my-portfolio-web.c*********l.ap-northeast-1.rds.amazonaws.com -u admin -p

MySQLに接続できました!

RSpecをインストールする方法

RSpecを使いたい時に見る記事

1:Gemfileに以下を追加して保存します。

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

:
(省略)
:

group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]

# 追加
gem 'rspec-rails', '~> 3.8'
gem 'factory_bot_rails', '~> 5.0'


end

group :development do

:
(省略)
:

end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

Gemをインストールします。

 bundle install

2. インストールされているか確認します。

RSpecがインストールされているか確認します。

bundle exec rspec --version

上記のコマンドを実行するとターミナルに以下のような実行結果が表示されます。

bundle exec rspec --version
RSpec 3.8
- rspec-core 3.8.2
- rspec-expectations 3.8.4
- rspec-mocks 3.8.1
- rspec-rails 3.8.2
- rspec-support 3.8.2

FactoryBotがインストールされているか確認します。

bundle exec gem list | grep factory_bot_rails

上記のコマンドを実行するとターミナルに以下のような実行結果が表示されます。

bundle exec gem list | grep factory_bot_rails
factory_bot_rails (5.0.2)

3. サンプルアプリでRSpecを利用できるようにする

サンプルアプリのプロジェクトにRSpecを導入します。

rails generate rspec:install

上記のコマンドを実行すると以下のファイルが生成されます。

アプリ名
└── spec
├── rails_helper.rb
└── spec_helper.rb

テスト用のDBを最新の構成にします。

rails db:migrate:reset RAILS_ENV=test

テスト用のDBとは自動テストを実行するときに利用する専用のDBです。
例えば自動テストで「全データが消えること」を確認するとき、
開発中に利用しているデータが消えてしまっては困ります。

開発中のデータと自動テスト用のデータを分離して考えることで、双方が干渉しないようになります。

chart.jsでグラフを作る

Docker環境下でグラフを作りたい

1:新しくモデルを追加する

docker-compose run web bundle exec rails g model hiit user:references training_day:date training_time:integer

2:マイグレートする

docker-compose exec web bundle exec rake db:migrate

3:user.rbに以下の記述を追加する

4:コントローラーの追加をする

docker-compose exec web rails g controller hiits new edit show index

5:ルーティングを追加するroutes.rbに以下の記述を追加

6:ビューを追加する

new.html.erbの中身

<section class="hiit-form">
  <div class="log-form">
    <div class="form-title tween-animate-title center-position">運動記録</div>
    <%= form_with model: @hiit, local: true do |f| %>
     <%= f.date_field :training_day, id: "date-form", type: "text", readonly: "",
         placeholder: 'クリックして運動した日をカレンダーで選択', class: "form-field btn" %>
     <% if @hiit.errors.include?(:training_day) %>
       <div class="alert alert-danger ">
      <%= @hiit.errors.messages[:training_day][0] %>
       </div>
      <% end %>
       <%= f.number_field :training_time, required: true, placeholder: '運動時間を分単位で選択' %>
        <% if @hiit.errors.include?(:training_time) %>
         <div class="alert alert-danger ">
        <%= @hiit.errors.messages[:training_time][0] %>
     <% end %>
      <%= f.label '運動メモ', class: "box center-position" %>
      <%= f.text_area :content, class: "form-area center-position", placeholder: '例: スクワットを〇〇分、腹筋を〇〇分、プランクを〇〇分など' %>
       </div>
      <%= f.submit yield(:button_text), class: "btn slide-wine center-position" %>
     <% end %>
   </section>
<%= render 'shared/datetime' %>

<%= render ‘shared/datetime’ %>の中身

<script>
 const today = new Date(new Date().setHours(0, 0, 0, 0))
 const a_month_ago = new Date(today.getFullYear(), today.getMonth() - 1, today.getDate())

// ● カレンダー
// 選択できない日付データ(自由に変更できます。)
 const disable_dates = ['']

// カレンダーの日本語化
    flatpickr.localize(flatpickr.l10ns.ja);

// カレンダーの表示
    flatpickr('#date-form', {
// スマートフォンでもカレンダーに「flatpickr」を使用
     disableMobile: true,
// 1ヶ月前から本日まで選択可
     minDate: a_month_ago,
// 選択できない日付
     disable: disable_dates
});
</script>

なおflatpicker(カレンダー機能)を使わないときは無視していいです。できればjsに置き換えたほうが良いです

 

Gem chart.jsの導入方法(Docker+Rails)

Gemfileに記述します。↓

Gemfile

gem 'rails', '~> 5.1.7'
gem 'puma', '~> 3.7'
gem 'sass-rails', '~> 5.0'
gem 'bootstrap-sass', '3.3.7'
gem 'font-awesome-sass'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.2'
gem 'turbolinks', '~> 5'
gem 'bcrypt', '~> 3.1.7'
gem 'kaminari'
gem 'rails-i18n', '~> 5.1'
gem 'jbuilder', '~> 2.5'

gem 'chart-js-rails', '~> 0.1.4' ←追加

コンテナを作ります

docker-compose build

コンテナを起動します

docker-compose up -d

コントローラを作成(名前は任意でOKです。ここではsmall_stepsとしている)

docker-compose exec web rails g controller small_steps index

package.jsonに以下を記述します


{
  "name": "chart_js_sample",
  "private": true,
  "dependencies": {
    "chart.js": "^2.7.1" ←追加
  }
}

Railsアプリがライブラリを読み込めるように以下を記述します。

/app/assets/javascripts/application.js
//= require rails-ujs
//= require turbolinks
//= require jquery3
//= require jquery_ujs
//= require jquery
//= require Chart.min  ←追加
//= require bootstrap
//= require_tree .

ビューに以下を記述します。

small_steps/index.html.erb

<h1 class="text-center">スモールステップとビッグエリア</h1>
<canvas id="myChart" width="200" height="200"></canvas>
<script>draw_graph();</script>

Javascript部分はCoffeeScriptに変換します。

app/assets/javascripts/small_steps.coffee
window.draw_graph = ->
  ctx = document.getElementById("myChart").getContext('2d')
  myChart = new Chart(ctx, {
    type: 'bar',
    data: {
      labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
      datasets: [{
        label: '# of Votes',
        data: [12, 19, 3, 5, 2, 3],
        backgroundColor: [
          'rgba(255, 99, 132, 0.2)',
          'rgba(54, 162, 235, 0.2)',
          'rgba(255, 206, 86, 0.2)',
          'rgba(75, 192, 192, 0.2)',
          'rgba(153, 102, 255, 0.2)',
          'rgba(255, 159, 64, 0.2)'
        ],
        borderColor: [
          'rgba(255,99,132,1)',
          'rgba(54, 162, 235, 1)',
          'rgba(255, 206, 86, 1)',
          'rgba(75, 192, 192, 1)',
          'rgba(153, 102, 255, 1)',
          'rgba(255, 159, 64, 1)'
        ],
        borderWidth: 1
      }]
    },
    options: {
      scales: {
        yAxes: [{
          ticks: {
            beginAtZero:true
          }
        }]
      }
    }
  })

http://localhost:3000/small_steps/indexにアクセスすると↓

グラフが描画された!

Docker環境で新規コントローラーの作成

Docker環境でのコントローラを作成するコマンド
tasksの部分は自分が作りたいコントローラー名にする
createとdestroyアクションを作成するという意味

docker-compose exec web rails g controller tasks create destroy --skip-template-engine

–skip-template-engine: ビューファイルをスキップする設定

docker-compose exec web rails g controller tasks create destroy --skip-template-engine

コントローラーを削除したいとき

docker-compose exec web rails destroy controller macs

エスケープ処理されてしまったときの対処(エラー対処録)

経緯: グラフ作成機能を開発していたときのこと

controllerの記述

def show
  @user = current_user
  @hiits = @user.hiits
  @graphdays = @hiits.order(:training_day).limit(1000)
  @dayline = Array.new
  @graphdays.each do |graphday|
    @dayline.push(graphday.training_day.strftime('%Y/%m/%d').to_s)
  end
  @graphtimes = @hiits.order(:training_day).limit(1000)
  @minuteline = Array.new
  @graphtimes.each do |graphtime|
    @minuteline.push(graphtime.training_time)
  end
end

show.html.erbの記述

<div class="chart-container" style="position: relative; width: 100%; height: 400px;">
  <canvas id="My_Chart"></canvas>
</div>
<script>
    var graphdays = <%= @dayline %>, graphminutes =
    <%= @minuteline %>
</script>
<script>draw_graph();</script>

 

グラフが表示されない・・・

検証してみてみると

var graphdays = [&quot;2021/03/11&quot;, &quot;2021/03/30&quot;, &quot;2021/04/07&quot;, &quot;2021/04/09&quot;, &quot;2021/04/10&quot;, &quot;2021/04/16&quot;, &quot;2021/04/16&quot;], graphminutes =
[22, 15, 20, 10, 10, 6, 10]

“が&quot;に変換されている!

原因はRails3から<%= ~ %>を使って出力を行う場合に自動的にエスケープ処理が行われるようになったため。

<script>
var graphdays = <%= raw @dayline %>, graphminutes =
<%= @minuteline %>
</script>
<script>draw_graph();</script>

または

<script>
var graphdays = <%== @dayline %>, graphminutes =
<%= @minuteline %>
</script>
<script>draw_graph();</script>

とするとエスケープされないように出力できる

var graphdays = ["2021/03/11", "2021/03/30", "2021/04/07", "2021/04/09", "2021/04/10", "2021/04/16", "2021/04/16"],
 graphminutes = [22, 15, 20, 10, 10, 6, 10]

グラフが描画された!

@dayline.html_safeで試した場合はエラーとなった。

rawと<%==%>は<%==%>のほうがパフォーマンス上のメリットが少々あるそうなので後者を選ぶことにした。

WARNING: UNPROTECTED PRIVATE KEY FILE!(エラー対処録)

経緯:EC2にsshキーでログインしようとしたところ

WARNING: UNPROTECTED PRIVATE KEY FILE!と怒られた

原因

秘密鍵のPermissionが0644だったので許可されなかった。

対処法

sudo chmod 600 ~/Desktop/〇〇.pem
                ↑秘密鍵の場所(各自置いているところで異なります)

chmod 600でパーミッションを変えてあげたところログインできました。

※秘密鍵の場所と秘密鍵の名前は各自で異なりますのでご注意を

自分は秘密鍵をデスクトップに仮置していたのでDesktopとなっています。

 

(Zeitwerk::NameError)エラー対処録Ruby+Heroku

Herokuでうまくデプロイできていなかったので

heroku run console 

で調べたところ次のようなエラーが出ました。

/app/vendor/bundle/ruby/3.0.0/gems/zeitwerk-2.5.4/lib/zeitwerk/loader/callbacks.rb:25:in `on_file_autoloaded’: expected file /app/app/serializers/〇〇_serializer.rb to define constant 〇〇Serializer, but didn’t (Zeitwerk::NameError)

解決法

config.autoloader = :classic

config/application.rbに追加する

〜〜
〜〜

#moduleから上は省略
module Api
  classApplication < Rails::Application

# Initialize configuration defaults for originally generated Rails version.
    config.load_defaults6.1
# Configuration for the application, engines, and railties goes here.
# These settings can be overridden in specific environments using the files
# in config/environments, which are processed later.
# config.time_zone = "Central Time (US & Canada)"
# config.eager_load_paths << Rails.root.join("extras")
#  これを追加↓
     config.autoloader = :classic
# Only loads a smaller set of middleware suitable for API only apps.
# Middleware like session, flash, cookies can be added back manually.
# Skip views, helpers and assets when generating a new resource.
     config.api_only = true
  end
end

追加して保存後に

bundle exec pumactl start

↑をコマンドしたところpumaを起動することができました。