参考
概要
Grailsに限らず、JavaベースのWebアプリケーションを公開するために、Webサーバ経由でTomcatなどのサーブレットコンテナにアクセスさせる、という方法が取られます。
Tomcatはポート8080で動いていて、Webサーバはポート80番で動いている。
ユーザがWebサーバにアクセスしてくると、処理をTomcatに流す、という感じです。
今回、NginxをWebサーバとして場合の設定方法をまとめます。
Grailsの設定
前提条件
大前提として、画像もCSSもJavaScriptもAsset Pipeline Plugin経由で扱うようにする必要が有ります。
Asset Pipelineの簡単な使い方は[Grails]Asset-Pipelineプラグインのメモを参照してください。
また、今回はGrailsアプリケーションのコンテキストルートを/
として、Tomcatにデプロイするwarファイル名もTomcatのメインアプリケーション扱いになるROOT.war
とします。
Grailsのデフォルトのコンテキストルートは、Config.groovyのどこかに以下の行を追加することで変更可能です。
grails.app.context = '/'
この状態でGrailsをrun-appで起動すると、http://localhost:8080/ でGrailsアプリケーションにアクセスできるようになります。
また、grails war
コマンドで生成されるデフォルトのwarファイル名はBuildConfig.groovyに以下の行を追加することで変更可能です。
grails.project.war.file = "target/ROOT.war"
設定
開発環境であれば、多くの場合そのままGrailsが起動するTomcatにアクセスすると思われますので、この場合は特に何も問題はありません。
しかし、本番サーバでNginxなどからアクセスが経由されてくる場合は、画像ファイルなどのURLの扱いが原因で、デフォルトでは404となってしまいます。
そこで、configファイルに以下の行を追記します。
environments {
development {
grails.logging.jul.usebridge = true
}
production {
grails.logging.jul.usebridge = false
// TODO: grails.serverURL = "http://www.changeme.com"
// 以下の行を追加
grails.assets.storagePath = "/tmp/hoge"
}
}
そして、実際にGrailsアプリケーションが動作するサーバ上で、上記で追加したパスのディレクトリ(/tmp/hoge)を作成して、Tomcatから書き込めるような権限にしておきます。
注意!このサンプルは/tmp配下にディレクトリを作成しましたが、Linuxディストリビューションによってタイミング等は異なりますが、/tmpディレクトリは定期的に削除されます。実際に運用する際にはTomcatからの書き込み権限が与えられる場所で、適切は場所を選択するようにしてください。
Nginxの設定
前提条件
今回、バーチャルホストを使っている。
ドメインやパスなどは適宜読み替えてください。
また、今回は用意したファイルは、nginxのデフォルトの設定ファイルから自動的に読みこまれるようにしています。
設定
server {
listen 80;
server_name example.com;
index index.html index.htm index.php;
# settings for access log
access_log /var/log/nginx/example.com.access.log;
# settings for error log
error_log /var/log/nginx/example.com.error.log;
location / {
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_pass http://127.0.0.1:8080;
proxy_cookie_path / /;
proxy_set_header X-Forwarded-For $remote_addr;
}
location ^~/assets {
alias /tmp/hoge;
}
}
基本的にはコレでNginxを起動すればOKです。
GrailsアプリケーションがTomcatにデプロイされるタイミングで、Asset Pipeline Pluginで扱われるファイルは全て、Config.groovyで指定した/tmp/hoge
ディレクトリ配下に展開されます。
そして、Nginxが/assets/
へのアクセスは自動的に、/tmp/hoge
へマッピングしてくれます。(alias)
問題点
Tomcat7から利用できるようになったパラレルデプロイですが、今回のように無条件にAsset Pipeline Plugin用のディレクトリが1箇所に固定されている場合に問題が発生します。
というのも、後から起動したアプリケーションが/tmp/hoge
ディレクトリを上書きしてしまうためです。
Asset Pipeline Pluginで扱うファイルに変化がなければ問題にはならないと思われますが、そういった状況毎にデプロイ方法を変えるのは時代の流れに逆行してしまうので、素直にTomcatの停止-> 古いROOTディレクトリの削除 -> ROOT.warの入れ替え -> Tomcatの起動を行うのがベターだと思います。
まとめ
自分が実際にハマったのでまとめました。
コンテキストが/
じゃなくても、Nginxの設定(パス)さえちゃんとしていれば動くんじゃないかなと思います。