nginxを使ってアクセスログを追う
やりたいこと
- ある検索項目(URLのパラメータ)がどのくらい使われているのか調べたい
やったこと
1.nginxのアクセスログの置き場所を確認
$ cat /etc/nginx/nginx.conf ~ access_log /var/log/nginx/access.log main; // ここにある ~
2.アクセスログから特定の文字が含まれている回数を出力してみる
// とりあえずログが存在するか確認 $ tail -f /var/log/nginx/access.log ログが流れてくる // 特定の文字が含まれている行数を出力 $ cat /var/log/nginx/access.log | grep {検索したい文字列} | wc -l 934
コマンド解説
wc -l
wc
コマンドは、自邸されたファイル内の行数、単語数、バイト数をカウントできる
オプション
-c
バイト数のみを集計して表示
-w
単語数のみを集計して表示
-c
行数のみを集計して表示
file
集計するファイルを指定する
3.数日前の複数のアクセスログファイルを含めて回数を出力
// 数日前のアクセスログは圧縮されているため解凍する $ gunzip /var/log/nginx/20190720.gz // 行数の出力 $ find /var/log/nginx/ -type f -name "access.log-2019*" | xargs sudo grep jobTypes | wc -l 7388 // 解凍したファイルを圧縮し直しておく $ gzip /var/log/nginx/20190720.gz
コマンド解説
xargs
xargs
コマンドは、標準入力やファイルを引数として、別のコマンドを実行することができる
Migrations are pending. To resolve this issue, run: bin/rails db:migrate RAILS_ENV=development
問題
エラーログさんに言われたように実行
rails db:migrate RAILS_ENV=development
再度起動してもなんもかわらない。。
解決
migrate実行してもなんでエラーが続くのかという根本は解決されてません。
rails g scaffold
もしくはrails g model
で作った時にmigrateファイルも自動生成されるが、
そもそも既存のDB使っていたためmigrateファイル必要なくない?ってことで、
自動生成されたmigrateファイルを削除。解決。
RailsでBasic認証・Dockerで環境変数を設定
Basic認証の処理を書く
class ApplicationController < ActionController::Base before_action :basic_auth protect_from_forgery with: :exception private def basic_auth authenticate_or_request_with_http_basic do |username, password| username == ENV.fetch('BASIC_AUTH_USER') && password == ENV.fetch('BASIC_AUTH_PASSWORD') end end end
ENV.fetch('BASIC_AUTH_USER')
ENV.fetch('BASIC_AUTH_PASSWORD')
で環境変数で設定しているものを参照する
環境変数の設定
環境変数とは
パスワードや秘密鍵など、Githubに載せて行きたくない・漏らしてはいけない情報を、サーバーなどのOSに保存しておき、 それをアプリケーションに渡す仕組み
dockerで環境変数を設定する方法
設定したい環境変数をまとめたファイルを作成
BASIC_AUTH_USER=user BASIC_AUTH_PASSWORD=password
docker composeファイルに設定を追記
version: '3' services: app: container_name: "app" build: context: . dockerfile: Dockerfile command: bundle exec rails s -p 3000 -b '0.0.0.0' ports: - 3000:3000 external_links: - db volumes: - .:/app # 追記 env_file: - .env
Railsアプリケーションを本番環境に構築するためのAWSでやったこと
ECRにrailsアプリケーションをプッシュ
ECRでリポジトリを作成
dockerイメージをプッシュ
// docker-compose.ymlまで移動しておく // awsコマンドでログイン $(aws ecr get-login --no-include-email --region ap-northeast-1) // ビルド $ docker build -t new/repository . // イメージにタグをつける $ docker tag new/repository:latest xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/new/repository:latest // ERCのリポジトリにイメージをプッシュ docker push xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/new/repository:latest
AWSでサーバーの準備
すでに準備されていたもの
Route53
Certificate Managerで証明書を発行
ハマりポイント:CNAMEレコードを追加しないといつまで経っても検証されない
EC2 > ロードバランシング
ターゲットグループを作成
- 今回はポートを3001に設定
- ターゲットを編集で使いたいインスタンスを登録
- そのインスタンスに紐づいているセキュリティグループのインバウンドを編集
ポート範囲:3001
ソース:ロードバランサーのセキュリティグループIDを指定
こいつをせっていしないと、504 Gatewaytimeout
になる
参考:AWSのロードバランサーはセキュリティグループに自分のグループIDが追加されてないと504 Gatewaytimeoutになる - YoshinoriN's Memento
ロードバランサー
RDS
- RDSのセキュリティグループでrailsアプリケーションからのアクセスを許可する
cronでawsコマンドが実行されない問題
問題
22時にインスタンス停止コマンドを打つように設定
0 22 * * * aws ec2 stop-instances --region=ap-northeast-1 --instance-ids=i-xxxx
時間が過ぎた後にawsコンソールから確認してもインスタンスが起動したまま。。
確認
普通に上記のコマンドを打った時にインスタンスが停止するか確認
$ aws ec2 stop-instances --region=ap-northeast-1 --instance-ids=i-xxxx { "StoppingInstances": [ { "InstanceId": "i-xxxx", "CurrentState": { "Code": 64, "Name": "stopping" }, "PreviousState": { "Code": 16, "Name": "running" } } ] }
結果:awsコンソールを確認するとインスタンスが停止している
cronのログを確認
$ tail -f /var/log/cron Jul 11 00:01:22 ip-10-0-0-11 CROND[18896]: (centos) CMD (aws ec2 stop-instances --region=ap-northeast-1 --instance-ids=i-xxxx)
結果:cronさんはコマンドを叩いてくれてはいる
でも、/var/log/cron
には実行ログしか書き込まれず、エラーがあってもここには出てこないらしい
エラーログを吐き出してみる
$ crontab -e 0 22 * * * aws ec2 stop-instances --region=ap-northeast-1 --instance-ids=xxxx > cron-error.log 2>&1 $ cat cron-error.log /bin/sh: aws: command not found
結果:どうやらコマンドのパスが合ってなくてこけてるらしい
解決
awsコマンドのパスを確認する
$ which aws ~/.local/bin/aws
コマンドのフルパスを指定する
$ crontab -e 0 22 * * * ~/.local/bin/aws ec2 stop-instances --region=ap-northeast-1 --instance-ids=xxxx
インスタンスを確認すると停止してる!
cronで時間指定してec2インスタンスを自動起動・停止する
cronとは
時間とその時間に実行したいプログラムを指定しておけば、 設定した時間にそのプログラムが実行される
cronコマンド
// cronに設定されているものを確認 crontab -l // cronの設定を編集 crontab -e // cronを削除(まるっと消える) crontab -r
時間指定の書式
// 分・時・日・月・曜日 * * * * * {command}
その他諸々の書き方:https://www.server-memo.net/tips/crontab.html
ec2インスタンス起動・停止
// 起動 aws ec2 start-instances --region=ap-northeast-1 --instance-ids=i-XXXXXXXX // 停止 aws ec2 stop-instances --region=ap-northeast-1 --instance-ids=i-XXXXXXXX
まとめると
// 毎朝9時に起動して 0 9 * * * aws ec2 start-instances --region=ap-northeast-1 --instance-ids=i-XXXXXXXX // 毎晩22時に停止する 0 22 * * * aws ec2 stop-instances --region=ap-northeast-1 --instance-ids=i-XXXXXXXX
docker上のrailsアプリケーションからローカル上のmysqlに接続できない問題
環境
問題
すでにrailsはdockerで起動済み
railsアプリケーションにアクセスしようとするとdbの接続エラーが出てくる
$ curl 0.0.0.0:3000/index Puma caught this error: Can't connect to MySQL server on 'xx.xx.xx.xx' (110 "Connection timed out") (Mysql2::Error::ConnectionError)
mysqlコマンドで外部からアクセスできるか確認
# mysql -h xx.xx.xx.xx -uroot -p Enter password: ERROR 2003 (HY000): Can't connect to MySQL server on 'xx.xx.xx.xx' (110)
できないぽ
解決策
全てを受け入れるようにしてみる(セキュリティ的にやばい)
参照:MySQLをiptablesで安全に外部公開する設定 | システムガーディアン株式会社
1. bind-addressで許可する
$ vim /etc/my.cnf bind-address = 0.0.0.0 # bind-address = 127.0.0.1 //コメントアウトしておく # bind-address = 10.x.x.xxx // 停止 sudo mysqladmin -uroot -p shutdown // 起動 sudo mysqld_safe &
確認
# mysql -h xx.xx.xx.xx -uroot -p Enter password: ERROR 2003 (HY000): Can't connect to MySQL server on 'xx.xx.xx.xx' (110)
できないぽ
んんー?
2. 初心にもどりAWSのセキュリティグループ
空いているポートを確認
$ nmap xx.xx.xx.xx Starting Nmap 6.40 ( http://nmap.org ) at 2019-07-10 11:16 JST Nmap scan report for mail.xxx.jp (xx.xx.xx.xx) Host is up (0.00050s latency). Not shown: 996 filtered ports PORT STATE SERVICE 22/tcp open ssh 80/tcp closed http 443/tcp open https 8002/tcp closed teradataordbms Nmap done: 1 IP address (1 host up) scanned in 4.46 seconds
お?3306が空いてないぞ
AWSのセキュリティグループで3006を全てに解放(セキュリティやば過ぎ)
$ nmap xx.xx.xx.xx Starting Nmap 6.40 ( http://nmap.org ) at 2019-07-10 11:16 JST Nmap scan report for mail.xxx.jp (xx.xx.xx.xx) Host is up (0.00050s latency). Not shown: 996 filtered ports PORT STATE SERVICE 22/tcp open ssh 80/tcp closed http 443/tcp open https 3306/tcp open mysql 8002/tcp closed teradataordbms Nmap done: 1 IP address (1 host up) scanned in 4.46 seconds
確認
# mysql -h xx.xx.xx.xx -uroot -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 7 Server version: 5.5.56-MariaDB MariaDB Server Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>
とりあえずいけたから、次はセキュリティ面を解決してかないと。