Redmine を Nginx + Unicorn へ移行

Apache + Passenger で動かしていた Redmine を Nginx + Unicorn に移行したのでそのメモ。 設定した環境 フロントの Nginx は https である。 Redmine は /var/redmine にインストールされている。 URL はドメイン/redmine で受ける. VPS 環境でUbuntu でスペックは低め。 Unicorn のインストール Redmine ディレクトリのルートに Gemfile.local を作る。 # Gemfile.local gem “unicorn” bundler で Unicorn をインストール $ bundle install Unicorn の設定スクリプト Redmine ディレクトリの config に unicorn.rb を下記のとおり作成する。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 worker_processes 1 timeout 60 listen File.expand_path("tmp/sockets/unicorn.sock", ENV['RAILS_ROOT']) pid File.expand_path("tmp/pids/unicorn.pid", ENV['RAILS_ROOT']) preload_app true stderr_path File.expand_path("log/unicorn.stderr.log", ENV['RAILS_ROOT']) stdout_path File.expand_path("log/unicorn.stdout.log", ENV['RAILS_ROOT']) GC.respond_to?(:copy_on_write_friendly=) and GC.copy_on_write_friendly = true before_fork do |server, worker| defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect! old_pid = "#{server.config[:pid]}.oldbin" if old_pid != server.pid begin sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU Process.kill(sig, File.read(old_pid).to_i) rescue Errno::ENOENT, Errno::ESRCH end end sleep 1 end after_fork do |server, worker| defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection end 初回アクセス時にタイムアウトしないように 60 秒に増やす。 数人しかアクセスしないのでワーカーは 1 つにする。 Nginx の設定 upstream redmine { server unix:/var/redmine/tmp/sockets/unicorn.sock; } … location /redmine { root /var/redmine/public; if ( -f $request_filename ) { break; } proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $http_host; proxy_pass http://redmine; } … Unicorn 起動 Unicorn で Redmine を起動 ...

2013年6月17日 · Toshimitsu Takahashi

Ubuntu 12.04 でメールサーバを立てずに sSMTP で CRON メールを送信するには

CRON などでメールを送信する際に、ざっくりと Postfix などを入れてしまっていた。 しかし、そもそも既にメールサーバが立っていれば、そこを経由して送信すれば MTA デーモンを動かす必要はない。 MSPに何を使うか探したところ、sSMTP が一番良さそうなのでこれを使うことに。 Ubuntu 12.04 で CRON の MAILTO でメール送信をするまでの設定のメモ。 インストール $ sudo apt-get install mailutils $ sudo apt-get install ssmtp 設定 /etc/ssmtp/ssmtp.conf # # Config file for sSMTP sendmail # # The person who gets all mail for userids < 1000 # Make this empty to disable rewriting. root=postmaster # The place where the mail goes. The actual machine name is required no # MX records are consulted. Commonly mailhosts are named mail.domain.com mailhub=<送信に使う SMTP サーバ> # Where will the mail seem to come from? rewriteDomain=<上書きするドメイン> # The full hostname hostname=<このホストの FQDN> # Are users allowed to set their own From: address? # YES - Allow the user to specify their own From: address # NO - Use the system generated From: address FromLineOverride=NO mailhub はその名のとおり経由するメールサーバを指定する。 rewriteDomain は経由先のメールサーバのドメインを指定する。設定しないとドメインが不正と判断され、迷惑メール扱いになる可能性が高い。 ...

2013年6月2日 · Toshimitsu Takahashi

MongoDB のレプリカセット運用時の 2.2 から 2.4 へのアップグレード

Webサービス自体はを止めずにバックエンドの MongoDB のバージョンアップをしたのでメモ。 具体的なバージョンは、2.2.2 から 2.4.1 へのアップグレード。 サービスの構成 フロントエンドに Nginx + Node の Web サーバ 1 台 バックエンドに MongoDB のデータベースサーバ 2 台をレプリケーション 但し、片方のサーバだけしか Primary にはならないように優先度をセットしている。 MongoDB のインストールは /usr/local 以下にバージョン毎にディレクトリ展開して、使用バージョンへシンボリックリンクを張っている。 以上のカジュアルな運用状況。 アップグレードの実行 前準備 クライアントのライブラリアップデート mongoose や 各種言語の ライブラリを 2.4 対応にアップデートする。 MongoDB 2.4 のバイナリを各サーバの /usr/local に展開しておく。 更新系のクライアント、daemon や cron によるバッチなどを停止もしくは無効にしておく。 サービス死活監視を無効にする。 実行手順 Upgrade MongoDB to 2.4 — MongoDB Manual 2.4.8 こちらに従って行います。 現状の SECONDARY サーバに入り、mongod を停止させる。 /usr/local/mongodb のシンボリックリンクを 2.4 へ張り替える。 mongod を起動する。 mongo シェルで db.serverStatus().version を実行し、バージョンアップを確認。 ここまでで最初のサーバのアップグレード完了。 現状の PRIMARY サーバに入り、mongo シェルでアクセスし rs.stepDown() で SECONDARY に降格させる。 ファイルオーバーが完了もしくは、SECONDARY になったことが rs.status() で確認できたら、mongod を停止させる。 /usr/local/mongodb のシンボリックリンクを 2.4 へ張り替える。 mongod を起動する。 mongo シェルで db.serverStatus().version を実行し、バージョンアップを確認。 これで2台目のサーバのアップグレード完了。 自分の環境ではこちらが PRIMARY に復帰したことを確認して終了。 補足 db.collection.validate() などでデータベースが正常か確認する。 ...

2013年4月14日 · Toshimitsu Takahashi

24bit/96kHz のハイレゾ WAVE ファイルを 48kHz の AAC ファイルに変換する

e-onkyo などで提供されてるハイレゾ音源の WAVE ファイルを iTunes でAAC変換すると 44.1kHz になってしまう。 個人的に 96kHz なのだから 48kHz にしたく調べたところ、MAC OS X で afconvert コマンドを用いて変換することで可能なことがわかった。 wav(WAVE) から caf 形式を経由して2段階で m4a(AAC) に変換します。 変換方法 source.wav を intermediate.caf にする。さらに final.m4a に変換する。 $ afconvert source.wav -d LEF32@48000 -f caff --soundcheck-generate --src-complexity bats -r 127 intermediate.caf $ afconvert intermediate.caf -d aac -f m4af -u pgcm 2 --soundcheck-read -b 288000 -q 127 -s 2 final.m4a 上記オプションは、アップル - iTunes - Mastered for iTunes を参考にした。

2013年3月29日 · Toshimitsu Takahashi

Windows 8 でストアアプリが開かなくなったときの対処

いつの間にか、Windows 8 のタイルからアプリを開かなくなってしまった(クリックしてもタイルのエフェクトはあるものの何も反応なし)。 困り果てていたのだが、なんとか Windows 修復機能を試したところ復活した。 管理者権限でコマンドプロンプトを起動して下記を実行する。 sfc /scannow

2013年3月2日 · Toshimitsu Takahashi

bash シンプルなデーモンプログラムの制御スクリプト

Linuxなどで動かすデーモンプログラムを起動(start)・停止(stop)・再起動(restart)・状態確認(status)するための制御スクリプトを書いたのでメモしておく。 実装のポイント 一般的なプロセスIDファイルによるプロセス確認をしている。 停止時に3秒おきにシグナル0を送り、プロセスが終了するまで見届ける。 statusでプロセスIDファイルだけ残ってプロセスが無いときはクラッシュの可能性が示す。 スクリプト 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 #!/bin/bash prgfile=<Program Script filepath> pidfile=<PID filepath> start() { if [ -f $pidfile ]; then pid=`cat $pidfile` kill -0 $pid >& /dev/null if [ $? -eq 0 ]; then echo "Daemon has started." return 1 fi fi $prgfile if [ $? -eq 0 ]; then echo "Daemon started." return 0 else echo "Failed to start daemon." return 1 fi } stop() { if [ ! -f $pidfile ]; then echo "Daemon not started." return 1 fi pid=`cat $pidfile` kill $pid >& /dev/null if [ $? -ne 0 ]; then echo "Operation not permitted." return 1 fi echo -n "Stopping daemon..." while true do kill -0 $pid >& /dev/null if [ $? -ne 0 ]; then break fi sleep 3 echo -n "." done echo -e "\nDaemon stopped." return 0 } status() { if [ -f $pidfile ]; then pid=`cat $pidfile` kill -0 $pid >& /dev/null if [ $? -eq 0 ]; then echo "Daemon running. (PID: ${pid})" return 0 else echo "Daemon might crash. (PID: ${pid} file remains)" return 1 fi else echo "Daemon not started." return 0 fi } restart() { stop if [ $? -ne 0 ]; then return 1 fi sleep 2 start return $? } case "$1" in start | stop | status | restart) $1 ;; *) echo "Usage: $0 {start|stop|status|restart}" exit 2 esac exit $? 実行プログラムのファイルパス プロセスIDファイルのパス 停止部分は実行プログラムの性質によって適宜変更すると良い。 ...

2013年2月21日 · Toshimitsu Takahashi

Chrome Extension の createHTMLNotification メソッドでデータを渡してフレキシブルに内容を構成するには

Chrome拡張でデスクトップ通知の実装時に、HTMLを使うときデータを簡単に渡す方法について。 Desktop Notifications chrome.notifications - Google Chrome を見ると、通常のタイトル、イメージ、テキストの三つを渡して表示する通知と、HTMLで自由に組める通知がある。 1 2 3 4 5 6 // Create a simple text notification: var notification = webkitNotifications.createNotification( '48.png', // icon url - can be relative 'Hello!', // notification title 'Lorem ipsum...' // notification body text ); このように前者の通知は引数でデータを渡せるが、後者では HTML ファイル名を指定するだけになっている。 1 2 3 4 // Or create an HTML notification: var notification = webkitNotifications.createHTMLNotification( 'notification.html' // html url - can be relative ); これで内容を可変にしたいときは、例として ...

2013年2月20日 · Toshimitsu Takahashi

HTTPサーバのログ解析からアタックを検出する簡易ツールを作ってみた

Webサイトを運用しているとアタックや如何わしいアクセスを調べたいときがあります。簡単にHTTPサーバのアクセスログから短い間隔で大量にアクセスしているホストを、諸々のコマンドで操作するのは面倒なので、簡単に検出できるツールがあると便利です。 探してみたところ簡単に扱えそうなものがなかったので、Rubyベースで作ってみました。 Detect HTTP Attack https://github.com/tilfin/detect-http-attack Ruby 1.9 系で動きます。依存するライブラリはないので、直ぐにコマンドラインで実行できます。標準入出力で処理しているのシェルのパイプラインに組み合わせることができます。 準備 $ git clone https://github.com/tilfin/detect-http-attack.git $ cd detect-http-attack $ ./detect_http_attack.rb --help Usage: detect_http_attack [options] -ltsv Log type is LTSV -n notify when detecting attack -s COUNT Specify minimum sequential count -i SECONDS Specify maximum interval seconds -f CONFFILE Specify configuration file 対応するログフォーマット Apache, Nginx Combined Log (Common Logもそのまま無いフィールドが空になる) LTSV format (引数に -ltsv を付加) http://ltsv.org/ 使い方 引数で検出する最大のアクセス間隔(秒)と、その間隔で連続した回数を引数で渡すと、それに適合するアクセスを標準出力します。 例えば、2秒以内の間隔で5回以上連続でアクセスがあった場合を検出するときは次のようにします。(デフォルトは3秒以内の間隔で8回以上連続で検出) ./detect-http-attack.rb -s 2 -i 5 < /var/log/apache/access_log 10.128.192.255 7 Mozilla/3.0 (windows) 2012-12-20T08:25:28+09:00 200 /admin/phpmyadmin/scripts/setup.php - 2012-12-20T08:25:28+09:00 200 /wp-content/plugins/wp-phpmyadmin/phpmyadmin/scripts/setup.php - 2012-12-20T08:25:28+09:00 200 /mysql/scripts/setup.php - 2012-12-20T08:25:28+09:00 200 /phpmyadmin2/scripts/setup.php - 2012-12-20T08:25:28+09:00 200 /pma/scripts/setup.php - 2012-12-20T08:25:28+09:00 200 /phpmyadmin/scripts/setup.php - 2012-12-20T08:25:28+09:00 200 /myadmin/scripts/setup.php - 2012-12-20T08:25:28+09:00 200 /phpMyAdmin/scripts/setup.php - 通常は、ホストごとにブロックで出力しますが、-n フラグを付けると標準エラーに検出したアクセス毎に出力します。ターミナルで下記のように実行すれば、検出したアタックを適宜表示しつつ、まとめた結果をファイルに書き出すことができます。 ...

2013年2月12日 · Toshimitsu Takahashi

Mongoose でセカンダリにアクセス可能な接続を設定をするには

MongoDB でレプリケーションセットを構成する。MongoDBでは Secondary サーバへのアクセスを読み取りであってもデフォルトで拒否するようになっている。 このためには接続ごとに slaveOk フラグを立てる必要があるが、そのときの Mongoose の設定に手間取ったのでメモしておく。 (2013/1/18 に、レプリケーション設定に誤りがあったため以降の内容を修正しています。) オプション設定 mongoose の connection を生成する方法は色々とありますが、createConnection メソッドを使っています。 createConnection の第2引数のオプションには、それぞれ以下のキーで設定を構成できます。 db - Node用 Native MongoDB ドライバーのオプション server - サーバ接続に関する設定 replset - レプリケーションセットに関する設定 ReplSet — MongoDB Node.JS Driver 1.3.20 documentation 接続を生成する関数例 以下、sampledb というデータベースに localhost で 27017 と 27018 ポートで動いている二つの MongoDB サーバに接続するときのサンプルです。レプリケーションセット名は「myrepl」で、コネクションプールもデフォルトの 5 から 10 に増やしています。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 const DB_HOST = "localhost:27017"; const DB_NAME = "sampledb"; const DB_REPLSET_NAME = "myrepl"; const DB_REPLSET_MEMBERS = "localhost:27017,localhost:27018" var mongoose = require('mongoose'); var mongooseConnection = (function(){ var uri; var opts = { server: { poolSize: 10, auto_reconnect: true } }; if (DB_REPLSET_NAME && DB_REPLSET_MEMBERS) { var rsmembers = DB_REPLSET_MEMBERS.split(','); var svs = []; rsmembers.forEach(function(sv){ svs.push("mongodb://" + sv + "/" + DB_NAME); }); uri = svs.join(","); opts.replset = { rs_name: DB_REPLSET_NAME, readPreference: 'primaryPreferred' }; } else { opts.db = { slave_ok: true }; uri = 'mongodb://' + DB_HOST + '/' + DB_NAME; } return mongoose.createConnection(uri, opts); })(); ※ DB_REPLSET_NAME, DB_REPLSET_MEMBERS が設定されていればレプリケーション設定になります。

2013年1月14日 · Toshimitsu Takahashi

Windows 8 で Google Apps メールの新着通知をデスクトップに表示させるには

Google Apps(独自ドメイン向け)用のメール機能 (Gmail) を使っている。 せっかく Windows 8 にしたので OS 自体のデスクトップ通知機能を使ってみたい。 メールをセットアップすれば良いのだが、ちょっとポイントがあるのでメモ。 iOSでメールを使ってる人には、知られた方法だと思うが、Gmail は Exchange Server 互換の機能を実装しているのでこれを使う。Exchange互換で使うにはOutlookを選ぶのがポイントである。 タイルの「メール」を開く。 「設定」→「アカウント」と選択する。 「アカウントの追加」→「Outlook」と選択する。 「Outlook アカウントの追加」で詳細を表示する。 「サーバーのアドレス」に m.Google.com を入力する。 「ドメイン」に対象ドメインなどを入力して、[接続] をクリック。 追加したアカウントの「設定」で「このアカウントのメール通知表示する」をオンにする。 これで下記のようにメールの通知がデスクトップに出るようになる。

2012年12月4日 · Toshimitsu Takahashi