cronと環境変数について調べた
なんかよくよく考えると環境変数って謎
— やまま (@yamacent) 2015, 6月 4
cronで定期的に実行するスクリプトに、DBのパスワードとかファイルに書きたくない文字列を環境変数で与えるのってどうしたらいいんだ?
— やまま (@yamacent) 2015, 6月 4
恒久的な環境変数というか。
— やまま (@yamacent) 2015, 6月 4
恒久的な環境変数というのがそもそも矛盾している?
すべての環境変数はシェルへのログイン時に定義されているの?
— やまま (@yamacent) 2015, 6月 4
cronが実行されるときの環境変数の状態はどうなってるんだろう
— やまま (@yamacent) 2015, 6月 4
デーモンが参照する環境変数はデーモンを起動したときの環境変数の状態がキャプチャされるのかな?クロージャみたいな
— やまま (@yamacent) 2015, 6月 4
デーモン起動・終了時実行の環境変数(パス)の違いに注意 http://t.co/oi6roeOq7n
— やまま (@yamacent) 2015, 6月 4
やっぱり直接スクリプトを実行するとそのときの環境変数が使われるんだな。serviceコマンド使うと(細かい挙動はOS等に依るが)ニュートラルな状態の環境変数になる。
/ デーモンの起動・終了にはserviceコマンドを利用しよう http://t.co/ux4NJkHJrO
— やまま (@yamacent) 2015, 6月 4
さては、たぶん俺にはプロセスという視点が抜けてるんだな
— やまま (@yamacent) 2015, 6月 4
いまこそ積ん読してた「入門UNIXシェルプログラミング」を読むとき
http://t.co/zc4judkPCz
— やまま (@yamacent) 2015, 6月 4
そして読んだらなんとなく分かった。いい本。
— やまま (@yamacent) 2015, 6月 4
要は、今のプロセスだけで有効なのがシェル変数で、それをexportすると環境変数になる。環境変数は親プロセスから起動された子プロセスにキー・値がコピーされる。値渡し。子プロセスから親プロセスの環境を変えることはできない
— やまま (@yamacent) 2015, 6月 4
これはYesだな
https://t.co/k3h1WqMK9D
— やまま (@yamacent) 2015, 6月 4
やっぱり恒久的な環境変数ってのは変だな。環境変数は各プロセスごとに持つもので、子プロセスに引き継がれる。
https://t.co/K3mrKvmXNk
— やまま (@yamacent) 2015, 6月 4
cronについては実験だな
— やまま (@yamacent) 2015, 6月 4
cron実行時の環境変数を設定 | admin note http://t.co/zvx1oBIhrv
— やまま (@yamacent) 2015, 6月 4
cron上でのコマンド実行を再現する - Qiita http://t.co/N3fBKyakwZ #feedly
— やまま (@yamacent) 2015, 6月 4
cronではたぶん無理やな。crontabにパスワード書くしかないか
— やまま (@yamacent) 2015, 6月 4
それかcrontabから呼び出すスクリプトに書くか。いずれにせよどっかのファイルには書かなきゃいけなそう
— やまま (@yamacent) 2015, 6月 4
ということで、結局crontabで登録したスクリプトにパスワードなど設定値を書いた。
crontabはこんな感じ。
$ crontab -l 00,30 * * * * path/to/script >> path/to/log 2>&1
リダイレクトについてもいろいろ初めて知った。
しかし『入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界』、買ってからほとんど読まずに今まで積ん読してたけど、読んでみたら平易で明快でいい本。とりあえず今日は調べたい部分だけつまみ食いしたけど、前半だけでも一回通読しといた方が生産性上がって長い目で見たときに時短になりそう。結構しょうもないことで詰まってること多いからな…
Railsのproduction環境のDB周りの謎が解決?した
昨日の問題が解決?した。
はてなを付けてるのは、一応の対策はわかったけど理由がよくわからんから。
昨日↓の記事
対策
昨日以下のようにしてたところを、
$ bin/rake db:migrate RAILS_ENV=production
このように変えれば動いた。
$ rake db:migrate RAILS_ENV=production
要はbin/rake
-> rake
。
疑問
springについて知ってから、
rake
, rails
の実行にはbin/
を付けてたんだけど、今回の場合これが問題だったようだ。なぜなのかは分からない。挙動を見る限りはbin
以下のbinstub実行時には環境変数がうまく読み込まれていないように見えるけれど。
それから、rails c
したときにも、実行の仕方によってDBのコネクション成否が異なるようなんだけど、これがrake db:migrate
のときと方則性が違ってもはや何が何だかさっぱりわからない。
昨日bin/rake db:create
は成功してた理由もよくわからない。
とりあえず、rails c
とrake 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:create
とdb:migrate
ではこの辺挙動が違うのだろうか?
試しにusername, passwordをコメントアウトしてみると、エラー内容が
Mysql2::Error: Access denied for user 'root'@'localhost' (using password: NO)
という感じになる。
もちろんproduction:
以下にusername, password, databaseをベタ書きすればうまくいくのかもしれないけど、そうじゃない感。
解決策
なぞ。
もう今日は元気ないので明日は以下を読むとこから始めよう。。
Rails アプリケーションを設定する — Rails ガイド
まとめ
なんか疲れてて単純ミスのような気もするし、自力では解決困難なガチのやつの気もする。誰か助けてください。。
続き書いた
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.
と書かれてる。コンフィギュレーションマネジメントシステムをネバーユーズドな自分はシェルスクリプトがいい。
やってるのは以下。
ディレクトリ構成
$ 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の設定ファイルは↓の記事で書いた通り。
まとめ
いろいろ確信持たずにやってるけど、これで一応動いてるような気がする。
関連する記事
- 作者: 新原雅司
- 出版社/メーカー: 技術評論社
- 発売日: 2013/09/12
- メディア: Kindle版
- この商品を含むブログ (5件) を見る
- 作者: Mitchell Hashimoto,Sky株式会社玉川竜司
- 出版社/メーカー: オライリージャパン
- 発売日: 2014/02/21
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (9件) を見る
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
フラグなし)
以上
- 作者: 新原雅司
- 出版社/メーカー: 技術評論社
- 発売日: 2013/09/12
- メディア: Kindle版
- この商品を含むブログ (5件) を見る
CentOSにNginxとMySQLのリポジトリを追加
昨日から何度もググってるので備忘録として自分でもメモしておく。ググったらすぐ答え出るんだけど。
CentOSデフォルトリポジトリのNginxとMySQLのバージョンが古いので、新しいバージョンをyum
コマンドでインストールするためのリポジトリ追加手順。
Nginx
参考:CentOS6.xにてnginxの最新版をインストールする手順 - Qiita
まぁ本当に上記ページ通りなんだけど、
ここ↓から「CentOS 6」等、対応するリンク(〜.rpm)をコピーして、
リポジトリ登録。
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
参考
- MySQLをCentOSにyumリポジトリからインストールする - sakaikの日々雑感~(T)編
- MySQL :: Using the MySQL Yum Repository :: 1 Installing MySQL on Linux Using the MySQL Yum Repository
ここはさらにその劣化コピーです:-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