Circleciを使ってEC2へ自動デプロイ
完成したymlファイル(testは容量がかかるので、コメントアウトにしている)
version: 2 jobs: # test: # machine: # image: circleci/classic:edge # steps: # - checkout # - run: # name: docker-compose build # command: docker-compose build # - run: # name: docker-compose up # command: docker-compose up -d # - run: # name: sleep for waiting db # command: sleep 120 # - run: # name: rails db:create # command: docker-compose run app bin/rails db:create # - run: # name: rails db:migrate (skip db:seed) # command: docker-compose run app bin/rails db:migrate # - run: # name: rails db:test:prepare # command: docker-compose run app bin/rails db:test:prepare # - run: # name: rails webpacker:install # command: docker-compose run app bin/rails webpacker:install # - run: # name: rspec # command: docker-compose run app rspec # - run: # name: docker-compose down # command: docker-compose down # deploy ジョブ: EC2 に SSH 接続して、デプロイを実行する deploy: machine: image: circleci/classic:edge steps: - checkout # CircleCIに登録した秘密鍵を呼び出す。 - add_ssh_keys: fingerprints: #sshの暗号化されたもの。 - 19:a4:94:21:15:c9:5c:c6:75:8a:94:4a:9c:1f:37:da - run: ssh ${USER_NAME}@${HOST_NAME} 'cd myapp && git pull' # - run: ssh ${USER_NAME}@${HOST_NAME} 'cd myapp && git pull && docker-compose run python ./manage.py migrate' workflows: version: 2 test_and_deploy: jobs: # - test # requiresなどが必要ない時は、:はいらない。今はdeployのみを行っているので、 # - deploy: - deploy # requires: # - test filters: branches: only: main
一番時間がかかったところはいつもssh周り
その他に、
RailsにJSを書く前に、yarn, npm, webpack, webpacker, ES6を理解する。
npmを便利にしたものが、yarn
JSは、ES5からES6へ。クラスやアロー関数などが使えるようになった。(babelで変換可)
上記のファイルの依存関係等をいい感じにまとめてくれるのが、webpackで、Railsにフィットさせるためのwebpackerというのがある。
npm
JavaScript(正確にはNode.jsモジュール)のパッケージマネージャです。言ってみれば、JavaScript世界におけるRubygemです。
npm = rubyでいうgem
npm install bootstrap
npmは、ダウンロードしたパッケージを./node_modulesに保存し、パッケージのリストを./package.jsonに保存します
yarn
npmよりずっと高速です。
npmより新しいパッケージマネージャです。yarnはnpmのリポジトリからパッケージを取得する点は同じ
ES6
クラス、アロー関数などでJSが書けるようになった
Babel
全てのブラウザでES6が動くわけではないので、EC5に変換するためのファイル。
Webpack
yarn, npm es5,es6などの依存関係を綺麗にまとめるもの。
webpacker
RailsアプリケーションにWebpackをいい感じに取り込めるgem
ルール
application.jsは、app/javascript/packs配下に置かれる。
viewにjsをincludeするには、
view <%= javascript_pack_tag 'pages/index' %> ↓ app/javascript/packs/index.js //ここにjsを書く。
参考;
https://techracho.bpsinc.jp/hachi8833/2020_01_16/85940
Mysql2::Error: Table 'myapp_development.post_tags' doesn't exist のエラー解決
背景
postを削除しようとしたら、このエラーが起こった。
解決のプロセス
mysqlのテーブルを見てみる
mysql> use myapp_development Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> show tables; +-----------------------------+ | Tables_in_myapp_development | +-----------------------------+ | ar_internal_metadata | | comments | | impressions | | likes | | posts | | posts_tags | | relationships | | schema_migrations | | tags | | users | +-----------------------------+ 10 rows in set (0.01 sec) mysql>
schembaを見てみる
create_table "posts_tags", id: false, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| t.bigint "post_id", null: false t.bigint "tag_id", null: false t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.index ["post_id"], name: "index_posts_tags_on_post_id" t.index ["tag_id"], name: "index_posts_tags_on_tag_id" end
post_tagsを削除しようとしているのはなぜ?
これが原因だった。
post.rb has_many :post_tags, dependent: :destroy
以前、タグを新しいテーブルを作成し、改良したときに、古いテーブルを消し忘れていた事が原因だった。
mysql8.0のエラー Plugin caching_sha2_password could not be loaded: /usr/lib/x86_64-linux-gnu/mariadb19/plugin/caching_sha2_password.so: cannot open shared object file: No such file or directory
MySQL5.7までの認証プラグインには mysql_native_password がデフォルトで使用されていましたが、MySQL8.0より新たに追加された caching_sha2_password
プラグインがもともとコードに書かれていたのに無いと言うことは、migrateとかをすればいいと思う。
http://blog.s-style.co.jp/2018/05/1807/
・新規dockerfileに以下を追加する
FROM ruby:2.6 WORKDIR /tmp RUN apt update && apt install -y lsb-release \ && apt remove -y libmariadb-dev-compat libmariadb-dev RUN wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-common_8.0.18-1debian10_amd64.deb \ https://dev.mysql.com/get/Downloads/MySQL-8.0/libmysqlclient21_8.0.18-1debian10_amd64.deb \ https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-community-client-core_8.0.18-1debian10_amd64.deb \ https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-community-client_8.0.18-1debian10_amd64.deb \ https://dev.mysql.com/get/Downloads/MySQL-8.0/libmysqlclient-dev_8.0.18-1debian10_amd64.deb RUN dpkg -i mysql-common_8.0.18-1debian10_amd64.deb \ libmysqlclient21_8.0.18-1debian10_amd64.deb \ mysql-community-client-core_8.0.18-1debian10_amd64.deb \ mysql-community-client_8.0.18-1debian10_amd64.deb \ libmysqlclient-dev_8.0.18-1debian10_amd64.deb
nginxをdockerから起動したら、エラーが消えた。
参考
Pumaについて
bindle exec puma -d
指定する場合
bundle exec puma -C config/puma.rb
pumaはサーバのソケットを開いたままリスタートできます。要するに、ユーザーに対してサーバを開放したままサーバのリスタートができるということです。ユーザーを待たせることがないため、pumaを速くすることに貢献しています。
hot resrartと呼ばれるやつ
停止
kill -SIGUSR2 `(cat tmp/pids/server.pid)`
or
bundle exec pumactl restart
https://arma-search.jp/article/ruby-puma#i-2
ソケットとは?
pumaの設定
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i threads threads_count, threads_count port ENV.fetch("PORT") { 3000 } environment ENV.fetch("RAILS_ENV") { "development" } plugin :tmp_restart app_root = File.expand_path("../..", __FILE__) #{myapp_root}/tmp/sockets/puma.sock に bind している bind "unix://#{myapp_root}/tmp/sockets/puma.sock"
「environment」
pumaをどの環境で動作させるかを指定します。デフォルトは'development'になっています。
「daemonize」
rackサーバーをデーモンにして起動するかどうか
「pidfile」
pidファイルを配置するパスを指定します。 tmp/pids/puma.pidに配置するほうが良いと思います。
「state_path」 サーバー情報を記載したstateファイルを配置するパスを指定します。 stateファイルはpumactlコマンドでサーバーを操作するのに使用します。 railsの場合、特別このようなファイルを配置するディレクトリはないので今回はtmp/pids/以下に配置
「Cluster mode」
クラスタモードとは複数のワーカープロセスを起動し、そのプロセスそれぞれでスレッドプールを持ちリクエストを処理する仕組みです。 ワーカープロセスの数は以下のように指定します。 Workerの数をマシンが持つCore数を超えないように気をつけて下さい。
「Thread Pool」 Pumaはスレッドによってリクエストを処理します。スレッドをスレッドプールに貯めておく数の下限から上限を指定することが出来ます。
「bind」 サーバーをどのように接続するかをURIで指定。シンプルにTCPで接続する場合tcp://0.0.0.0:80、またWebサーバーの前段にnginxをなどを置き、そこからUNIX Socket経由で接続する場合はunix:///var/run/puma.sockのように指定します。
なんでNginxを使うのか、高速化と処理の負担を分散させる。
Nginx: 静的,画像を処理
↓↑UNIXドメインソケット(unix://の意味はこれか。)
Pumaは動的なファイルの処理に集中できる
スタートしてみた
# bundle exec puma Puma starting in single mode... * Puma version: 5.1.1 (ruby 2.6.6-p146) ("At Your Service") * Min threads: 5 * Max threads: 5 * Environment: development * PID: 36
ハンズオン
nginxとpumaの設定、連携が書かれていてわかりやすい。