light log

学んだこととか

cronと環境変数について調べた

ということで、結局crontabで登録したスクリプトにパスワードなど設定値を書いた。

crontabはこんな感じ。

$ crontab -l
00,30 * * * * path/to/script >> path/to/log 2>&1

リダイレクトについてもいろいろ初めて知った。

しかし『入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界』、買ってからほとんど読まずに今まで積ん読してたけど、読んでみたら平易で明快でいい本。とりあえず今日は調べたい部分だけつまみ食いしたけど、前半だけでも一回通読しといた方が生産性上がって長い目で見たときに時短になりそう。結構しょうもないことで詰まってること多いからな…

Railsのproduction環境のDB周りの謎が解決?した

昨日の問題が解決?した。

はてなを付けてるのは、一応の対策はわかったけど理由がよくわからんから。

昨日↓の記事

yamacent.hatenablog.com

対策

昨日以下のようにしてたところを、

$ bin/rake db:migrate RAILS_ENV=production

このように変えれば動いた。

$ rake db:migrate RAILS_ENV=production

要はbin/rake -> rake

疑問

springについて知ってから、

yamacent.hatenablog.com

rake, railsの実行にはbin/を付けてたんだけど、今回の場合これが問題だったようだ。なぜなのかは分からない。挙動を見る限りはbin以下のbinstub実行時には環境変数がうまく読み込まれていないように見えるけれど。

それから、rails cしたときにも、実行の仕方によってDBのコネクション成否が異なるようなんだけど、これがrake db:migrateのときと方則性が違ってもはや何が何だかさっぱりわからない。

昨日bin/rake db:createは成功してた理由もよくわからない。

とりあえず、rails crake db:migrateを実行したときの成否パターンを以下にまとめてみた。

これら2つに対して、

  • bin/を付ける
  • bundle execを付ける
  • 何も付けない

のそれぞれに

  • RAILS_ENV=productionを前に付ける
  • RAILS_ENV=productionを後ろに付ける

というパターンを試した。

環境は昨日と同じ。

rails console

失敗するケース

$ rails c RAILS_ENV=production
$ bin/rails c RAILS_ENV=production
$ bundle exec rails c RAILS_ENV=production

成功するケース

$ RAILS_ENV=production rails c
$ RAILS_ENV=production bin/rails c
$ RAILS_ENV=production bundle exec rails c

まとめると、RAILS_ENV=productionが前にあると成功、後ろにあると失敗する。rails, bin/rails, bundle exec railsは関係なし。

あと、ここでの「成功」はエラーが出ずにコンソールが起動することを言ってる。そこでDBにアクセスしようとするとエラーになったケースもあったような気がする。。

rake db:migrate

失敗するケース

$ bin/rake db:migrate RAILS_ENV=production
$ RAILS_ENV=production bin/rake db:migrate

成功するケース

$ rake db:migrate RAILS_ENV=production
$ RAILS_ENV=production rake db:migrate
$ bundle exec rake db:migrate RAILS_ENV=production
$ RAILS_ENV=production bundle exec rake db:migrate

まとめると、rake, bundle exec rakeは成功、bin/rakeは失敗する。RAILS_ENV=productionの前後は関係なし。

まとめ

こういう結果になる理由が全然わからなくてものすごく気持ち悪いんだけど、今はこれ以上深堀りせず先に進むことにする。

これは後でレベルが上がってから振り返ったらなんてことなく理解できるパターンのような気がする。

疲れた。

Railsのproduction環境のDB周りでハマった

未解決。 一応解決した。続き記事は末尾。

よくわからなすぎて悲しい気持ちになってきたのでこれメモって寝る。

明日起きたら解決策閃いてたらいいな。

環境

$ cat /etc/redhat-release 
CentOS release 6.6 (Final)
$ bundle exec ruby -v
ruby 2.2.0p0 (2014-12-25 revision 49005) [x86_64-linux]
$ bundle exec rails -v
Rails 4.2.1

事象

これが失敗する。(以下、ユーザ名・パスワード等一部加工してる)

$ bin/rake db:migrate RAILS_ENV=production
rake aborted!
Mysql2::Error: Access denied for user 'myuser'@'localhost' (using password: YES)
-e:1:in `<main>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)

production環境では$DATABASE_URLで接続内容を設定したいのに、database.ymlのdefault部分の値(development,test環境で使用しているユーザ名やパスワード)が使われている。その結果、production環境ではこれらのユーザは未作成のため失敗してる。

database.yml(抜粋)

default: &default
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: myuser
  password: myuserpass
  socket: /tmp/mysql.sock

...

production:
  <<: *default
  url: <%= ENV['DATABASE_URL'] %>
  socket: /var/lib/mysql/mysql.sock

$DATABASE_URLの値

$ echo $DATABASE_URL
mysql2://productionuser:productionpass@localhost/production_database

謎なのは、このままの設定でdb:createは成功すること。

$ bin/rake db:create RAILS_ENV=production
   (0.4ms)  CREATE DATABASE `production_database` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`

db:createdb:migrateではこの辺挙動が違うのだろうか?

試しにusername, passwordをコメントアウトしてみると、エラー内容が

Mysql2::Error: Access denied for user 'root'@'localhost' (using password: NO)

という感じになる。

もちろんproduction:以下にusername, password, databaseをベタ書きすればうまくいくのかもしれないけど、そうじゃない感。

解決策

なぞ。

もう今日は元気ないので明日は以下を読むとこから始めよう。。

Rails アプリケーションを設定する — Rails ガイド

まとめ

なんか疲れてて単純ミスのような気もするし、自力では解決困難なガチのやつの気もする。誰か助けてください。。

続き書いた

yamacent.hatenablog.com

cronを使ってみた

使ってみたメモ。超初歩。

概要

cronはジョブを指定した時間に定期的に実行してくれるコマンド(サービス)。

crondデーモンを起動しておく必要がある。

cronで実行されるジョブはcrontabファイルで管理する。crontabファイルは各ユーザごとに存在する。各crontabで管理されるジョブはそのcrontabを所有するユーザの権限で実行される。

crontabファイルは直接編集するのではなく、crontabコマンドで管理(登録/削除/表示)する。

crontabコマンド

書式

crontab [ -u user ] { -l | -r | -e }

-u userでcrontabの所有ユーザを指定する。この指定を省略するとcrontabコマンドを実行したユーザのcrontabが対象となる。

crontab -lでcrontabの内容を表示する。

crontab -rでcrontabの内容を消去する。なんの確認もなく一気に全部消えるので要注意。

crontab -eでエディタが立ち上がってcrontabを編集できる。

crontabファイルの書式

書式

* * * * * command

アスタリスクが左から順に分、時、日、月、曜日を表していて、commandが実行するコマンドを表す。それらをスペース区切りで配置する。

参考:crontabの書き方 | server-memo.net

上の参考ページには大量のわかりやすい例が載っているので、詳しくはそちら参照。

いくつかだけ引用する。

毎時15分になると実行
15 * * * *

毎月10日のAM 6:15 に実行
15 6 10 * *

10分ごとに実行する場合
*/10 * * * *

簡単。

crontab -r 対策

上にも書いたけど、crontab -rでcrontabが簡単に消去されてしまうことが問題なようだ。しかも-e-rはキーが隣同士だ。

問題な「ようだ」と書いたのは、現時点で自分は一つ二つコマンドを登録するだけのつもりなので、全部消えてしまう事の重大さがいまいちピンと来ていないから。でもまぁちゃんと運用していく上で問題だろうことは容易に想像できる。

ということでいくつか対策があるみたい。

crontab -e は「絶対に」使ってはいけない - ろば電子が詰まっている

エイリアス-iオプションを付けて必ず確認が出るようにするとか、-eは使わずファイルに書いたcrontabをcrontabコマンドで読み込むようにするとか。

でもまぁやっぱり今はまだ、自分にはこの辺はオーバースペックな気がするので、当面は「-rには気をつける」という心掛けでいいかな、という気がする。登録ジョブが増えてきたら考えようと思う。

まとめ

意外と簡単な設定で使えて驚き。

Vagrantfileにプロビジョニングを書いてみた

Vagrantfileにプロビジョニングを書いてみた。

chefもansibleも初期学習コストが高そうだし全然大したことやらないのでシェルで書いた。Vagrantのドキュメントにも

If you've never used a configuration management system before, it is recommended you start with basic shell scripts for provisioning.

と書かれてる。コンフィギュレーションマネジメントシステムをネバーユーズドな自分はシェルスクリプトがいい。

やってるのは以下。

  • Nginxを入れる
  • MySQLを入れる
  • rbenvとruby-buildを入れてRubyを入れる
  • NginxとMySQLをサービスとして立ち上げる

ディレクトリ構成

$ tree
.
├── Vagrantfile
└── provision
    ├── files
    │   ├── nginx.conf
    │   └── rails_app.conf
    └── scripts
        ├── provision.sh
        └── provision_root.sh

3 directories, 5 files

Vagrantfile

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure(2) do |config|
  config.vm.box = "centos6"

  config.vm.network "forwarded_port", guest: 80, host: 8080

  config.vm.provision "file", source: "~/.vimrc", destination: ".vimrc"
  config.vm.provision "file", source: "~/.gemrc", destination: ".gemrc"
  config.vm.provision "file", source: "provision/files/nginx.conf",
    destination: "nginx.conf"
  config.vm.provision "file", source: "provision/files/rails_app.conf",
    destination: "rails_app.conf"
  config.vm.provision "shell", path: 'provision/scripts/provision_root.sh'
  config.vm.provision "shell", path: 'provision/scripts/provision.sh', privileged: false
end

.vimrcと.gemrcは必須じゃないけど、後でsshで操作するときに使い勝手よくするためにコピーしてる。

privileged:オプション(デフォルトでtrue)の有無でrootで実行されるスクリプトとそうでないスクリプトを分けてる。

privileged: true(デフォルト)で指定したスクリプトの中の~はrootのホーム(/root)になるので注意。最初間違えた。

シェルスクリプト

provision/scripts/provision_root.sh

#!/bin/env bash

yum update -y
yum install -y vim
yum install -y openssl-devel # for Ruby

# Nginx
yum localinstall -y http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
yum install -y nginx

for i in /etc/nginx/conf.d/*; do mv $i $i.bk; done
mv nginx.conf /etc/nginx/
mv rails_app.conf /etc/nginx/conf.d/

# MySQL
yum localinstall -y http://dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm
yum install -y mysql-community-server
yum install -y mysql-community-devel # for mysql2 gem

# Service
nginx
chkconfig nginx on
/etc/init.d/mysqld start
chkconfig mysqld on

provision/scripts/provision.sh

# Ruby
git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
source ~/.bash_profile

rbenv install 2.2.2
rbenv global 2.2.2

gem install bundler --no-document
gem install rails --no-document

vimは必須じゃない。

config.vm.provision "file"は、vagrantユーザ(一般ユーザ)権限でscpされるとのことなので、nginxの設定ファイルはいったんホームディレクトリにコピーしてからシェルスクリプトで/etc/nginx以下に移動してる。もっといい方法ありそう。

nginxの設定ファイルは↓の記事で書いた通り。

yamacent.hatenablog.com

NginxとMySQLリポジトリ追加は↓。

yamacent.hatenablog.com

まとめ

いろいろ確信持たずにやってるけど、これで一応動いてるような気がする。

関連する記事

yamacent.hatenablog.com

yamacent.hatenablog.com

yamacent.hatenablog.com

Vagrant入門ガイド

Vagrant入門ガイド

実践 Vagrant

実践 Vagrant

VagrantのProvisioningタイミングメモ

メモ。

Provisioning - Vagrant Documentation

バージョン

$ vagrant -v
Vagrant 1.7.2

プロビジョニングが実行される

  • 初回のvagrant up
  • vagrant up --provision
  • vagrant provision
  • vagrant reload --provision

プロビジョニングが実行されない

  • 二回目以降のvagrant up--provisionフラグなし)
  • vagrant reload--provisionフラグなし)

以上

Vagrant入門ガイド

Vagrant入門ガイド

CentOSにNginxとMySQLのリポジトリを追加

昨日から何度もググってるので備忘録として自分でもメモしておく。ググったらすぐ答え出るんだけど。

CentOSデフォルトリポジトリのNginxとMySQLのバージョンが古いので、新しいバージョンをyumコマンドでインストールするためのリポジトリ追加手順。

Nginx

参考:CentOS6.xにてnginxの最新版をインストールする手順 - Qiita

まぁ本当に上記ページ通りなんだけど、

ここ↓から「CentOS 6」等、対応するリンク(〜.rpm)をコピーして、

nginx: Linux packages

リポジトリ登録。

yum localinstall -y http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm

あとは普通にインストール。

yum install -y nginx

MySQL

参考

この日記は、以下のURL(MySQLドキュメント)の、劣化コピーです:-p。

ここはさらにその劣化コピーです:-p

ここ↓から「Red Hat Enterprise Linux 6 / Oracle Linux 6 (Architecture Independent), RPM Package」等、対応するダウンロードボタンを押して、遷移先のページのリンク(〜.rpm)をコピー、

MySQL :: Download MySQL Yum Repository

リポジトリ登録。

yum localinstall -y http://dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm

mysql-community-*のパッケージをインストール。

yum install -y mysql-community-server